00001 #include <neuro/stringtable.h>
00002 #include <assert.h>
00003 #include <malloc.h>
00004 #include <string.h>
00005
00006
00007
00008 #ifndef _GNU_SOURCE
00009 #define _GNU_SOURCE
00010 #endif
00011 #ifndef __USE_GNU
00012 #define __USE_GNU
00013 #endif
00014
00015 #include <search.h>
00016
00017 struct StringTableNode {
00018 char *key;
00019 void *val;
00020 };
00021
00022 struct StringTable {
00023 void *stringTableNodeTab;
00024 };
00025
00026 struct StringTable *newStringTable(void)
00027 {
00028 struct StringTable *st;
00029 st = calloc(sizeof(struct StringTable), 1);
00030 return st;
00031 }
00032
00033 static const char *makeStringFromInt(int key)
00034 {
00035 static char buf[16];
00036 sprintf(buf, "%d", key);
00037 return buf;
00038 }
00039
00040 int stringToInt(const char *str)
00041 {
00042 int result;
00043 sscanf(str, "%d", &result);
00044 return result;
00045 }
00046
00047 static int compare(const void *a, const void *b)
00048 {
00049 const char *ca = *(const char **) a, *cb = * (const char **) b;
00050 return strcmp(ca, cb);
00051 }
00052
00053 int putInt(struct StringTable *st, int key, void *val)
00054 {
00055 return putString(st, makeStringFromInt(key), val);
00056 }
00057
00058 int putString(struct StringTable *st, const char *key, void *val)
00059 {
00060 struct StringTableNode *result;
00061 result = (struct StringTableNode *)
00062 tfind(&key, &st->stringTableNodeTab, compare);
00063 if (result == NULL) {
00064 result = calloc(sizeof(*result), 1);
00065 result->key = strdup(key);
00066 result->val = val;
00067 tsearch(result, &st->stringTableNodeTab, compare);
00068 }
00069 else {
00070 result = * (struct StringTableNode **) result;
00071 result->val = val;
00072 }
00073 return 0;
00074 }
00075
00076 int delInt(struct StringTable *st, int key)
00077 {
00078 return delString(st, makeStringFromInt(key));
00079 }
00080
00081 int delString(struct StringTable *st, const char *key)
00082 {
00083 struct StringTableNode *result;
00084 char *toFree;
00085 result = (struct StringTableNode *)
00086 tfind(&key, &st->stringTableNodeTab, compare);
00087 if (result == NULL) return ERR_NOSTRING;
00088 result = * (struct StringTableNode **) result;
00089 toFree = result->key;
00090 tdelete(result, &st->stringTableNodeTab, compare);
00091 free(toFree);
00092 free(result);
00093 return 0;
00094 }
00095
00096 void *findInt(struct StringTable *st, int key)
00097 {
00098 return findString(st, makeStringFromInt(key));
00099 }
00100
00101 void *findString(struct StringTable *st, const char *key)
00102 {
00103 struct StringTableNode **result;
00104 result = (struct StringTableNode **)
00105 tfind(&key, &st->stringTableNodeTab, compare);
00106 return (result == NULL) ? NULL : (*result)->val;
00107 }
00108
00109 static void *audata;
00110 static StringTableIterator asti;
00111 static struct StringTable *ast;
00112
00113 static void allFunc(const void *nodep, const VISIT which, const int depth)
00114 {
00115 struct StringTableNode *result;
00116 if (which != endorder && which != leaf) return;
00117 result = *(struct StringTableNode **) nodep;
00118 asti(ast, result->key, result->val, audata);
00119 }
00120
00121 static void freeFunc(void *nodep)
00122 {
00123 struct StringTableNode *result;
00124 result = (struct StringTableNode *) nodep;
00125 free(result->key);
00126 free(result);
00127 }
00128
00129
00130 void allStrings(struct StringTable *st, StringTableIterator sti, void *udata)
00131 {
00132 audata = udata;
00133 asti = sti;
00134 ast = st;
00135 twalk(st->stringTableNodeTab, allFunc);
00136 }
00137
00138 void freeStringTable(struct StringTable *st)
00139 {
00140 tdestroy(st->stringTableNodeTab, freeFunc);
00141 st->stringTableNodeTab = NULL;
00142 free(st);
00143 }
00144