Thu, 06 Feb 2014 14:16:13 +0000
locale.h name seems to conflict with system locale.h name on some systems
| 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 |