libicl_private.c

来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 1,108 行 · 第 1/3 页

C
1,108
字号
          icldataqStart = i;
          i += ICLDATAQSTARTLEN + 1;
          /* now look for first double quotes */
          while((terms[i] != '"') &&
                (i < len - 1)) {
            ++i;
          }
          
          // now look for the matching set of quotes
          if(i == len) {
            return FALSE;
          }
          
          inData = TRUE;
        }
      }
    }
      
    /* Check for JIS7 Japanese Encoding markers */

    if(!inData) {
      if((i + 2) < len) {
        if ((terms[i] == 27) && (terms[i+1] == '$') && (terms[i+2] == 'B'))
          inJIS7 = TRUE;
        else
          if ((terms[i] == 27) && (terms[i+1] == '(') && (terms[i+2] == 'B'))
            inJIS7 = FALSE;
      }
    }

    /* Check for end of data */

    if(inData) {
      if(terms[i] == '"') {
        if(((i + 1) < len) &&
           (terms[i + 1] == '"')) {
          inData = FALSE;
        }
      }
    }

    /* If we are not looking at Japanese characters, try to parse the 
       input. */
    if (!inJIS7)
      switch (terms[i]) {
      case '(':
      case '[':
      case '{':
        if (!inquotes)
          parens = parens + 1;
        break;
      case ')':
      case ']':
      case '}':
        if (!inquotes) {
          parens = parens - 1;
          if ((parens == 0) && (!icl_stIsOperatorChar(terms[i+1])))
            done = TRUE;
        }
        break;
      case '\'':
        inquotes = !inquotes;
        break;
      case ',' :
        if ((parens == 0) && (inquotes == 0))
          done = TRUE;
        break;
      case ' ':
      case '\n':
      case '\t':
        if ((parens == 0) && (inquotes == 0) && seen_something)
          done = TRUE;
        break;
      default: 
        if (icl_stIsSeparator(&terms[i])) {
          if ((parens == 0) && (inquotes == 0))
            done = TRUE;
        }
        else 
          seen_something = TRUE;
      } /* End switch */
  } /* End while */

  if (!parens && !inquotes) {
    if (icl_stIsSeparator(&terms[i])) {
      n = i;
      last_separator = terms[i];
    }
    else 
      n = i+1;
    *aterm = malloc(n+1);
    memcpy(*aterm, terms, n);
    (*aterm)[n] = '\0';
    *atermLen = n;
    i++;
    while ((terms[i] != 0) && ((terms[i] == ' ') || 
                               (icl_stIsSeparator(&terms[i]))))
      i++;
    *restterms = &terms[i];
    *restTermsLen = len - i;
    return TRUE;
  }
  else {
    *aterm = strdup("");
    *atermLen = 0;
    *restterms = strdup("");
    *restTermsLen = 0;
    return FALSE;
  } 
}


/****************************************************************************
 * name:    icl_stFunctorArgs
 * purpose: Splits a string containing a prolog-style structure into a functor
 *          and arguments
 * inputs:
 *   - char *structure: In form  "a(arg1, arg2, ...)"
 * outputs:
 *   - char *func: returns "a"
 *   - char *args: returns "arg1, arg2, ..."
 * remarks:
 *   - func and args will return new copies of the data, which should
 *     be free'd once they are no longer needed
 *   - If no arguments exist, the empty string is returned in args
 *     (1 byte allocated)
 ****************************************************************************/
EXPORT_MSCPP
void EXPORT_BORLAND 
icl_safeStFunctorArgs(char *structure,
                      size_t structLen,
                      char **func,
                      size_t* funcLen,
                      char **args,
                      size_t* argsLen)
{
  char *p;
  int i;
 
  /* Make sure structure is not NULL! */
  if (!structure)
    structure = NULL;
 
  /* If structure is just a string, list or other compound term, */
  /* or an atom, just return the term, don't search for "("             */
  /* Note that icldataq(...) can only show up after a paren! */
  if (((*structure) && 
       (strchr("{[(\"", *structure) != NULL)) ||
      icl_stIsStr(structure)) {
    icl_stHeadTailPtr(structure, func, args);
    *args = strdup("");
    *argsLen = 0;
  }
 
  /* Otherwise, assume structure in form aaa(bbb,ccc): pluck of */
  /* functor by searching for first "(" char.                   */
  else {
 
    p = strstr(structure, "(");
    if (!p) {                         /* no arguments in term */
      *func = strdup(structure);
      /* Chop off trailing '.' */
      i = structLen;
      if ((i > 0) && (*func)[i] == '.')
        (*func)[i] = '\0';
      *funcLen = strlen(*func);
      *args = strdup("");
      *argsLen = 0;
    }
    else {
      /* *funcLen doesn't include null char */
      *funcLen = p - structure;
      *func = malloc(*funcLen + 1);
      strncpy(*func, structure, *funcLen);
      (*func)[*funcLen] = '\0';
      /* exact length of data--no null char included */
      *argsLen = structLen - ((p + 1) - structure) + 1;
      /* need to remove trailing ')' char--it's either ')' or ').' */
      *args = (char*)malloc(*argsLen + 1);
      memset(*args, '\0', *argsLen + 1);
      (void)memcpy(*args, p + 1, *argsLen);
      if((*argsLen >= 1) &&
         ((*args)[*argsLen - 1] != ')')) {
        *argsLen -= 1;
      }
    }
  }
}

