libicl.c

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

C
2,613
字号
	}
	if(termStack.item != NULL) {
	  free(termStack.item);
	}
	return NULL;
	break;
      }
      compoundStack.item[compoundStack.count - 1] = NULL;
      compoundStack.count--;
      currCompound = (struct CompoundInfo*)compoundStack.item[compoundStack.count - 1];
      icl_add_compound_argument(currCompound, currTerm);
    }
  }
  icl_WriteTerm(currTerm);
  printf("\n");
  fprintf(stderr, "icl_copy_term_nonrec unreachable\n");
  return NULL;
}

/****************************************************************************
 * name:    icl_copy_term
 * purpose: Creates a copy of the term, all in new memory.
 *	    Dereferences variables from binding list if available
 ****************************************************************************/
/*
  EXPORT_MSCPP
  ICLTerm *EXPORT_BORLAND
  icl_copy_term(ICLTerm *t, struct dyn_array *vars)
  {
  ICLTerm *res = NULL;

  if (vars) {
  icl_deref(&t, *vars);
  }

  if (icl_IsVar(t)) {
  res = icl_NewVar(icl_Str(t));
  }
  else if (icl_IsInt(t)) {
  res = icl_NewInt(icl_Int(t));
  }
  else if (icl_IsFloat(t)) {
  res = icl_NewFloat(icl_Float(t));
  }
  else if (icl_IsStr(t)) {
  res = icl_NewStr(icl_Str(t));
  }
  else if (icl_IsStruct(t)) {
  ICLTerm *argList = icl_NewList(icl_copy_list_type(icl_Arguments(t),vars));
  res = icl_NewStructFromList(icl_Functor(t), argList);
  }
  else if (icl_IsList(t)) {
  res = icl_NewList(icl_copy_list_type(icl_List(t),vars));
  }
  else if (icl_IsGroup(t)) {
  char startC, *sep = NULL;
  icl_GetGroupChars(t, &startC, &sep);
  res = icl_NewGroup(startC, sep, icl_copy_list_type(icl_List(t), vars));
  icl_stFree(sep);
  }
  else if (t == NULL) {
  return NULL;
  }
  else {
  fprintf(stderr, "Unknown type in icl_copy_term\n");
  }

  return (res);
  }
*/

/**
 * Creates a new copy of a ListType list, dereferencing vars if available.
 */
static
ICLListType *
icl_copy_list_type(ICLListType *list, struct dyn_array *vars)
{
  ICLListType *res = NULL, *end = NULL;

  while (list) {
    if (!res) {
      ICLTerm* copy = icl_copy_term_nonrec(list->elt, vars);
      res = icl_NewCons(copy, NULL);
      end = res;
    }
    else {
      end->next = icl_NewCons(icl_copy_term_nonrec(list->elt, vars), NULL);
      end = end->next;
    }
    list = list->next;
  }

  return(res);
}



/**
 * Creates a copy of the term, all in new memory.
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_CopyTerm(ICLTerm *t)
{
  return (icl_copy_term(t, NULL));
}


/**
 * Creates a new copy of a ListType list
 */
EXPORT_MSCPP
ICLListType * EXPORT_BORLAND
icl_CopyListType(ICLListType *list)
{
  return(icl_copy_list_type(list, NULL));
}



