#include #include #include #include #include "finalize.h" #include "ustr.h" struct Node { struct Node *next; struct UStr ustr; }; static struct Node *node; static void cleanup(void) { for (struct Node *n = node, *next; n; n = next) { next = n->next; free(n); } } const struct UStr * UStrAdd_(const char *s, bool *added) { static bool first = true; if (first) { first = false; finalizeRegister(cleanup); } size_t len = strlen(s); if (added) { *added = true; } for (struct Node *n = node; n; n = n->next) { if (len == n->ustr.len && !strcmp(s, n->ustr.cstr)) { if (added) { *added = false; } return &n->ustr; } } struct Node *n = malloc(len + 1 + sizeof(size_t) + sizeof(struct Node *)); if (!n) { fprintf(stderr, "makeUStr: out of memory\n"); abort(); } n->next = node; n->ustr.len = len; strcpy(n->ustr.cstr, s); node = n; return &node->ustr; } const struct UStr * UStrAdd(const char *s) { return UStrAdd_(s, 0); } void UStrPrintPool(void) { for (const struct Node *n = node; n; n = n->next) { printf("%s\n", n->ustr.cstr); } }