#define _GNU_SOURCE #include "strpool.h" #include #include #undef uthash_nonfatal_oom #define uthash_nonfatal_oom(elt) ut_oom_recover(elt) static bool oom = false; static void ut_oom_recover(strpool *elem) { oom = true; } // for zero terminated strings bool StrPoolAddStr(strpool **pp, const char *s) { strpool *elem; if (!(elem = (strpool*)malloc(sizeof(strpool)))) return false; if (!(elem->str = strdup(s))) { free(elem); return false; } oom = false; HASH_ADD_KEYPTR(hh, *pp, elem->str, strlen(elem->str), elem); if (oom) { free(elem->str); free(elem); return false; } return true; } // for not zero terminated strings bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen) { strpool *elem; if (!(elem = (strpool*)malloc(sizeof(strpool)))) return false; if (!(elem->str = malloc(slen + 1))) { free(elem); return false; } memcpy(elem->str, s, slen); elem->str[slen] = 0; oom = false; HASH_ADD_KEYPTR(hh, *pp, elem->str, strlen(elem->str), elem); if (oom) { free(elem->str); free(elem); return false; } return true; } bool StrPoolCheckStr(strpool *p, const char *s) { strpool *elem; HASH_FIND_STR(p, s, elem); return elem != NULL; } void StrPoolDestroy(strpool **p) { strpool *elem, *tmp; HASH_ITER(hh, *p, elem, tmp) { free(elem->str); HASH_DEL(*p, elem); free(elem); } *p = NULL; } bool strlist_add(struct str_list_head *head, const char *filename) { struct str_list *entry = malloc(sizeof(struct str_list)); if (!entry) return false; entry->str = strdup(filename); if (!entry->str) { free(entry); return false; } LIST_INSERT_HEAD(head, entry, next); return true; } static void strlist_entry_destroy(struct str_list *entry) { if (entry->str) free(entry->str); free(entry); } void strlist_destroy(struct str_list_head *head) { struct str_list *entry; while (entry = LIST_FIRST(head)) { LIST_REMOVE(entry, next); strlist_entry_destroy(entry); } }