2021-03-04 11:30:38 +00:00
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include "strpool.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#undef uthash_nonfatal_oom
|
|
|
|
#define uthash_nonfatal_oom(elt) ut_oom_recover(elt)
|
|
|
|
|
2022-07-26 16:15:28 +00:00
|
|
|
static bool oom = false;
|
2021-03-04 11:30:38 +00:00
|
|
|
static void ut_oom_recover(strpool *elem)
|
|
|
|
{
|
2022-07-26 16:15:28 +00:00
|
|
|
oom = true;
|
2021-03-04 11:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// for zero terminated strings
|
2022-07-26 16:15:28 +00:00
|
|
|
bool StrPoolAddStr(strpool **pp, const char *s)
|
2021-03-04 11:30:38 +00:00
|
|
|
{
|
2022-07-26 16:15:28 +00:00
|
|
|
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;
|
2021-03-04 11:30:38 +00:00
|
|
|
}
|
|
|
|
// for not zero terminated strings
|
2022-07-26 16:15:28 +00:00
|
|
|
bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen)
|
2021-03-04 11:30:38 +00:00
|
|
|
{
|
2022-07-26 16:15:28 +00:00
|
|
|
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;
|
2021-03-04 11:30:38 +00:00
|
|
|
}
|
|
|
|
|
2022-07-26 16:15:28 +00:00
|
|
|
bool StrPoolCheckStr(strpool *p, const char *s)
|
2021-03-04 11:30:38 +00:00
|
|
|
{
|
2022-07-26 16:15:28 +00:00
|
|
|
strpool *elem;
|
|
|
|
HASH_FIND_STR(p, s, elem);
|
|
|
|
return elem != NULL;
|
2021-03-04 11:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void StrPoolDestroy(strpool **p)
|
|
|
|
{
|
2022-07-26 16:15:28 +00:00
|
|
|
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);
|
|
|
|
}
|
2021-03-04 11:30:38 +00:00
|
|
|
}
|