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: 
106diff
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: 
104diff
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: 
105diff
changeset | 24 | return (id==STRINGID_NONE | 
| 
f1bb821008fc
stringstore_get should work on STRINGID_NONE too.
 Tuomo Valkonen <tuomov@iki.fi> parents: 
105diff
changeset | 25 | ? NULL | 
| 
f1bb821008fc
stringstore_get should work on STRINGID_NONE too.
 Tuomo Valkonen <tuomov@iki.fi> parents: 
105diff
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: 
104diff
changeset | 29 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 30 | typedef struct{ | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 31 | const char *key; | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 32 | uint len; | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 33 | } D; | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 34 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 35 | static int cmp(const void *d_, const char *nodekey) | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 36 | { | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 37 | D *d=(D*)d_; | 
| 73 | 38 | |
| 105 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 39 | int res=strncmp(d->key, nodekey, d->len); | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 40 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 41 | return (res!=0 | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 42 | ? res | 
| 110 
13134ea30227
Oops, fixed comparison function order.
 Tuomo Valkonen <tuomov@iki.fi> parents: 
108diff
changeset | 43 | : (nodekey[d->len]=='\0' ? 0 : -1)); | 
| 105 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 44 | } | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 45 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 46 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
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: 
104diff
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: 
104diff
changeset | 56 | d.key=str; | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 57 | d.len=l; | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 58 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
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: 
104diff
changeset | 68 | StringId stringstore_find(const char *str) | 
| 73 | 69 | { | 
| 105 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 70 | return stringstore_find_n(str, strlen(str)); | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 71 | } | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 72 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 73 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 74 | StringId stringstore_alloc_n(const char *str, uint l) | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 75 | { | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
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: 
104diff
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: 
104diff
changeset | 106 | StringId stringstore_alloc(const char *str) | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 107 | { | 
| 108 
2b4dd5f948bc
Better handling of STRINGID_NONE
 Tuomo Valkonen <tuomov@iki.fi> parents: 
107diff
changeset | 108 | if(str==NULL) | 
| 
2b4dd5f948bc
Better handling of STRINGID_NONE
 Tuomo Valkonen <tuomov@iki.fi> parents: 
107diff
changeset | 109 | return STRINGID_NONE; | 
| 
2b4dd5f948bc
Better handling of STRINGID_NONE
 Tuomo Valkonen <tuomov@iki.fi> parents: 
107diff
changeset | 110 | |
| 105 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 111 | return stringstore_alloc_n(str, strlen(str)); | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 112 | } | 
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
changeset | 113 | |
| 
de53cada1423
Added stringstore_find/alloc_n
 Tuomo Valkonen <tuomov@iki.fi> parents: 
104diff
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: 
107diff
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 |