/**
 * Creates a new ICL object of type integer.
 * @param i integer value for the structure
 * @return a pointer to the new ICL object
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewInt(gint64 i)
{
  ICLTerm *res = malloc(sizeof(ICLTerm));
  gint64 *iptr = malloc(sizeof(gint64));

  *iptr = i;
  res->iclType = icl_int_type;
  res->p = iptr;
  res->magic_cookie = ICL_MAGIC_COOKIE;
  res->len = sizeof(gint64);

  res->refCount = 1;
  res->glibAlloc = 0;
  res->hadQuotes = 0;
  return (res);
}


/**
 * Creates a new ICL object of type float
 * @param f double value for the structure
 * @return a pointer to the new ICL object
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewFloat(double f)
{
  ICLTerm *res = malloc(sizeof(ICLTerm));
  double *fptr = malloc(sizeof(double));

  *fptr = f;
  res->iclType = icl_float_type;
  res->p = fptr;
  res->magic_cookie = ICL_MAGIC_COOKIE;
  res->len = sizeof(double);

  res->refCount = 1;
  res->glibAlloc = 0;
  res->hadQuotes = 0;
  return (res);
}


/**
 * Creates a new ICL object of type string. Uses a copy of the given string.
 * @param s string value for the structure
 * @return a pointer to the new ICL object or NULL if s is not valid
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewStr(char *s)
{
  ICLTerm *res = NULL;

  if (s) {
    res = malloc(sizeof(ICLTerm));

    res->iclType = icl_str_type;
    res->p = strdup(s);
    res->magic_cookie = ICL_MAGIC_COOKIE;
    res->refCount = 1;
    res->glibAlloc = 0;
    res->hadQuotes = 0;
    res->len = strlen(s);
  }

  return (res);
}

ICLTerm*
icl_NewStrNoCopy(char *s)
{
  ICLTerm *res = NULL;

  if (s) {
    res = malloc(sizeof(ICLTerm));

    res->iclType = icl_str_type;
    res->p = s;
    res->magic_cookie = ICL_MAGIC_COOKIE;
    res->refCount = 1;
    res->glibAlloc = 0;
    res->hadQuotes = 0;
    res->len = strlen(s);
  }

  return (res);
}

/**
 * Creates a new ICL object of type variable.
 * @param name string value containing the name for the structure
 * @return a pointer to the new ICL object or NULL if name isn't valid
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewVar(char *name)
{
  ICLTerm *res = NULL;

  if (name && *name) {
    res = malloc(sizeof(ICLTerm));

    res->iclType = icl_var_type;
    res->p = strdup(name);
    res->magic_cookie = ICL_MAGIC_COOKIE;
    res->refCount = 1;
    res->glibAlloc = 0;
    res->hadQuotes = 0;
    res->len = strlen(name);
  }

  return (res);
}

ICLTerm *
icl_NewVarNoCopy(char *name)
{
  ICLTerm *res = NULL;

  if (name && *name) {
    res = malloc(sizeof(ICLTerm));

    res->iclType = icl_var_type;
    res->p = name;
    res->magic_cookie = ICL_MAGIC_COOKIE;
    res->refCount = 1;
    res->glibAlloc = 0;
    res->hadQuotes = 0;
    res->len = strlen(name);
  }

  return (res);
}

/**
 * Creates a new ICL object of type structure given args as a list
 * @param functor string name for the structure
 * @param args an icl List object
 * @return a pointer to the new ICL object or NULL if invalid args or
 *         invalid functor
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewStructFromList(char *functor, ICLTerm *args)
{
  ICLTerm       *res = NULL;
  ICLStructType *st = NULL;

  if (icl_IsList(args) && icl_stIsStr(functor)) {

    res = malloc(sizeof(ICLTerm));
    st = malloc(sizeof(ICLStructType));

    st->name = strdup(functor);
    st->numArgs = icl_NumTerms(args);
    st->args = args;

    res->iclType = icl_struct_type;
    res->p = st;
    res->magic_cookie = ICL_MAGIC_COOKIE;
    res->refCount = 1;
    res->glibAlloc = 0;
    res->hadQuotes = 0;
    res->len = sizeof(st);
  }

  return (res);
}



/**
 * Creates a new ICL object of type structure. Uses a copy of functor.
 * @param functor string name for the structure
 * @param arity the new structure's arity
 * @param ... a variable length argument list containing pointers to ICLTerms
 * @return a pointer to the new ICL object or NULL if not valid args
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewStruct(char *functor, int arity, ...)
{
  ICLTerm *arg,  *res = NULL;

  va_list ap;	/* points to each unnamed arg in turn */
  int i=0;

  if (icl_stIsStr(functor)) {
    ICLStructType *st = malloc(sizeof(ICLStructType));
    ICLTerm *args;

    res = malloc(sizeof(ICLTerm));

    args = icl_NewList(NULL);

    /* copy args into list */
    va_start(ap, arity);	/* point ap to first unnamed arg */
    for (i=0; i< arity;i++) {
      arg = va_arg(ap, ICLTerm*);
      if (arg) {
        icl_AddToList(args, arg, TRUE);
      }
    }
    va_end(ap);

    st->name = strdup(functor);
    st->numArgs = arity;
    st->args = args;

    res->iclType = icl_struct_type;
    res->p = st;
    res->magic_cookie = ICL_MAGIC_COOKIE;
    res->refCount = 1;
    res->glibAlloc = 0;
    res->hadQuotes = 0;
    res->len = sizeof(st);
  }

  return (res);
}


/**
 * Returns a new element of ICLListType.
 */
EXPORT_MSCPP
ICLListType * EXPORT_BORLAND
icl_NewCons(ICLTerm *elt, ICLListType *tail)
{
  ICLListType *res = malloc(sizeof(ICLListType));

  res->elt = elt;
  res->next = tail;
  if(elt != NULL) {
    iclIncRef(elt);
  }

  return (res);
}

