Added an init phase to most modules.
[svn-fe.git] / string_pool.c
blob49908ca9dbe49bc6984826e3c6c04755b6a80f45
1 #include <string.h>
2 #include <stdint.h>
4 #include "trp.h"
5 #include "obj_pool.h"
6 #include "string_pool.h"
8 typedef struct node_s node_t;
9 static struct trp_root tree = { ~0 };
11 struct node_s {
12 uint32_t offset;
13 struct trp_node children;
16 /* Create two memory pools: one for node_t, and another for strings */
17 obj_pool_gen(node, node_t, 4096);
18 obj_pool_gen(string, char, 4096);
20 static char *node_value(node_t *node)
22 return node ? string_pointer(node->offset) : NULL;
25 static int node_value_cmp(node_t *a, node_t *b)
27 return strcmp(node_value(a), node_value(b));
30 static int node_indentity_cmp(node_t *a, node_t *b)
32 int r = node_value_cmp(a, b);
33 return r ? r : (((uintptr_t) a) > ((uintptr_t) b))
34 - (((uintptr_t) a) < ((uintptr_t) b));
37 /* Build a Treap from the node_s structure (a trp_node w/ offset) */
38 trp_gen(static, tree_, node_t, children, node, node_indentity_cmp);
40 char *pool_fetch(uint32_t entry)
42 return node_value(node_pointer(entry));
45 uint32_t pool_intern(char *key)
47 /* Canonicalize key */
48 node_t *match = NULL;
49 uint32_t key_len;
50 if (key == NULL)
51 return ~0;
52 key_len = strlen(key) + 1;
53 node_t *node = node_pointer(node_alloc(1));
54 node->offset = string_alloc(key_len);
55 strcpy(node_value(node), key);
56 match = tree_psearch(&tree, node);
57 if (!match || node_value_cmp(node, match)) {
58 tree_insert(&tree, node);
59 } else {
60 node_free(1);
61 string_free(key_len);
62 node = match;
64 return node_offset(node);
67 uint32_t pool_tok_r(char *str, const char *delim, char **saveptr)
69 char *token = strtok_r(str, delim, saveptr);
70 return token ? pool_intern(token) : ~0;
73 void pool_print_seq(uint32_t len, uint32_t *seq, char delim, FILE *stream)
75 uint32_t i;
76 for (i = 0; i < len && ~seq[i]; i++) {
77 fputs(pool_fetch(seq[i]), stream);
78 if (i < len - 1 && ~seq[i + 1])
79 fputc(delim, stream);
83 uint32_t pool_tok_seq(uint32_t max, uint32_t *seq, char *delim, char *str)
85 char *context = NULL;
86 uint32_t length = 0, token = str ? pool_tok_r(str, delim, &context) : ~0;
87 while (length < max) {
88 seq[length++] = token;
89 if (token == ~0)
90 break;
91 token = pool_tok_r(NULL, delim, &context);
93 seq[length ? length - 1 : 0] = ~0;
94 return length;
97 void pool_init(void)
99 uint32_t node;
100 node_init();
101 string_init();
102 for (node = 0; node < node_pool.size; node++) {
103 tree_insert(&tree, node_pointer(node));
107 void pool_reset(void)
109 node_reset();
110 string_reset();