libicl.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 2,613 行 · 第 1/5 页
C
2,613 行
elt, pc, n);
if(n > 100) {
char* abort = 0;
fprintf(stderr, "icl_FreeTerm suspicious recursion number; aborting\n");
abort[0] = 1;
}
if(decRes < 0) {
char* abort = 0;
fprintf(stderr, "icl_FreeTerm duplicate free; aborting\n");
abort[0] = 1;
}
*/
if (icl_IsValid(elt)) {
if ((elt->iclType == icl_int_type) ||
(elt->iclType == icl_float_type) ||
(elt->iclType == icl_var_type) ||
(elt->iclType == icl_str_type) ||
(elt->iclType == icl_dataq_type)) {
if(elt->glibAlloc == 1) {
g_free(elt->p);
}
else {
free(elt->p); /* frees space allocated by pointer */
elt->p = NULL;
}
}
else
if (elt->iclType == icl_struct_type) {
ICLStructType *st = elt->p;
free(st->name);
st->name = NULL;
icl_FreeTermMulti(st->args, n + 1, pc);
free(elt->p);
elt->p = NULL;
}
else
if (elt->iclType == icl_list_type) {
ICLListType *list = elt->p;
ICLListType *next;
while (list) {
icl_FreeTermMulti(list->elt, n + 1, pc);
next = list->next;
memset(list, 0, sizeof(ICLListType));
free(list);
list = next;
}
elt->p = NULL;
}
if (elt->iclType == icl_group_type) {
ICLGroupType *gp = elt->p;
ICLListType *list = gp->list;
ICLListType *next;
free(gp->separator);
gp->separator = NULL;
while (list) {
icl_FreeTermMulti(list->elt, n + 1, pc);
next = list->next;
list->next = NULL;
memset(list, 0, sizeof(ICLListType));
free(list);
list = next;
}
free(gp);
elt->p = NULL;
}
memset(elt, 0, sizeof(ICLTerm));
elt->magic_cookie = 0xdeadbeef;
elt->iclType = icl_no_type;
free(elt);
#ifdef NORMAL_GC
CHECK_LEAKS();
#endif
}
}
#if 0
/****************************************************************************
* name: icl_ReuseMem
* purpose: A very simple form of garbage collection for ICLTerms.
* Often, a programmer wants to create a "temporary" ICL structure to
* pass to some procedure, such that the life of the structure needs only
* exist during that call. icl_ReuseMem can be used for this purpose, to
* recover the memory for a temporary structure.
* remarks:
* icl_ReuseMem keeps a static pointer of the last structure passed which
* it will free to make room for the next structure coming in. Therefore,
* the "life expectancy" of a structure passed to icl_ReuseMem is only
* until the next call to this function.
* warning:
* Do not use this function twice in the same call, since the second call
* will erase the value of the first (see above)
* ie. WRONG!!!
* do(icl_ReuseMem(icl_NewStr("a")), icl_ReuseMem(icl_NewStr("b")));
****************************************************************************/
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_ReuseMem(ICLTerm *elt)
{
static ICLTerm *last = NULL;
icl_Free(last);
last = elt;
return elt;
}
#endif
/****************************************************************************
* Structure testing routines
****************************************************************************/
/**
* Returns TRUE if object is of type List.
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsList(ICLTerm *elt)
{
return (icl_IsValid(elt) && (elt->iclType == icl_list_type));
}
/**
* Returns TRUE if object is of type Group.
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsGroup(ICLTerm *elt)
{
return (icl_IsValid(elt) && (elt->iclType == icl_group_type));
}
/**
* Returns TRUE if object is of type Struct.
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsStruct(ICLTerm *elt)
{
return (icl_IsValid(elt) && (elt->iclType == icl_struct_type));
}
/**
* Returns TRUE if object is of type Str.
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsStr(ICLTerm *elt)
{
return (icl_IsValid(elt) && (elt->iclType == icl_str_type));
}
/**
* Returns TRUE if object is of type Var.
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsVar(ICLTerm *elt)
{
return (icl_IsValid(elt) && (elt->iclType == icl_var_type));
}
/**
* Returns TRUE if object is of type Int.
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsInt(ICLTerm *elt)
{
return (icl_IsValid(elt) && (elt->iclType == icl_int_type));
}
/**
* Returns TRUE if object is of type Float.
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsFloat(ICLTerm *elt)
{
return (icl_IsValid(elt) && (elt->iclType == icl_float_type));
}
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsDataQ(ICLTerm* elt)
{
return (icl_IsValid(elt) && (elt->iclType == icl_dataq_type));
}
/**
* Returns TRUE if object is valid.
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_IsValid(ICLTerm *elt)
{
return (elt && (elt->magic_cookie == ICL_MAGIC_COOKIE));
}
/*****************************************************************************
* name: icl_IsGround
* purpose:
*****************************************************************************/
int icl_IsGround(ICLTerm *term)
{
ICLListType *plist = (ICLListType *)NULL;
if (! icl_IsValid(term))
return FALSE;
if(icl_IsVar(term))
return FALSE;
if(icl_IsStruct(term))
plist = icl_Arguments(term);
else if(icl_IsList(term))
plist = icl_List(term);
/* ??? check for any other complex types? */
while(icl_ListHasMoreElements(plist)) {
ICLTerm *el = icl_ListElement(plist);
if(!icl_IsGround(el))
return FALSE;
plist = icl_ListNextElement(plist);
}
return TRUE;
}
/**
* Get the data associated with this ICLTerm if it is of type
* icl_dataq_type.
*
* @return a pointer to the data, or NULL
* @see icl_dataq_type
*/
EXPORT_MSCPP
void* EXPORT_BORLAND
icl_DataQ(ICLTerm* elt)
{
if(icl_IsDataQ(elt)) {
return elt->p;
}
else {
return NULL;
}
}
EXPORT_MSCPP
size_t EXPORT_BORLAND
icl_DataQLen(ICLTerm* elt)
{
if(icl_IsDataQ(elt)) {
return elt->len;
}
else {
return 0;
}
}
/**
* Returns 0 if invalid.
*/
EXPORT_MSCPP
size_t EXPORT_BORLAND
icl_Len(ICLTerm* elt)
{
if(icl_IsValid(elt)) {
return elt->len;
}
else {
return 0;
}
}
/**
* Returns the value for an ICL int.
* If not valid, returns 0.
*/
EXPORT_MSCPP
gint64 EXPORT_BORLAND
icl_Int(ICLTerm *elt)
{
gint64 *i;
if (icl_IsInt(elt)) {
i = elt->p;
return (*i);
}
else return(0);
}
/**
* Returns the value for an ICL float.
* If not valid, returns 0.0.
*/
EXPORT_MSCPP
double EXPORT_BORLAND
icl_Float(ICLTerm *elt)
{
double *f;
if (icl_IsFloat(elt)) {
f = elt->p;
return (*f);
}
else return(0.0);
}
/**
* Returns the value for an ICL str, struct (functor), or an ICL var
* (returns name). If not valid, returns NULL.
* Otherwise returns a pointer to the true string value, which should
* <em>not</em> be deallocated or changed!!!
*/
EXPORT_MSCPP
char * EXPORT_BORLAND
icl_Str(ICLTerm *elt)
{
if (icl_IsStr(elt) || icl_IsVar(elt))
return((char*)(elt->p));
else
if (icl_IsStruct(elt)) {
ICLStructType *st = elt->p;
return(st->name);
}
else return(NULL);
}
/**
* Returns the functor for an ICL struct.
* If not valid, returns NULL.
* Otherwise returns a pointer to the true string value, which should
* <em>not</em> be deallocated or changed!!!
*/
EXPORT_MSCPP
char * EXPORT_BORLAND
icl_Functor(ICLTerm *elt)
{
if (icl_IsStruct(elt)) {
ICLStructType *st = elt->p;
return(st->name);
}
else {
return(NULL);
}
}
/**
* Returns a pointer to the list of arguments for an ICL structure.
* If not valid, returns NULL.
*/
EXPORT_MSCPP
ICLListType * EXPORT_BORLAND
icl_Arguments(ICLTerm *elt)
{
if (icl_IsStruct(elt)) {
ICLStructType *st = elt->p;
return(icl_List(st->args));
}
else return(NULL);
}
/**
* Returns the start character and separators for a group.
* If not valid group, returns FALSE.
* <p>example:</p>
* <pre>
* {a ; b ; c} returns '{' and ";"
* </pre>
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_GetGroupChars(ICLTerm *group, char *startC, char **sep)
{
if (icl_IsGroup(group)) {
ICLGroupType *gt = group->p;
*startC = gt->startChar;
*sep = strdup(gt->separator);
return(TRUE);
}
else return(FALSE);
}
/**
* Returns a pointer to the list of elements for an ICL list.
* If not valid, returns NULL. Also works for an icl_Struct
* (equivalent to icl_Arguments) or an icl_Group.
*/
EXPORT_MSCPP
ICLListType * EXPORT_BORLAND
icl_List(ICLTerm *elt)
{
if (icl_IsList(elt)) {
ICLListType *list = elt->p;
return(list);
}
else
if (icl_IsGroup(elt)) {
ICLGroupType *gp = elt->p;
ICLListType *list = gp->list;
return(list);
}
else
if (icl_IsStruct(elt)) {
ICLStructType *st = elt->p;
return(icl_List(st->args));
}
else return(NULL);
}
EXPORT_MSCPP
ICLListType * EXPORT_BORLAND icl_ListNext(ICLListType* t)
{
return t->next;
}
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND icl_ListElt(ICLListType* t)
{
return t->elt;
}
ICLListType* icl_copy_listtype(ICLListType* l)
{
ICLListType* newList = NULL;
ICLListType* prev = NULL;
while(l) {
newList = (ICLListType*)malloc(sizeof(ICLListType));
if(prev != NULL) {
prev->next = newList;
}
newList->next = NULL;
newList->elt = icl_CopyTerm(l->elt);
l = l->next;
prev = newList;
}
return newList;
}
/**
* Returns a pointer to the list of elements for an ICL list.
* If not valid, returns NULL. Also works for an icl_Struct
* (equivalent to icl_Arguments) or an icl_Group.
*/
EXPORT_MSCPP
ICLListType * EXPORT_BORLAND
icl_ListCopy(ICLTerm *elt)
{
if (icl_IsList(elt)) {
ICLListType *list = elt->p;
return(icl_copy_listtype(list));
}
else
if (icl_IsGroup(elt)) {
ICLGroupType *gp = elt->p;
ICLListType *list = gp->list;
return(icl_copy_listtype(list));
}
else
if (icl_IsStruct(elt)) {
ICLStructType *st = elt->p;
return(icl_copy_listtype(icl_List(st->args)));
}
else {
return(NULL);
}
}
/****************************************************************************
* List manipulation
****************************************************************************/
/**
* Adds an object at the beginning or the end of the list or a group.
* @return TRUE if the object can be added
*/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_AddToList(ICLTerm *list, ICLTerm *elt, int atEnd)
{
if (icl_IsValid(elt) && (icl_IsList(list) || icl_IsGroup(list)) ) {
/* Empty list */
if (icl_IsList(list) && !list->p) {
list->p = icl_NewCons(elt, NULL);
return TRUE;
}
else {
/* at beginning */
if (!atEnd) {
list->p = icl_NewCons(elt, list->p);
}
else {
/* Group of one elt ?? */
if (icl_IsGroup(list) && (!((ICLGroupType*)list->p)->list))
((ICLGroupType *)list->p)->list = icl_NewCons(elt, NULL);
/* l
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?