libutils.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 691 行 · 第 1/2 页
C
691 行
&& (p[3] == '/' || p[3] == 0)){
while (o != target && *--o != '/');
if (o == target && *o == '/') {
++o;
}
p += 3;
}
else {
*o++ = *p++;
}
}
target[o-target] = 0;
return (char *)target;
}
/**
* Prints out debug messages.
*/
EXTERN void printDebug(int level, char *str, ...) {
if (level < DEBUG_LEVEL) {
char buf[512];
va_list ptr;
va_start(ptr,str);
vsprintf(buf,str,ptr);
printf("DEBUG : %s\n", buf);
va_end(ptr);
}
}
/**
* Prints out warning messages
*/
EXTERN void printWarning(int level, char *str, ...) {
if (level < DEBUG_LEVEL) {
char buf[512];
va_list ptr;
va_start(ptr,str);
vsprintf(buf,str,ptr);
printf("WARNING : %s\n", buf);
va_end(ptr);
}
}
/**
* Prints a dictionary's contents as ICLTerms.
*/
void print_dictionary(DICTIONARY *d) {
int i, n;
printf("Print dictionary of size %d\n", d->size);
for(i=0, n=d->size; i<n; i++)
printf("Key %s Value : %s\n",
icl_NewStringFromTerm((ICLTerm*)d->key[i]),
icl_NewStringFromTerm((ICLTerm*)d->value[i]));
}
/**
* Initialize the hash_table to the size asked for. Allocates space
* for the correct number of pointers and sets them to NULL. If it
* can't allocate sufficient memory, signals error by setting the size
* of the table to 0.
*/
hthash_table *htconstruct_table(hthash_table *table, size_t size)
{
size_t i;
htbucket **temp;
table -> size = size;
table -> table = (htbucket * *)malloc(sizeof(htbucket *) * size);
temp = table -> table;
if ( temp == NULL )
{
table -> size = 0;
return table;
}
for (i=0;i<size;i++)
temp[i] = NULL;
return table;
}
/*
* Hashes a string to produce an unsigned short, which should be
* sufficient for most purposes.
*/
static unsigned hthash(char *string)
{
unsigned ret_val = 0;
int i;
while (*string)
{
i = (int)(*string);
ret_val ^= i;
ret_val <<= 1;
string ++;
}
return ret_val;
}
/**
* Insert <code>key</code> into hash table.
* Returns pointer to old data associated with the key, if any, or
* NULL if the key wasn't in the table previously.
*/
void *htinsert(char *key, void *data, hthash_table *table)
{
unsigned val = hthash(key) % table->size;
htbucket *ptr;
/*
* NULL means this bucket hasn't been used yet. We'll simply
* allocate space for our new bucket and put our data there, with
* the table pointing at it.
*/
if (NULL == (table->table)[val])
{
(table->table)[val] = (htbucket *)malloc(sizeof(htbucket));
if (NULL==(table->table)[val])
return NULL;
(table->table)[val] -> key = strdup(key);
(table->table)[val] -> next = NULL;
(table->table)[val] -> data = data;
return (table->table)[val] -> data;
}
/*
* This spot in the table is already in use. See if the current string
* has already been inserted, and if so, increment its count.
*/
for (ptr = (table->table)[val];NULL != ptr; ptr = ptr -> next)
if (0 == strcmp(key, ptr->key))
{
void *old_data;
old_data = ptr->data;
ptr -> data = data;
return old_data;
}
/*
* This key must not be in the table yet. We'll add it to the head of
* the list at this spot in the hash table. Speed would be
* slightly improved if the list was kept sorted instead. In this case,
* this code would be moved into the loop above, and the insertion would
* take place as soon as it was determined that the present key in the
* list was larger than this one.
*/
ptr = (htbucket *)malloc(sizeof(htbucket));
if (NULL==ptr)
return 0;
ptr -> key = strdup(key);
ptr -> data = data;
ptr -> next = (table->table)[val];
(table->table)[val] = ptr;
return data;
}
/**
* Look up a key and return the associated data. Returns NULL if
* the key is not in the table.
*/
void *htlookup(char *key, hthash_table *table)
{
unsigned val = hthash(key) % table->size;
htbucket *ptr;
if (NULL == (table->table)[val])
return NULL;
for ( ptr = (table->table)[val];NULL != ptr; ptr = ptr->next )
{
if (0 == strcmp(key, ptr -> key ) ) {
return ptr->data;
}
}
return NULL;
}
/**
* Delete a key from the hash table and return associated
* data, or NULL if not present.
*/
void *htdel(char *key, hthash_table *table)
{
unsigned val = hthash(key) % table->size;
void *data;
htbucket *ptr, *last = NULL;
if (NULL == (table->table)[val])
return NULL;
/*
* Traverse the list, keeping track of the previous node in the list.
* When we find the node to delete, we set the previous node's next
* pointer to point to the node after ourself instead. We then delete
* the key from the present node, and return a pointer to the data it
* contains.
*/
for (last = NULL, ptr = (table->table)[val];
NULL != ptr;
last = ptr, ptr = ptr->next)
{
if (0 == strcmp(key, ptr -> key))
{
if (last != NULL )
{
data = ptr -> data;
last -> next = ptr -> next;
free(ptr->key);
free(ptr);
return data;
}
/*
* If 'last' still equals NULL, it means that we need to
* delete the first node in the list. This simply consists
* of putting our own 'next' pointer in the array holding
* the head of the list. We then dispose of the current
* node as above.
*/
else
{
data = ptr->data;
(table->table)[val] = ptr->next;
free(ptr->key);
free(ptr);
return data;
}
}
}
/*
* If we get here, it means we didn't find the item in the table.
* Signal this by returning NULL.
*/
return NULL;
}
/**
* Function htfree_table() iterates the table, calling this repeatedly to free
* each individual node. This, in turn, calls one or two other
* functions - one to free the storage used for the key, the other
* passes a pointer to the data back to a function defined by the user,
* process the data as needed.
*/
void htfree_node(char *key, void *data, void *otherData)
{
htfreeNodeData *oData;
(void)data;
oData = (htfreeNodeData *)otherData;
if (oData->function) {
void *toFree = htdel(key,oData->the_table);
oData->function(toFree);
}
else {
htdel(key,oData->the_table);
}
}
/**
* Frees a complete table by iterating over it and freeing each node.
* the second parameter is the address of a function it will call with a
* pointer to the data associated with each node. This function is
* responsible for freeing the data, or doing whatever is needed with
* it.
*/
void htfree_table(hthash_table *table, void (*func)(void *))
{
htfreeNodeData freeData;
freeData.function = func;
freeData.the_table = table;
htenumerate( table, htfree_node, &freeData);
free(table->table);
table->table = NULL;
table->size = 0;
}
/**
* Simply invokes the function given as the second parameter for each
* node in the table, passing it the key and the associated data.
*/
void htenumerate( hthash_table *table, void (*func)(char *, void *, void *), void *otherData)
{
unsigned i;
htbucket *temp;
htbucket *nextPtr;
for (i=0;i<table->size; i++)
{
if ((table->table)[i] != NULL)
{
nextPtr = (table->table)[i]->next;
for (temp = (table->table)[i];
NULL != temp;
temp = nextPtr)
{
nextPtr = temp->next;
func(temp -> key, temp->data, otherData);
}
}
}
}
void printer(char *key, void *data, void *otherData)
{
(void)otherData;
printf("Key = [%s], data = %s\n", key, (char *)data);
}
void htprint(hthash_table *table)
{
printf("Printing table\n");
htenumerate(table, printer, NULL);
}
/**
* @defgroup Utilities Utilities
*
* Some text about this module.
*
* @{
*/
/**
* @file libutils.h
*/
/**
* @file libutils.c
*/
/** @} */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?