Rework pool_tok_seq and pool_print_seq.
[svn-fe.git] / string_pool.c
blobac45abab33b53d0f6f550d24927daaa1f109f20a
1 #include <string.h>
3 #include "trp.h"
4 #include "obj_pool.h"
5 #include "string_pool.h"
7 typedef struct node_s node_t;
8 typedef trp(node_t) tree_t;
9 static tree_t tree = { ~0 };
11 struct node_s {
12 uint32_t offset;
13 trp_node(node_t) 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_, tree_t, node_t, children, node,
39 node_indentity_cmp);
41 char *pool_fetch(uint32_t entry)
43 return node_value(node_pointer(entry));
46 uint32_t pool_intern(char *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_reset(void)
99 node_reset();
100 string_reset();