libicl.c

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

C
2,613
字号
/****************************************************************************
 *   File    : libicl.c
 *   Author  : Adam Cheyer
 *   Purpose : Contains C version of ICL constructor and accessor routines
 *   Updated : 5/21/97
 *
 *   -------------------------------------------------------------------------
 *   Unpublished-rights reserved under the copyright laws of the United States.
 *
 *      This data and information is proprietary to, and a valuable trade
 *      secret of, SRI International.  It is given in confidence by SRI
 *      International. Its use, duplication, or disclosure is subject to the
 *      restrictions set forth in the License Agreement under which it has
 *      been distributed.
 *
 *   Unpublished Copyright (c) 1993-97, SRI International.
 *   -------------------------------------------------------------------------
 *
 *****************************************************************************/

#define EXPORT_BORLAND

#ifdef IS_DLL
#define EXPORT_MSCPP __declspec(dllexport)
#else
#define EXPORT_MSCPP
#endif

/****************************************************************************
 * RCS Header
 ****************************************************************************/
#ifndef lint
/*char *rcsid= "$Header: /home/zuma1/OAA/CVSRepository/oaa2/src/oaalib/c/src/libicl.c,v 1.45 2005/04/19 01:43:34 agno Exp $";*/
#endif


/****************************************************************************
 *Include files
 ****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <malloc.h>
#include <stdarg.h>  	/* Variable length argument lists */
#include <ctype.h>
#include "libicl.h"
#include "libutils.h"
#include "libicl_private.h"
#include "libicl_depr.h"
#include "stdpccts.h"

#ifdef _WINDOWS
#include "oaa-windows.h"
#endif

/****************************************************************************
 * Global variables and definitions
 ****************************************************************************/

extern char* ICLDATAQSTART;
extern size_t ICLDATAQSTARTLEN;
static int rename_vars_index;

#ifndef STREQ
#define STREQ(str1, str2) (strcmp((str1), (str2)) == 0)
#endif

#ifdef NORMAL_GC
char* gc_strdup(char* s)
{
  int i = strlen(s);
  char* p = (char*)malloc(i + 1);
  strcpy(p, s);
  p[i] = '\0';
  return p;
}
#endif

/*****************************************************************************
 * Local utility routines for dynamic arrays (used for unification)
 *****************************************************************************/

/****************************************************************************
 * Forward references for some static functions
 ****************************************************************************/
static void icl_deref(ICLTerm **var, struct dyn_array var_bindings);
static ICLListType *
icl_copy_list_type(ICLListType *list, struct dyn_array *vars);

EXTERN void printDebug(int level, char *str, ...);

/****************************************************************************
 * More forward references
 ****************************************************************************/
static void iclIncRef(ICLTerm* t);
int iclDecRef(ICLTerm* t);
static void icl_FreeTermMulti(ICLTerm *elt, int n, void* pc);

/****************************************************************************
 * name:    iclIncRef
 * purpose: Increment the reference count of a term
 ****************************************************************************/
static void iclIncRef(ICLTerm* t)
{
  t->refCount++;
}

/**
 * Decrement the reference count of a term.
 * @return a new reference count, which may be negative (for multiple incorrect
 *  frees).
 */
int iclDecRef(ICLTerm* t)
{
  if(t != NULL) {
    t->refCount -= 1;
    return t->refCount;
  }
  return -1;
}

/**
 * Initializes a dynamic array.
 */
EXPORT_MSCPP
void EXPORT_BORLAND icl_init_dyn_array(struct dyn_array *da)
{
  (*da).allocated = 0;
  (*da).count = 0;
  (*da).item = NULL;
}

/**
 * Returns TRUE if the term is a variable.
 * @param t a string containing a prolog term (or variable)
 * @return TRUE if the term is a variable
 */
EXPORT_MSCPP
int EXPORT_BORLAND
icl_stIsVar(char *t)
{
  return ((t != NULL) && ((*t == '_') || ((*t >= 'A') && (*t <= 'Z'))));
}

EXPORT_MSCPP
int EXPORT_BORLAND
icl_stIsOperation(char *t){
  return icl_stOperationArgs(t, NULL, NULL, NULL);
}

