libicl.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 2,613 行 · 第 1/5 页
C
2,613 行
if(hashedVal != NULL) {
free((*term)->p);
(*term)->p = strdup(hashedVal);
}
else {
char tempName[10];
sprintf(tempName, "_%d", rename_vars_index);
rename_vars_index++;
htinsert((char *)((*term)->p),strdup(tempName),knownVars);
free((*term)->p);
(*term)->p = strdup(tempName);
}
}
else
if (((*term)->iclType == icl_list_type) ||
((*term)->iclType == icl_group_type) ||
((*term)->iclType == icl_struct_type)) {
l = icl_List(*term);
while (l) {
icl_rename_vars_termhelper(&l->elt, knownVars);
l = l->next;
}
}
}
}
/**
* Renames all unique vars in a term to "_NUM" format.
* Used by asserts to get around variable name collisions
*/
static
void icl_rename_vars_term(ICLTerm **term)
{
hthash_table knownVars;
htconstruct_table(&knownVars, 271);
icl_rename_vars_termhelper(term, &knownVars);
#ifdef NORMAL_GC
htfree_table(&knownVars,GC_debug_free);
#else
htfree_table(&knownVars,free);
#endif
}
/*****************************************************************************
* Trace and error messages
*****************************************************************************/
/****************************************************************************
* Structure construction routines
****************************************************************************/
struct compoundInfo_s
{
char* preChild;
size_t preChildLen;
char* postChild;
size_t postChildLen;
char* preAllButFirst;
size_t preAllButFirstLen;
char* postAllButLast;
size_t postAllButLastLen;
char* postPend;
size_t postPendLen;
int numChildrenToDo;
int originalNumChildren;
}
;
typedef struct compoundInfo_s compoundInfo_t;
compoundInfo_t* compoundInfo_new()
{
compoundInfo_t* res = (compoundInfo_t*)malloc(sizeof(compoundInfo_t));
memset(res, 0, sizeof(compoundInfo_t));
return res;
}
int compoundInfo_finished(compoundInfo_t* ci)
{
if(ci->numChildrenToDo == 0) {
return TRUE;
}
else {
return FALSE;
}
}
void compoundInfo_setNumChildren(compoundInfo_t* ci, int n)
{
ci->numChildrenToDo = n;
ci->originalNumChildren = n;
}
int compoundInfo_getCurrentChildNum(compoundInfo_t* ci)
{
return ci->originalNumChildren - ci->numChildrenToDo;
}
void compoundInfo_setPreAllButFirst(compoundInfo_t* ci, char* s, size_t len)
{
ci->preAllButFirst = s;
ci->preAllButFirstLen = len;
}
void compoundInfo_setPostAllButLast(compoundInfo_t* ci, char* s, size_t len)
{
ci->postAllButLast = s;
ci->postAllButLastLen = len;
}
void compoundInfo_setPreChild(compoundInfo_t* ci, char* s, size_t len)
{
ci->preChild = s;
ci->preChildLen = len;
}
void compoundInfo_setPostChild(compoundInfo_t* ci, char* s, size_t len)
{
ci->postChild = s;
ci->postChildLen = len;
}
void compoundInfo_setPostPend(compoundInfo_t* ci, char* s, size_t len)
{
ci->postPend = s;
ci->postPendLen = len;
}
char* compoundInfo_getPreChild(compoundInfo_t* ci, int i, size_t* len)
{
if(ci->preAllButFirst != NULL) {
if(i != 0) {
*len = ci->preAllButFirstLen;
return ci->preAllButFirst;
}
else {
*len = 0;
return NULL;
}
}
else {
*len = ci->preChildLen;
return ci->preChild;
}
}
char* compoundInfo_getPostChild(compoundInfo_t* ci, int i, size_t* len)
{
if(ci->postAllButLast != NULL) {
if(i != ci->originalNumChildren - 1) {
*len = ci->postAllButLastLen;
return ci->postAllButLast;
}
else {
*len = 0;
return NULL;
}
}
else {
*len = ci->postChildLen;
return ci->postChild;
}
}
char* compoundInfo_getPostPend(compoundInfo_t* ci, size_t* len)
{
*len = ci->postPendLen;
return ci->postPend;
}
void compoundInfo_childFinished(compoundInfo_t* ci)
{
--(ci->numChildrenToDo);
}
/**
* You must free termAsString when you are done with it.
*/
int icl_toWireString(ICLTerm* t, char** termAsString, size_t* termAsStringLen)
{
GByteArray* bytes = g_byte_array_new();
GPtrArray* compoundList = g_ptr_array_new();
GPtrArray* workingList = g_ptr_array_new();
ICLTerm* currentTerm = NULL;
compoundInfo_t* sentinel;
compoundInfo_t* ci;
compoundInfo_t* currentCompound;
char startChar;
char* separator;
int childNum;
char* tmpData;
size_t tmpLen;
int numberLen;
int isCompound;
int numArgs;
char* functor;
int zeroLenCompound = FALSE;
int compoundSize = 0;
int i;
unsigned int ui;
/*
{
char* ds = icl_NewStringFromTerm(t);
printf("icl_toWireString() working on %s\n", ds);
icl_stFree(ds);
}
*/
g_ptr_array_add(workingList, t);
sentinel = compoundInfo_new();
sentinel->numChildrenToDo = 1;
sentinel->originalNumChildren = 1;
g_ptr_array_add(compoundList, sentinel);
while((compoundList->len > 0) ||
(workingList->len > 0)) {
zeroLenCompound = FALSE;
currentTerm = (ICLTerm*)g_ptr_array_index(workingList, workingList->len - 1);
(void)g_ptr_array_remove_index(workingList, workingList->len - 1);
currentCompound = (compoundInfo_t*)g_ptr_array_index(compoundList, compoundList->len - 1);
childNum = compoundInfo_getCurrentChildNum(currentCompound);
tmpData = compoundInfo_getPreChild(currentCompound, childNum, &tmpLen);
if(tmpData != NULL) {
g_byte_array_append(bytes, tmpData, tmpLen);
}
switch(currentTerm->iclType) {
case icl_list_type:
g_byte_array_append(bytes, "[", 1);
numArgs = icl_NumTerms(currentTerm);
ci = compoundInfo_new();
compoundInfo_setPostPend(ci, "]", 1);
compoundInfo_setNumChildren(ci, numArgs);
compoundInfo_setPreAllButFirst(ci, ",", 1);
g_ptr_array_add(compoundList, ci);
isCompound = TRUE;
break;
case icl_group_type:
icl_GetGroupChars(currentTerm, &startChar, &separator);
icl_stFree(separator);
g_byte_array_append(bytes, &startChar, 1);
numArgs = icl_NumTerms(currentTerm);
ci = compoundInfo_new();
switch(startChar) {
case '{':
compoundInfo_setPostPend(ci, "}", 1);
default:
compoundInfo_setPostPend(ci, ")", 1);
}
compoundInfo_setNumChildren(ci, numArgs);
compoundInfo_setPreAllButFirst(ci, ",", 1);
g_ptr_array_add(compoundList, ci);
isCompound = TRUE;
break;
case icl_struct_type:
functor = icl_Functor(currentTerm);
numArgs = icl_NumTerms(currentTerm);
ci = compoundInfo_new();
g_byte_array_append(bytes, functor, strlen(functor));
g_byte_array_append(bytes, "(", 1);
compoundInfo_setPostPend(ci, ")", 1);
compoundInfo_setNumChildren(ci, numArgs);
compoundInfo_setPreAllButFirst(ci, ",", 1);
g_ptr_array_add(compoundList, ci);
isCompound = TRUE;
break;
case icl_int_type:
case icl_float_type:
case icl_str_type:
case icl_var_type:
case icl_dataq_type:
isCompound = FALSE;
numArgs = 0;
break;
default:
fprintf(stderr, "libicl.c icl_toWireString() unknown type [%i] in term at %p\n", currentTerm->iclType, currentTerm);
return FALSE;
}
if(isCompound) {
ICLTerm* toAdd;
/*
printf("Found compound with %i args; compoundList has %i elements\n", numArgs, compoundList->len);
*/
if(numArgs > 0) {
for(i = numArgs - 1; i >= 0; --i) {
toAdd = icl_NthTerm(currentTerm, i + 1);
g_ptr_array_add(workingList, toAdd);
{
char* ds = icl_NewStringFromTerm(toAdd);
//printf("Added child [%s] at index %i to workingList; workingList length = %i\n", ds, i, workingList->len);
icl_stFree(ds);
}
}
continue;
}
else {
zeroLenCompound = TRUE;
}
}
compoundSize = compoundList->len;
currentCompound = (compoundInfo_t*)g_ptr_array_index(compoundList, compoundList->len - 1);
if(!zeroLenCompound) {
switch(currentTerm->iclType) {
case icl_int_type:
numberLen = snprintf(NULL, 0, "%lld", *((gint64*)currentTerm->p));
if(numberLen < 0) {
numberLen = 128;
}
tmpData = (char*)malloc(numberLen + 1);
numberLen = snprintf(tmpData, numberLen + 1, "%lld", *((gint64*)currentTerm->p));
if(numberLen < 0) {
numberLen = 128;
}
g_byte_array_append(bytes, tmpData, strlen(tmpData));
/*
printf("Wrote %i bytes for integer %s\n", numberLen, tmpData);
*/
free(tmpData);
break;
case icl_float_type:
numberLen = snprintf(NULL, 0, "%f", *((double*)currentTerm->p));
if(numberLen < 0) {
numberLen = 128;
}
tmpData = (char*)malloc(numberLen + 1);
numberLen = snprintf(tmpData, numberLen + 1, "%f", *((double*)currentTerm->p));
if(numberLen < 0) {
numberLen = 128;
}
g_byte_array_append(bytes, tmpData, strlen(tmpData));
/*
printf("Wrote %i bytes for float %s\n", numberLen, tmpData);
*/
free(tmpData);
break;
case icl_var_type:
g_byte_array_append(bytes, (char*)currentTerm->p, strlen((char*)currentTerm->p));
/*
printf("Wrote %i bytes for var %s\n", strlen((char*)currentTerm->p), (char*)currentTerm->p);
*/
break;
case icl_str_type:
if(currentTerm->hadQuotes == 1) {
tmpData = icl_stQuoteForce((char*)currentTerm->p);
}
else {
tmpData = icl_stQuote((char*)currentTerm->p);
}
g_byte_array_append(bytes, tmpData, strlen(tmpData));
/* printf("Wrote %i bytes for str %s\n", strlen((char*)currentTerm->p), (char*)currentTerm->p); */
/* don't free tmpData--I'd rather icl_stQuote returned new memory, but
* that's not the way it is
*/
break;
case icl_dataq_type:
tmpData = (char*)currentTerm->p;
/* printf("Writing icl_dataq_type of length %i\n", currentTerm->len); */
g_byte_array_append(bytes, "icldataq(\"", 10);
for(ui = 0; ui < currentTerm->len; ++ui) {
if(tmpData[ui] == '"') {
g_byte_array_append(bytes, "\"\"", 2);
}
else {
g_byte_array_append(bytes, &tmpData[ui], 1);
}
}
g_byte_array_append(bytes, "\")", 2);
break;
default:
fprintf(stderr, "libicl.c icl_toWireString() unknown non-compound type [%i] at %p\n", currentTerm->iclType, currentTerm);
return FALSE;
}
tmpData = compoundInfo_getPostChild(currentCompound, compoundInfo_getCurrentChildNum(currentCompound), &tmpLen);
if(tmpData != NULL) {
g_byte_array_append(bytes, tmpData, tmpLen);
}
compoundInfo_childFinished(currentCompound);
/*
printf("Child finished for current compound\n");
*/
}
else {
/* nothing */
}
while(compoundInfo_finished(currentCompound)) {
tmpData = compoundInfo_getPostPend(currentCompound, &tmpLen);
if(tmpData != NULL) {
g_byte_array_append(bytes, tmpData, tmpLen);
/*
printf("Wrote %i bytes for postPend on compound %s\n", tmpLen, tmpData);
*/
}
(void)g_ptr_array_remove_index(compoundList, compoundList->len - 1);
free(currentCompound);
/*
printf("Compound finished compoundList length = %i\n", compoundList->len);
*/
if(compoundList->len == 0) {
#ifdef NORMAL_GC
*termAsString = (char*)malloc(bytes->len);
memcpy(*termAsString, bytes->data, bytes->len);
*termAsStringLen = bytes->len;
g_byte_array_free(bytes, FALSE);
g_ptr_array_free(compoundList, TRUE);
g_ptr_array_free(workingList, TRUE);
#else
*termAsString = bytes->data;
*termAsStringLen = bytes->len;
g_byte_array_free(bytes, FALSE);
g_ptr_array_free(compoundList, TRUE);
g_ptr_array_free(workingList, TRUE);
#endif
return TRUE;
}
currentCompound = (compoundInfo_t*)g_ptr_array_index(compoundList, compoundList->len - 1);
tmpData = compoundInfo_getPostChild(currentCompound, compoundInfo_getCurrentChildNum(currentCompound), &tmpLen);
if(tmpData != NULL) {
g_byte_array_append(bytes, tmpData, tmpLen);
}
compoundInfo_childFinished(currentCompound);
/*
printf("Child finished for current compound (through adding another compound)\n");
*/
}
}
fprintf(stderr, "libicl.c icl_toWireString() This should never be reached\n");
g_byte_array_free(bytes, TRUE);
g_ptr_array_free(compoundList, TRUE);
g_ptr_array_free(workingList, TRUE);
return FALSE;
}
/**
* Create a new IclTerm from the given data.
*
* @param data the data representing the term.
* @param len the length of the data. If data is a char*,
* this does not include the ending '\0' character.
*/
EXPORT_MSCPP
ICLTerm* EXPORT_BORLAND
icl_NewTermFromData(char* data, size_t len)
{
ICLTerm* res = parser_getTermFromString(data, len);
CHECK_LEAKS();
return res;
}
/**
* Returns a pointer to a new structured Icl term given string
* containing an ICL expression,
* or NULL if a valid object could not be created.
*
* @deprecated Use icl_NewTermFromData() instead
*/
EXPORT_MSCPP
ICLTerm * EXPORT_BORLAND
icl_NewTermFromString(char* t)
{
ICLTerm* res = NULL;
if(t != NULL) {
res = icl_NewTermFromData(t, strlen(t));
CHECK_LEAKS();
return res;
}
else {
return NULL;
}
}
/**
* Creates a string representation from an ICL term.
* The string value is created in a new space which should be
* icl_stFree'd when finished using.
*/
EXPORT_MSCPP
char * EXPORT_BORLAND
icl_NewStringFromTerm(ICLTerm *t)
{
char *res = NULL;
char* tmp = NULL;
int tmpBufSz = 0;
if (t==NULL)
return NULL;
/* Make sure the term is OK */
if (!icl_IsValid(t))
return NULL;
if (icl_IsVar(t)) {
res = strdup(t->p);
}
else if (icl_IsInt(t)) {
tmpBufSz = snprintf(tmp, 0, "%lld", icl_Int(t));
if(tmpBufSz < 0) {
tmpBufSz = 128;
}
++tmpBufSz;
tmp = (char*)malloc(tmpBufSz * sizeof(char));
(void)memset(tmp, 0, tmpBufSz);
snprintf(tmp, tmpBufSz, "%lld", icl_Int(t));
res = tmp;
}
else if (icl_IsFloat(t)) {
tmpBufSz = snprintf(tmp, 0, "%f", icl_Float(t));
if(tmpBufSz < 0) {
tmpBufSz = 128;
}
++tmpBufSz;
tmp = (char*)malloc(tmpBufSz * sizeof(char));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?