Tue, 24 Apr 2007 19:00:47 +0200
Oops, fixed comparison function order.
73 | 1 | /* |
2 | * libtu/stringstore.c | |
3 | * | |
107
da2a985da6ee
Clean-up and pending updates
Tuomo Valkonen <tuomov@iki.fi>
parents:
106
diff
changeset
|
4 | * Copyright (c) Tuomo Valkonen 2004-2007. |
73 | 5 | * |
6 | * You may distribute and modify this library under the terms of either | |
7 | * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. | |
8 | */ | |
9 | ||
10 | #include <stdlib.h> | |
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
11 | #include <string.h> |
73 | 12 | |
13 | #include "misc.h" | |
14 | #include "output.h" | |
15 | #include "rb.h" | |
16 | #include "stringstore.h" | |
17 | ||
18 | ||
19 | static Rb_node stringstore=NULL; | |
20 | ||
74 | 21 | |
22 | const char *stringstore_get(StringId id) | |
23 | { | |
106
f1bb821008fc
stringstore_get should work on STRINGID_NONE too.
Tuomo Valkonen <tuomov@iki.fi>
parents:
105
diff
changeset
|
24 | return (id==STRINGID_NONE |
f1bb821008fc
stringstore_get should work on STRINGID_NONE too.
Tuomo Valkonen <tuomov@iki.fi>
parents:
105
diff
changeset
|
25 | ? NULL |
f1bb821008fc
stringstore_get should work on STRINGID_NONE too.
Tuomo Valkonen <tuomov@iki.fi>
parents:
105
diff
changeset
|
26 | : (const char*)(((Rb_node)id)->k.key)); |
74 | 27 | } |
28 | ||
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
29 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
30 | typedef struct{ |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
31 | const char *key; |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
32 | uint len; |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
33 | } D; |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
34 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
35 | static int cmp(const void *d_, const char *nodekey) |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
36 | { |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
37 | D *d=(D*)d_; |
73 | 38 | |
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
39 | int res=strncmp(d->key, nodekey, d->len); |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
40 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
41 | return (res!=0 |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
42 | ? res |
110
13134ea30227
Oops, fixed comparison function order.
Tuomo Valkonen <tuomov@iki.fi>
parents:
108
diff
changeset
|
43 | : (nodekey[d->len]=='\0' ? 0 : -1)); |
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
44 | } |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
45 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
46 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
47 | StringId stringstore_find_n(const char *str, uint l) |
73 | 48 | { |
49 | Rb_node node; | |
50 | int found=0; | |
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
51 | D d; |
73 | 52 | |
53 | if(stringstore==NULL) | |
54 | return STRINGID_NONE; | |
55 | ||
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
56 | d.key=str; |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
57 | d.len=l; |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
58 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
59 | node=rb_find_gkey_n(stringstore, &d, (Rb_compfn*)cmp, &found); |
73 | 60 | |
61 | if(!found) | |
62 | return STRINGID_NONE; | |
63 | ||
64 | return (StringId)node; | |
65 | } | |
66 | ||
67 | ||
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
68 | StringId stringstore_find(const char *str) |
73 | 69 | { |
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
70 | return stringstore_find_n(str, strlen(str)); |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
71 | } |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
72 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
73 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
74 | StringId stringstore_alloc_n(const char *str, uint l) |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
75 | { |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
76 | Rb_node node=(Rb_node)stringstore_find_n(str, l); |
73 | 77 | char *s; |
78 | ||
79 | if(node!=NULL){ | |
80 | node->v.ival++; | |
81 | return node; | |
82 | } | |
83 | ||
84 | if(stringstore==NULL){ | |
85 | stringstore=make_rb(); | |
86 | if(stringstore==NULL) | |
87 | return STRINGID_NONE; | |
88 | } | |
89 | ||
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
90 | s=scopyn(str, l); |
73 | 91 | |
92 | if(s==NULL) | |
93 | return STRINGID_NONE; | |
94 | ||
95 | node=rb_insert(stringstore, s, NULL); | |
96 | ||
97 | if(node==NULL) | |
98 | return STRINGID_NONE; | |
99 | ||
100 | node->v.ival=1; | |
101 | ||
102 | return (StringId)node; | |
103 | } | |
104 | ||
105 | ||
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
106 | StringId stringstore_alloc(const char *str) |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
107 | { |
108
2b4dd5f948bc
Better handling of STRINGID_NONE
Tuomo Valkonen <tuomov@iki.fi>
parents:
107
diff
changeset
|
108 | if(str==NULL) |
2b4dd5f948bc
Better handling of STRINGID_NONE
Tuomo Valkonen <tuomov@iki.fi>
parents:
107
diff
changeset
|
109 | return STRINGID_NONE; |
2b4dd5f948bc
Better handling of STRINGID_NONE
Tuomo Valkonen <tuomov@iki.fi>
parents:
107
diff
changeset
|
110 | |
105
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
111 | return stringstore_alloc_n(str, strlen(str)); |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
112 | } |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
113 | |
de53cada1423
Added stringstore_find/alloc_n
Tuomo Valkonen <tuomov@iki.fi>
parents:
104
diff
changeset
|
114 | |
73 | 115 | void stringstore_free(StringId id) |
116 | { | |
117 | Rb_node node=(Rb_node)id; | |
118 | ||
108
2b4dd5f948bc
Better handling of STRINGID_NONE
Tuomo Valkonen <tuomov@iki.fi>
parents:
107
diff
changeset
|
119 | if(node==NULL) |
73 | 120 | return; |
121 | ||
122 | if(node->v.ival<=0){ | |
123 | warn("Stringstore reference count corrupted."); | |
124 | return; | |
125 | } | |
126 | ||
127 | node->v.ival--; | |
128 | ||
129 | if(node->v.ival==0){ | |
130 | char *s=(char*)(node->k.key); | |
131 | rb_delete_node(node); | |
132 | free(s); | |
133 | } | |
134 | } | |
135 | ||
104 | 136 | |
137 | void stringstore_ref(StringId id) | |
138 | { | |
139 | Rb_node node=(Rb_node)id; | |
140 | ||
141 | if(node!=NULL) | |
142 | node->v.ival++; | |
143 | } | |
144 |