EXPORT_MSCPP
int EXPORT_BORLAND
icl_stIsIclDataQ(char* t, size_t len)
{
  static size_t dataqMarkerLen = 0;
  if(dataqMarkerLen == 0) {
    dataqMarkerLen = strlen(ICLDATAQSTART);
  }
  if(len >= 9) {
    if(strncmp(t, ICLDATAQSTART, dataqMarkerLen) == 0) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
 * Returns TRUE if the term is an integer.
 * @param t a string containing an integer
 * @return TRUE if the term is a integer
 */
EXPORT_MSCPP
int EXPORT_BORLAND
icl_stIsInt(char *t)
{
  char *p;

  strtol(t, &p, 10);
  return ((p != t) && (*p == '\0'));
}


/**
 * Returns TRUE if the term is a float.
 * @param t a string containing a float
 * @return TRUE if the term is a float
 */
EXPORT_MSCPP
int EXPORT_BORLAND
icl_stIsFloat(char *t)
{
  char *p;

  strtod(t, &p);
  if (p == t)			/* strtod failed */
    return (FALSE);

  if (*p == '\0')		/* String contains only 1.0 */
    return (TRUE);

  if ((*p == 'E'))
    return (((*(p+1) == '+') ||
             (*(p+1) == '-')) &&
            (atoi(p+2) > 0));
  else return (FALSE);
}

/**
 * Converts any '' marks inside a string to just '.
 * Single quotes inside strings will be doubled when coming from Prolog.
 * This is icldataq safe because it is only called on known iclStr types.
 * @param s a string containing prolog terms on input
 */
EXPORT_MSCPP
void EXPORT_BORLAND
icl_stUndoubleQuotes(char *s)
{
  char c;
  char cc;
  char* in_ptr;
  char* out_ptr;

  in_ptr = s;
  out_ptr = s;

  while ((c = *in_ptr++) != (char) NULL) {
    cc = *in_ptr;
    if (c == '\'' && cc == c) {
      *out_ptr++ = c;
      in_ptr++;
    } else {
      *out_ptr++ = c;
    }
  }
  *out_ptr++ = '\0';
}

/**
 * Converts any '' marks inside a string to just ', and
 * removes any external quote marks around the string.
 * Calls icl_stRemoveQuotes, followed by icl_stUndoubleQuotes.
 * should be okay for icldataq, since we assume s does not contain an icldataq.
 *
 * @param s a string containing an ICL Str.
 * @return a pointer to the original string, which has been
 *         modified appropriately.
 *
 */
EXPORT_MSCPP
char * EXPORT_BORLAND
icl_stFixQuotes(char *s)
{
  icl_stRemoveQuotes(s);
  icl_stUndoubleQuotes(s);
  return s;
}



/**
 * Doubles any "'" in the string, to prepare the string to be
 * surrounded by "'".
 * @param s a string containing prolog terms
 * @return the string with any <code>'</code> to <code>''</code>.
 *         The pointer returned should <em>not</em> be deallocated or the contents
 *         changed in any way, just used as is. The original parameter
 *         string is <em>not</em> changed. Safe for icldataq since we assume s
 *         contains no icldataq() terms.
 */
EXPORT_MSCPP
char * EXPORT_BORLAND
icl_stDoubleQuotes(char *s)
{
  static char *out_str = 0;
  static int out_str_len = 0;
  char *in_ptr, *out_ptr;
  char c;
  int i = 0;
  int num = 0;
  int new_len;

  /* Count number of ' chars */
  while (i < (int)strlen(s)) {
    if (s[i] == '\'') {
      num++;
    }
    i++;
  }

  new_len = strlen(s) + num + 10;

  /* Reallocate space if necessary */
  if (out_str_len < new_len) {
    if (out_str) {
      icl_stFree(out_str);
    }
    out_str = malloc(new_len);
    out_str_len = new_len;
  }

  /* Copy string to new buffer, doubling ' char */
  in_ptr = s;
  out_ptr = out_str;
  while ((c = *in_ptr++) != 0) {
    if (c == '\'') {
      *out_ptr++ = c;
      *out_ptr++ = c;
    } else {
      *out_ptr++ = c;
    }
  }
  *out_ptr++ = (char) 0;

  return out_str;

}


/**
 * Adjusts the quotes in a string to be a legal ICL Str.
 * If necessary, adds <code>'</code> characters around the string, and
 * doubles any internal <code>'</code> chars.
 * The original parameter string is <em>not</em> changed.
 * @param s a string
 * @return a legal ICL Str. The pointer returned should <em>not</em> be
 *         deallocated or the contents changed in any way, just used as is.
 */
EXPORT_MSCPP
char * EXPORT_BORLAND
icl_stQuoteForce(char *s)
{
  static char *out_str = 0;
  static int out_str_len = 0;

  /* Code adapted from icl_DoubleQuotes */
  char *in_ptr, *out_ptr;
  char c;
  int i = 0;
  int num = 0;
  int new_len;
  
  /* Count number of ' chars */
  while (i < (int)strlen(s)) {
    if (s[i] == '\'') {
      num++;
    }
    i++;
  }
  
  new_len = strlen(s) + num + 10;
  
  /* Reallocate space if necessary */
  if (out_str_len < new_len) {
    if (out_str) {
      icl_stFree(out_str);
    }
    out_str = malloc(new_len);
    out_str_len = new_len;
  }
  
  /* Copy string to new buffer, doubling ' char, and wrapping in ' */
  in_ptr = s;
  out_ptr = out_str;
  *out_ptr++ = '\'';
  while ((c = *in_ptr++) != 0) {
    if (c == '\'') {
      *out_ptr++ = c;
      *out_ptr++ = c;
    } else {
      *out_ptr++ = c;
    }
  }
  *out_ptr++ = '\'';
  *out_ptr++ = (char) 0;
  
  return (out_str);
}

/**
 * Adjusts the quotes in a string to be a legal ICL Str.
 * If necessary, adds <code>'</code> characters around the string, and
 * doubles any internal <code>'</code> chars.
 * The original parameter string is <em>not</em> changed.
 * @param s a string
 * @return a legal ICL Str. The pointer returned should <em>not</em> be
 *         deallocated or the contents changed in any way, just used as is.
 */
EXPORT_MSCPP
char * EXPORT_BORLAND
icl_stQuote(char *s)
{
  static char *out_str = 0;
  static int out_str_len = 0;

  if (icl_stIsStr(s))
    return (s);

  /* Code adapted from icl_DoubleQuotes */
  else {
    char *in_ptr, *out_ptr;
    char c;
    int i = 0;
    int num = 0;
    int new_len;

    /* Count number of ' chars */
    while (i < (int)strlen(s)) {
      if (s[i] == '\'') {
        num++;
      }
      i++;
    }

    new_len = strlen(s) + num + 10;

    /* Reallocate space if necessary */
    if (out_str_len < new_len) {
      if (out_str) {
        icl_stFree(out_str);
      }
      out_str = malloc(new_len);
      out_str_len = new_len;
    }

    /* Copy string to new buffer, doubling ' char, and wrapping in ' */
    in_ptr = s;
    out_ptr = out_str;
    *out_ptr++ = '\'';
    while ((c = *in_ptr++) != 0) {
      if (c == '\'') {
        *out_ptr++ = c;
        *out_ptr++ = c;
      } else {
        *out_ptr++ = c;
      }
    }
    *out_ptr++ = '\'';
    *out_ptr++ = (char) 0;

    return (out_str);
  }
}





/**
 * Removes leading and trailing spaces and other unprintables.
 * @param s: a string containing prolog terms
 */
EXPORT_MSCPP
void EXPORT_BORLAND
icl_stTrim(char *s)
{
  while (s && (*s) && (*s <= ' '))
    strcpy(s, &s[1]);
  while (s && (*s) && (s[strlen(s)-1] <= ' '))
    s[strlen(s)-1] = '\0';
}



/**
 * Appends a string onto the end of a first one, adjusting the
 * size of the resulting string if necessary. The memory allocation of
 * str1 will be readjusted to be able to contain
 * text for both str1 and str2.
 * @param str1 address of a string pointer, maybe containing data
 * @param str2 a string to concatenate to str1
 *
 */
EXPORT_MSCPP
void EXPORT_BORLAND
icl_stAppend(char **str1, char *str2)
{
  char *p;
  int str2len = strlen(str2);

  if (!str2 || !*str2) return;

  if (*str1 == NULL) {

    *str1 = (char*)malloc(sizeof(char) * (str2len + 1));
    *str1 = strdup(str2);
    (*str1)[str2len] = '\0';
  }
  else {
    p = malloc(strlen(*str1) + strlen(str2)+1);
    strcpy(p, *str1);
    strcat(p, str2);
    icl_stFree(*str1);
    *str1 = p;
  }
}





static
void icl_rename_vars_termhelper(ICLTerm **term, hthash_table *knownVars)
{
  ICLListType *l;
  char *hashedVal;

  /* Validate incoming arguments */
  if (icl_IsValid(*term)) {
    if (icl_IsVar(*term)) {
      if((strncmp((*term)->p,"_",1) == 0) &&
         (strlen((*term)->p) == 1)) {
	char tempName[10];
	hashedVal = NULL;
	sprintf(tempName, "_%d", rename_vars_index);
	rename_vars_index++;
	free((*term)->p);
	(*term)->p = strdup(tempName);
      }
      else {
	hashedVal = (char *)htlookup((char *)((*term)->p), knownVars);
      }

⌨️ 快捷键说明

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