EXPORT_MSCPP
ICLTerm* EXPORT_BORLAND
icl_NewDataQ(void const* data, size_t dataLen)
{
  ICLTerm* res = malloc(sizeof(ICLTerm));
  res->p = malloc(dataLen);
  if(dataLen > 0) {
    memcpy(res->p, data, dataLen);
  }
  else {
    res->p = NULL;
  }
  res->len = dataLen;
  res->iclType = icl_dataq_type;
  res->magic_cookie = ICL_MAGIC_COOKIE;
  res->refCount = 1;
  res->glibAlloc = 0;
  res->hadQuotes = 0;

  return res;
}

ICLTerm*
icl_NewDataQNoCopy(void* data, size_t dataLen)
{
  ICLTerm* res = malloc(sizeof(ICLTerm));
  res->p = data;
  res->len = dataLen;
  res->iclType = icl_dataq_type;
  res->magic_cookie = ICL_MAGIC_COOKIE;
  res->refCount = 1;
  res->glibAlloc = 0;
  res->hadQuotes = 0;

  return res;
}

/**
 * Creates a new ICL object of type group.
 * @param startC a character which initially delimits the group (e.g. '{')
 * @param separator separator character
 * @param list a value of type list, probably returned by icl_NewCons()
 * @return a pointer to the new ICL object
 * @see icl_NewCons
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewGroup(char startC, char *separator, ICLListType *list)
{
  ICLTerm *res = malloc(sizeof(ICLTerm));
  ICLGroupType *gp = malloc(sizeof(ICLGroupType));

  res->iclType = icl_group_type;
  gp->startChar = startC;
  gp->separator = strdup(separator);
  gp->list = list;
  res->p = gp;
  res->magic_cookie = ICL_MAGIC_COOKIE;
  res->refCount = 1;
  res->glibAlloc = 0;
  res->hadQuotes = 0;
  res->len = sizeof(gp);

  return (res);
}

/**
 * Creates a new ICL object of type list.
 * @param list a value of type list, probably returned by icl_NewCons()
 * @return a pointer to the new ICL object
 * @see icl_NewCons
 */
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewList(ICLListType *list)
{
  ICLTerm *res = malloc(sizeof(ICLTerm));

  res->iclType = icl_list_type;
  res->p = list;
  res->magic_cookie = ICL_MAGIC_COOKIE;
  res->refCount = 1;
  res->glibAlloc = 0;
  res->hadQuotes = 0;
  res->len = sizeof(list);

  return (res);
}


EXPORT_MSCPP
void EXPORT_BORLAND
icl_FreeTermSingle(ICLTerm *elt)
{
  /* void* pc = current_text_addr(); */
  icl_FreeTermMulti(elt,0,0);
}

EXPORT_MSCPP
void EXPORT_BORLAND
icl_FreeTerm(ICLTerm *elt)
{
  icl_FreeTermMulti(elt,0,0);
}

/**
 * Free a memory pointer (string or term) and set it to NULL afterwards.
 * @param p a variable to deallocate
 * <p><b>Remarks:</b></p>
 * <ul>
 *   <li>icl_stFree() is better than free() because it checks that you will
 *     never attempt to free a NULL variable, and you will never
 *     try to free the same variable twice, which can lead to BIG problems!</li>
 *   <!--li>icl_stFree() is defined as a macro so that it is not necessary to pass
 *     in the address of the variable you want to free, which is unnatural.</li-->
 * </ul>
 */
EXPORT_MSCPP
void EXPORT_BORLAND
icl_stFree(void *p) {
  if (p) {
#ifdef NORMAL_GC
    GC_debug_free(p); p = 0;
#else
  free(p); p = 0;
#endif
  }
}

/****************************************************************************
 * name:    icl_FreeTermMulti
 * purpose: Frees all memory used by an object ptr
 * remarks: Use icl_Free() macro, which then sets the pointer to NIL
 ****************************************************************************/
static void
icl_FreeTermMulti(ICLTerm *elt, int n, void* pc)
{
#ifdef NORMAL_GC
  CHECK_LEAKS();
#endif
  /*
    int decRes = 0;
    int i = 0;
    int max = (n > 10 ? 10 : n);
    CHECK_LEAKS();

    if(elt != NULL) {
    iclDecRef(elt);
    }

    for(i = 0; i < max; i++) {
    fprintf(stderr, "  ");
    }
    fprintf(stderr, "icl_FreeTerm on %x called from %x recursion %i\n",

⌨️ 快捷键说明

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