#include <assert.h>
#include <memory.h>
#include "mem.h"
+#include "types.h"
#include "q.h"
// ------------------------------- malloc, alloc routines ---------------------
}
void string_set(string_t*str, const char*text)
{
- str->len = strlen(text);
+ if(text) {
+ str->len = strlen(text);
+ } else {
+ str->len = 0;
+ }
str->str = text;
}
string_t string_new(const char*text, int len)
string_t string_new2(const char*text)
{
string_t s;
- s.len = strlen(text);
+ if(text) {
+ s.len = strlen(text);
+ } else {
+ s.len = 0;
+ }
s.str = text;
return s;
}
}
}
}
+
int dict_count(dict_t*h)
{
return h->num;
}
-void* dict_lookup2(dict_t*h, const char*s, int len)
+void* dict_lookup4(dict_t*h, const char*s, int len, const void*data)
{
if(!h->num)
return 0;
/* check subsequent entries for a match */
while(e) {
- if(e->len == len && !memcmp(e->s, s, len)) {
+ if(e->len == len && !memcmp(e->s, s, len) && (!data || data==e->data)) {
return e->data;
}
e = e->next;
}
return 0;
}
+void* dict_lookup3(dict_t*h, const char*s, const void*data)
+{
+ int l = strlen(s);
+ return dict_lookup4(h, s, l, data);
+}
+void* dict_lookup2(dict_t*h, const char*s, int len)
+{
+ return dict_lookup4(h, s, len, 0);
+}
void* dict_lookup(dict_t*h, const char*s)
{
int l = strlen(s);
}
return 0;
}
+
+static dictentry_t* dict_get_all(dict_t*h, const char*s)
+{
+ if(!h->num)
+ return 0;
+ unsigned int ohash = string_hash2(s);
+ unsigned int hash = ohash % h->hashsize;
+ return h->slots[hash];
+}
+
void dict_foreach_keyvalue(dict_t*h, void (*runFunction)(void*data, const char*key, void*val), void*data)
{
int t;
}
}
}
+
void dict_free_all(dict_t*h, void (*freeFunction)(void*))
{
int t;
rfx_free(h->slots);
memset(h, 0, sizeof(dict_t));
}
+
void dict_clear(dict_t*h)
{
dict_free_all(h, 0);
}
+
void dict_destroy(dict_t*dict)
{
dict_clear(dict);
rfx_free(map);
}
+// ------------------------------- array_t --------------------------------------
+
+array_t* array_new() {
+ array_t*d = malloc(sizeof(array_t));
+ memset(d, 0, sizeof(array_t));
+ d->entry2pos = dict_new();
+ return d;
+}
+void array_free(array_t*array) {
+ dict_destroy(array->entry2pos);
+ array->entry2pos;
+ if(array->d) {
+ free(array->d);array->d = 0;
+ }
+ free(array);
+}
+const char*array_getkey(array_t*array, int nr) {
+ if(nr > array->num || nr<0) {
+ printf("error: reference to element %d in array[%d]\n", nr, array->num);
+ *(int*)0 = 0;
+ return 0;
+ }
+ return array->d[nr].name;
+}
+char*array_getvalue(array_t*array, int nr) {
+ if(nr > array->num || nr<0) {
+ printf("error: reference to element %d in array[%d]\n", nr, array->num);
+ *(int*)0 = 0;
+ return 0;
+ }
+ return array->d[nr].data;
+}
+int array_append(array_t*array, const char*name, const void*data) {
+ while(array->size <= array->num) {
+ array->size += 64;
+ if(!array->d) {
+ array->d = malloc(sizeof(array_entry_t)*array->size);
+ } else {
+ array->d = realloc(array->d, sizeof(array_entry_t)*array->size);
+ }
+ }
+ if(name) {
+ array->d[array->num].name = strdup(name);
+ } else {
+ array->d[array->num].name = 0;
+ }
+ array->d[array->num].data = (void*)data;
+ dict_put2(array->entry2pos, name, (void*)(ptroff_t)(array->num+1));
+ return array->num++;
+}
+int array_find(array_t*array, const char*name)
+{
+ if(!name)
+ name = "";
+ int pos = (int)(ptroff_t)dict_lookup(array->entry2pos, name);
+ return pos-1;
+}
+int array_find2(array_t*array, const char*name, void*data)
+{
+ if(!name)
+ name = "";
+ int len= strlen(name);
+
+ dictentry_t*e = dict_get_all(array->entry2pos, name);
+
+ while(e) {
+ int index = ((int)(ptroff_t)e->data) - 1;
+ if(e->len == len && !memcmp(e->s, name, len) && array->d[index].data == data) {
+ return index;
+ }
+ e = e->next;
+ }
+ return -1;
+}
+int array_update(array_t*array, const char*name, void*data) {
+ int pos = array_find(array, name);
+ if(pos>=0) {
+ array->d[pos].data = data;
+ return pos;
+ }
+ return array_append(array, name, data);
+}
+int array_append_if_new(array_t*array, const char*name, void*data) {
+ int pos = array_find(array, name);
+ if(pos>=0)
+ return pos;
+ return array_append(array, name, data);
+}
+
+// ------------------------------- list_t --------------------------------------
+
+struct _commonlist;
+typedef struct _listinfo {
+ int size;
+ struct _commonlist*last;
+} listinfo_t;
+
+typedef struct _commonlist {
+ void*entry;
+ struct _commonlist*next;
+ listinfo_t info[0];
+} commonlist_t;
+
+int list_length(void*_list)
+{
+ commonlist_t*l = (commonlist_t*)_list;
+ if(!l)
+ return 0;
+ return l->info[0].size;
+}
+void list_append_(void*_list, void*entry)
+{
+ commonlist_t**list = (commonlist_t**)_list;
+ commonlist_t* n = 0;
+ if(!*list) {
+ n = malloc(sizeof(commonlist_t)+sizeof(listinfo_t));
+ *list = n;
+ } else {
+ n = malloc(sizeof(commonlist_t));
+ (*list)->info[0].last->next = n;
+ }
+ n->next = 0;
+ n->entry = entry;
+ (*list)->info[0].last = n;
+ (*list)->info[0].size++;
+}
+void list_free_(void*_list)
+{
+ commonlist_t**list = (commonlist_t**)_list;
+ commonlist_t*l = *list;
+ while(l) {
+ commonlist_t*next = l->next;
+ free(l);
+ l = next;
+ }
+ *list = 0;
+}
extern "C" {
#endif
+#define NEW(t,y) t*y = (t*)malloc(sizeof(t));memset(y, 0, sizeof(t));
+
/* dynamically growing mem section */
typedef struct _mem_t {
char*buffer;
int num;
} dict_t;
+/* array of key/value pairs, with fast lookup */
+typedef struct _array_entry {
+ const char*name;
+ void*data;
+} array_entry_t;
+
+typedef struct _array {
+ int num;
+ int size;
+ array_entry_t*d;
+ dict_t*entry2pos;
+} array_t;
+
/* array of strings, string<->int mapping,
with O(1) for int->string lookup and
~O(n/hashsize) for string->int lookup */
int(*compare)(const void *, const void *);
} heap_t;
+char* strdup_n(const char*str, int size);
+
void mem_init(mem_t*mem);
int mem_put(mem_t*m, void*data, int length);
int mem_putstring(mem_t*m, string_t str);
void stringarray_init(stringarray_t*sa, int hashsize);
void stringarray_put(stringarray_t*sa, string_t str);
+
char* stringarray_at(stringarray_t*sa, int pos);
string_t stringarray_at2(stringarray_t*sa, int pos);
int stringarray_find(stringarray_t*sa, string_t*str);
void dict_put(dict_t*dict, string_t t1, void* t2);
void dict_put2(dict_t*dict, const char* t1, void* t2);
void dict_put3(dict_t*dict, const char* t1, int len, void* t2);
-
-stringarray_t* dict_index(dict_t*dict);
-int dict_count(dict_t* dict);
-void* dict_lookup(dict_t*dict, const char*name);
-void dict_dump(dict_t*dict, FILE*fi, const char*prefix);
-char dict_del(dict_t*dict, const char* name);
+int dict_count(dict_t*h);
+void dict_dump(dict_t*h, FILE*fi, const char*prefix);
+void* dict_lookup3(dict_t*h, const char*s, const void*data);
+void* dict_lookup2(dict_t*h, const char*s, int len);
+void* dict_lookup(dict_t*h, const char*s);
+char dict_del(dict_t*h, const char*s);
void dict_foreach_keyvalue(dict_t*h, void (*runFunction)(void*data, const char*key, void*val), void*data);
void dict_foreach_value(dict_t*h, void (*runFunction)(void*));
void dict_free_all(dict_t*h, void (*freeFunction)(void*));
-void dict_clear(dict_t*dict);
+void dict_clear(dict_t*h);
void dict_destroy(dict_t*dict);
void map_init(map_t*map);
void heap_dump(heap_t*h, FILE*fi);
void** heap_flatten(heap_t*h);
-char* strdup_n(const char*str, int size);
+array_t* array_new();
+void array_free(array_t*array);
+const char*array_getkey(array_t*array, int nr);
+char*array_getvalue(array_t*array, int nr);
+int array_append(array_t*array, const char*name, const void*data);
+int array_find(array_t*array, const char*name);
+int array_find2(array_t*array, const char*name, void*data);
+int array_update(array_t*array, const char*name, void*data);
+int array_append_if_new(array_t*array, const char*name, void*data);
+
+#define DECLARE(x) struct _##x;typedef struct _##x x##_t;
+#define DECLARE_LIST(x) \
+struct _##x##_list { \
+ struct _##x* x; \
+ struct _##x##_list*next; \
+}; \
+typedef struct _##x##_list x##_list_t;
+int list_length(void*_list);
+void list_append_(void*_list, void*entry);
+void list_free_(void*_list);
+#define list_new() ((void*)0)
+#define list_append(list, e) {sizeof((list)->next);list_append_(&(list),(e));}
+#define list_free(list) {sizeof((list)->next);list_free_(&(list));}
#ifdef __cplusplus
}