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 + -
显示快捷键?