view anagram/agcore/search.cpp @ 14:a02e9434072e

Fix friend declaration for gcc10. XXX: did not check it against the IBM compiler, might end up needing XXX: to be conditional.
author David A. Holland
date Tue, 31 May 2022 00:59:42 -0400
parents 13d2b8934445
children
line wrap: on
line source

/*
 * AnaGram, A System for Syntax Directed Programming
 * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
 * See the file COPYING for license and usage terms.
 *
 * search.cpp
 */

#include <ctype.h>
#include "port.h"

#include "arrays.h"
#include "search.h"

//#define INCLUDE_LOGGING
#include "log.h"


SearchProcess::SearchProcess()
  : keyLength(0)
  , ptr(0)
  , currentMode(notSet)
{
  LOGSECTION("SearchProcess::SearchProcess");
}

void SearchProcess::setKey(AgString k) {
  LOGSECTION("SearchProcess::setKey");
  key = k;
  ptr = key.pointer();
  keyLength = key.size();
  LOGV(key) LCV(ptr) LCV(keyLength);
  memset(offset, 0, 256);
  currentMode = notSet;
  int i;
  for (i = 0; i < keyLength; i++) {
    offset[(unsigned) key[i]] = (unsigned char)(i+1);
    if (isalpha(key[i])) {
      offset[(unsigned)key[i]^0x20] = (unsigned char) (i+1);
    }
    LOGV(i) LV(key[i]);
    LOGV(key[i]) LCV(offset[(unsigned) key[i]]);
    LOGV(key[i]^0x20) LCV(offset[(unsigned)key[i]^0x20]);
  }
}

char *SearchProcess::scanForward(char *line, int n) {
  LOGSECTION("SearchProcess::scanForward");
  if (currentMode != forward) {
    int i;
    for (i = 0; i < keyLength; i++) {
      offset[(unsigned)key[i]] = (unsigned char) (i+1);
      if (isalpha((unsigned) key[i])) {
	offset[(unsigned)key[i]^0x20] = (unsigned char) (i+1);
      }
    }
    currentMode = forward;
  }
  //char *logBuf = new char[keyLength + 1];
  //logBuf[keyLength] = 0;
  char *p = line + keyLength - 1;
  char *end = line + n;
  LOGV((int) p) LCV((int) end);
  while (p < end) {
    int k = offset[*(unsigned char *) p];
    if (k) {
      p -= k - 1;
      //strncpy(logBuf, p, keyLength);
      //LOGV((int) p) LCV(*(unsigned char *)p) LCV(k) LCV(logBuf);
      k = offset[*(unsigned char *) p];
      if (k && strnicmp(p, ptr, keyLength) == 0) {
	return p;
      }
    }
    p += keyLength;
  }
  //delete [] logBuf;
  return 0;
}

char *SearchProcess::scanReverse(char *line, int n) {
  LOGSECTION("SearchProcess::scanReverse");
  if (currentMode != reverse) {
    int i = keyLength;
    while (i--) {
      offset[(unsigned) key[i]] = (unsigned char) (i+1);
      if (isalpha((unsigned) key[i])) {
	offset[(unsigned)key[i]^0x20] = (unsigned char) (i+1);
      }
    }
    currentMode = reverse;
  }
  //char *logBuf = new char[keyLength + 1];
  //char *logBuf = local_array(keyLength + 1, char);
  LocalArray<char> logBuf(keyLength + 1);
  logBuf[keyLength] = 0;
  char *p = line + n - keyLength;
  LOGV((int) line) LCV((int) p);
  while (line <= p) {
    int k = offset[*(unsigned char *)p];
    if (k) {
      p -= k - 1;
      strncpy(logBuf, p, keyLength);
      LOGV((int) p) LCV(*(unsigned char *)p) LCV(k) LCV(logBuf);
      k = offset[*(unsigned char *) p];
      if (k && strnicmp(p, ptr, keyLength) == 0) {
	return p;
      }
      p--;
    }
    else {
      p -= keyLength;
    }
  }
  return 0;
}