/****************************************************************************
 * name:    icl_stOperator
 * purpose: Checks an incoming prolog atom to see if it is an operator.
 *          Returns 0 if the term not is an operator
 * inputs:
 *   - char *term: a string containing a prolog atom
 * returns:
 *   the priority if the term is an operator, 0 otherwise
 * Note : Operators currently are :
 *          +, - : of priority 2
 *          *, / : of priority 3
 *          :,:- : of priority 1
 ****************************************************************************/
EXPORT_MSCPP
int EXPORT_BORLAND 
icl_stIsOperator(char *t)
{
  int index = 0;
  while (operators[index].mPriority>=0){
    //printf("Checking %d %s vs %s %d\n", STREQ(t, operators[index].mName), t, operators[index].mName, operators[index].mPriority);
    if (STREQ(t, operators[index].mName))
      return operators[index].mPriority;
    index++;
  }
  return -1;
}

EXPORT_MSCPP
int EXPORT_BORLAND 
icl_stIsOperatorChar(char t){
  char temp[2];
  temp[0] = t;
  temp[1] = 0;
  return icl_stIsOperator(temp);
}


/****************************************************************************
 * name:    icl_stNthElt
 * purpose: Returns the Nth element in a comma-separated list of terms
 * inputs:
 *   - char *list: a string containing a comma-separated list of terms
 *   - int      n: index into a list (nth term)
 * outputs:
 *   - char  *elt: the nth term in the list.
 * remarks: not icldataq safe; won't fix--unused
 ****************************************************************************/
EXPORT_MSCPP
void EXPORT_BORLAND 
icl_stNthElt(char *list,
             int n,
             char **elt)
{
  /* Local string variables */
  char *temp = NULL;

  while ( (strcmp(list, "") != 0) && (n > 0)) {
    n--;
    if (n == 0)
      icl_stHeadTailPtr(list, elt, &list);
    else {
      icl_stHeadTailPtr(list, &temp, &list);
      /* Deallocation local string variables */
      icl_stFree(temp);
    }
  }
  if (*elt) icl_stTrim(*elt);
}

char* findString(char const* haystack, size_t len, char const* needle, size_t needleLen) 
{
  char const* start = NULL;
  char* toRet = NULL;
  int done = FALSE;
  if((needle == NULL) ||
     (haystack == NULL) ||
     (len == 0)) {
    return NULL;
  }
  
  start = haystack;
  while(!done) {
    toRet = (char*)memchr(start, *needle, len);
    start = toRet;
    if((needleLen + (start - haystack)) > len) {
      return NULL;
    }
    if(strncmp(start, needle, needleLen) == 0) {
      done = TRUE;
    }
    ++start;
    len -= (start - haystack);
  }
  return toRet;
}

/****************************************************************************
 * name:    find_first_operator
 * purpose: Finds the first occurence of an operator within an Icl Expression. 
 * This won't work if an icldataq occurs before the operator.
 * inputs:
 *   - char *term: a string containing a prolog term (or variable)
 * returns:
 *   The index of the first operator if found, -1 otherwise
 ****************************************************************************/
int find_first_operator(char* s, char* op) {  
  int parCount; 
  char* operator_ptr = s;
  int length = strlen(s);
  int index,i;
  /* Look for the first occurence of the operator which is not inside 
     a set of perenthesis. 
  */
  while ((operator_ptr = findString(operator_ptr, length, op, strlen(op)))!=NULL) { 
    parCount = 0; 
    operator_ptr++;
    index = length-strlen(operator_ptr);
    for (i=0;i<index;i++) { 
      if(s[i]=='(')
        parCount++;
      if(s[i]==')')
        parCount--;
    }
    if (parCount == 0) 
      return index-1; 
  }
  return -1;
}

/****************************************************************************
 * name:    icl_stOperation
 * purpose: Returns true if the term is an operation
 * inputs:
 *   - char *term: a string containing a prolog term (or variable)
 * returns:
 *   True if the term is a variable
 * Note : An operation is defined by a binary operator and two operands.
 *        Operators currently are :
 *          +, - : of priority 2
 *          *, / : of priority 3
 *          :,:- : of priority 1
 ****************************************************************************/
EXPORT_MSCPP
int EXPORT_BORLAND 
icl_safeStOperationArgs(char *t, char** op, char** left, char** right)
{
  /* First we look for the and operator */
  int index = 0;
  while (operators[index].mPriority>=0){
    int operator_index=0;
    if ((operator_index = find_first_operator(t, operators[index].mName))>0) {  
      // Here we have found an suitable operator
      if (left) {
        *left = (char*)malloc(operator_index+1);
        strncpy(*left, t, operator_index); 
        (*left)[operator_index]=0;
      }

      if(op)
        *op = strdup(operators[index].mName);

      if (right) {
        *right = strdup(t+operator_index+strlen(operators[index].mName));
        //*right = (char*)malloc(strlen(t)-operator_index-strlen(operators[index].mName));
        //strncpy(*right, t+operator_index+strlen(operators[index].mName), strlen(t)-operator_index-strlen(operators[index].mName));
      }
      /* DEBUG */
      if (0 && op && left && right)
        printf("Expression Operator : %s Left : %s Right : %s\n", *op, *left, *right);
      return 1;
    }
    index++;
  }
  return 0;
}

int icl_safeStIsVar(char* t, size_t len) 
{
  if(len > 0) {
    return ((t != NULL) && ((*t == '_') || ((*t >= 'A') && (*t <= 'Z'))));
  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?