rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <string.h>
|
nuclear@0
|
4 #include "treestore.h"
|
nuclear@0
|
5
|
nuclear@0
|
6 /* ---- ts_value implementation ---- */
|
nuclear@0
|
7
|
nuclear@0
|
8 int ts_init_value(struct ts_value *tsv)
|
nuclear@0
|
9 {
|
nuclear@0
|
10 memset(tsv, 0, sizeof *tsv);
|
nuclear@0
|
11 return 0;
|
nuclear@0
|
12 }
|
nuclear@0
|
13
|
nuclear@0
|
14 void ts_destroy_value(struct ts_value *tsv)
|
nuclear@0
|
15 {
|
nuclear@0
|
16 int i;
|
nuclear@0
|
17
|
nuclear@0
|
18 free(tsv->str);
|
nuclear@0
|
19 free(tsv->vec);
|
nuclear@0
|
20
|
nuclear@0
|
21 for(i=0; i<tsv->array_size; i++) {
|
nuclear@0
|
22 ts_destroy_value(tsv->array + i);
|
nuclear@0
|
23 }
|
nuclear@0
|
24 }
|
nuclear@0
|
25
|
nuclear@0
|
26
|
nuclear@0
|
27 struct ts_value *ts_alloc_value(void)
|
nuclear@0
|
28 {
|
nuclear@0
|
29 struct ts_value *v = malloc(sizeof *v);
|
nuclear@0
|
30 if(!v || ts_init_value(v) == -1) {
|
nuclear@0
|
31 free(v);
|
nuclear@0
|
32 return 0;
|
nuclear@0
|
33 }
|
nuclear@0
|
34 return v;
|
nuclear@0
|
35 }
|
nuclear@0
|
36
|
nuclear@0
|
37 void ts_free_value(struct ts_value *tsv)
|
nuclear@0
|
38 {
|
nuclear@0
|
39 ts_destroy_value(tsv);
|
nuclear@0
|
40 free(tsv);
|
nuclear@0
|
41 }
|
nuclear@0
|
42
|
nuclear@0
|
43
|
nuclear@0
|
44 int ts_copy_value(struct ts_value *dest, struct ts_value *src)
|
nuclear@0
|
45 {
|
nuclear@0
|
46 int i;
|
nuclear@0
|
47
|
nuclear@0
|
48 if(dest == src) return 0;
|
nuclear@0
|
49
|
nuclear@0
|
50 *dest = *src;
|
nuclear@0
|
51
|
nuclear@0
|
52 dest->str = 0;
|
nuclear@0
|
53 dest->vec = 0;
|
nuclear@0
|
54 dest->array = 0;
|
nuclear@0
|
55
|
nuclear@0
|
56 if(src->str) {
|
nuclear@0
|
57 if(!(dest->str = malloc(strlen(src->str) + 1))) {
|
nuclear@0
|
58 goto fail;
|
nuclear@0
|
59 }
|
nuclear@0
|
60 strcpy(dest->str, src->str);
|
nuclear@0
|
61 }
|
nuclear@0
|
62 if(src->vec && src->vec_size > 0) {
|
nuclear@0
|
63 if(!(dest->vec = malloc(src->vec_size * sizeof *src->vec))) {
|
nuclear@0
|
64 goto fail;
|
nuclear@0
|
65 }
|
nuclear@0
|
66 memcpy(dest->vec, src->vec, src->vec_size * sizeof *src->vec);
|
nuclear@0
|
67 }
|
nuclear@0
|
68 if(src->array && src->array_size > 0) {
|
nuclear@0
|
69 if(!(dest->array = calloc(src->array_size, sizeof *src->array))) {
|
nuclear@0
|
70 goto fail;
|
nuclear@0
|
71 }
|
nuclear@0
|
72 for(i=0; i<src->array_size; i++) {
|
nuclear@0
|
73 if(ts_copy_value(dest->array + i, src->array + i) == -1) {
|
nuclear@0
|
74 goto fail;
|
nuclear@0
|
75 }
|
nuclear@0
|
76 }
|
nuclear@0
|
77 }
|
nuclear@0
|
78 return 0;
|
nuclear@0
|
79
|
nuclear@0
|
80 fail:
|
nuclear@0
|
81 free(dest->str);
|
nuclear@0
|
82 free(dest->vec);
|
nuclear@0
|
83 if(dest->array) {
|
nuclear@0
|
84 for(i=0; i<dest->array_size; i++) {
|
nuclear@0
|
85 ts_destroy_value(dest->array + i);
|
nuclear@0
|
86 }
|
nuclear@0
|
87 free(dest->array);
|
nuclear@0
|
88 }
|
nuclear@0
|
89 return -1;
|
nuclear@0
|
90 }
|
nuclear@0
|
91
|
nuclear@0
|
92
|
nuclear@0
|
93 int ts_set_value(struct ts_value *tsv, const char *str)
|
nuclear@0
|
94 {
|
nuclear@0
|
95 if(tsv->str) {
|
nuclear@0
|
96 ts_destroy_value(tsv);
|
nuclear@0
|
97 if(ts_init_value(tsv) == -1) {
|
nuclear@0
|
98 return -1;
|
nuclear@0
|
99 }
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@0
|
102 if(!(tsv->str = malloc(strlen(str) + 1))) {
|
nuclear@0
|
103 return -1;
|
nuclear@0
|
104 }
|
nuclear@0
|
105 strcpy(tsv->str, str);
|
nuclear@0
|
106 return 0;
|
nuclear@0
|
107 }
|
nuclear@0
|
108
|
nuclear@0
|
109 int ts_set_valueiv(struct ts_value *tsv, int count, ...)
|
nuclear@0
|
110 {
|
nuclear@0
|
111 int res;
|
nuclear@0
|
112 va_list ap;
|
nuclear@0
|
113 va_start(ap, count);
|
nuclear@0
|
114 res = ts_set_valueiv_va(tsv, count, ap);
|
nuclear@0
|
115 va_end(ap);
|
nuclear@0
|
116 return res;
|
nuclear@0
|
117 }
|
nuclear@0
|
118
|
nuclear@0
|
119 #define MAKE_NUMSTR_FUNC(typestr, fmt) \
|
nuclear@0
|
120 static char *make_##typestr##str(int x) \
|
nuclear@0
|
121 { \
|
nuclear@0
|
122 static char scrap[128]; \
|
nuclear@0
|
123 char *str; \
|
nuclear@0
|
124 int sz = snprintf(scrap, sizeof scrap, fmt, x); \
|
nuclear@0
|
125 if(!(str = malloc(sz + 1))) return 0; \
|
nuclear@0
|
126 sprintf(str, fmt, x); \
|
nuclear@0
|
127 return str; \
|
nuclear@0
|
128 }
|
nuclear@0
|
129
|
nuclear@0
|
130 MAKE_NUMSTR_FUNC(int, "%d")
|
nuclear@0
|
131 MAKE_NUMSTR_FUNC(float, "%d")
|
nuclear@0
|
132
|
nuclear@0
|
133 #define ARGS_ARE_INT ((enum ts_value_type)42)
|
nuclear@0
|
134
|
nuclear@0
|
135 int ts_set_valueiv_va(struct ts_value *tsv, int count, va_list ap)
|
nuclear@0
|
136 {
|
nuclear@0
|
137 if(count < 1) return -1;
|
nuclear@0
|
138 if(count == 1) {
|
nuclear@0
|
139 int num = va_arg(ap, int);
|
nuclear@0
|
140 if(!(tsv->str = make_intstr(tsv->inum))) {
|
nuclear@0
|
141 return -1;
|
nuclear@0
|
142 }
|
nuclear@0
|
143
|
nuclear@0
|
144 tsv->type = TS_NUMBER;
|
nuclear@0
|
145 tsv->inum = num;
|
nuclear@0
|
146 tsv->fnum = (float)num;
|
nuclear@0
|
147 return 0;
|
nuclear@0
|
148 }
|
nuclear@0
|
149
|
nuclear@0
|
150 /* otherwise it's an array, let ts_set_valuefv_va handle it */
|
nuclear@0
|
151 /* XXX: va_arg will need to be called with int instead of float. set a special
|
nuclear@0
|
152 * value to the type field before calling this, to signify that.
|
nuclear@0
|
153 */
|
nuclear@0
|
154 tsv->type = ARGS_ARE_INT;
|
nuclear@0
|
155 return ts_set_valuefv_va(tsv, count, ap);
|
nuclear@0
|
156 }
|
nuclear@0
|
157
|
nuclear@0
|
158 int ts_set_valuei(struct ts_value *tsv, int inum)
|
nuclear@0
|
159 {
|
nuclear@0
|
160 return ts_set_valueiv(tsv, 1, inum);
|
nuclear@0
|
161 }
|
nuclear@0
|
162
|
nuclear@0
|
163
|
nuclear@0
|
164 int ts_set_valuefv(struct ts_value *tsv, int count, ...)
|
nuclear@0
|
165 {
|
nuclear@0
|
166 int res;
|
nuclear@0
|
167 va_list ap;
|
nuclear@0
|
168 va_start(ap, count);
|
nuclear@0
|
169 res = ts_set_valuefv_va(tsv, count, ap);
|
nuclear@0
|
170 va_end(ap);
|
nuclear@0
|
171 return res;
|
nuclear@0
|
172 }
|
nuclear@0
|
173
|
nuclear@0
|
174 int ts_set_valuefv_va(struct ts_value *tsv, int count, va_list ap)
|
nuclear@0
|
175 {
|
nuclear@0
|
176 int i;
|
nuclear@0
|
177
|
nuclear@0
|
178 if(count < 1) return -1;
|
nuclear@0
|
179 if(count == 1) {
|
nuclear@0
|
180 int num = va_arg(ap, int);
|
nuclear@0
|
181 if(!(tsv->str = make_floatstr(tsv->inum))) {
|
nuclear@0
|
182 return -1;
|
nuclear@0
|
183 }
|
nuclear@0
|
184
|
nuclear@0
|
185 tsv->type = TS_NUMBER;
|
nuclear@0
|
186 tsv->inum = num;
|
nuclear@0
|
187 tsv->fnum = (float)num;
|
nuclear@0
|
188 return 0;
|
nuclear@0
|
189 }
|
nuclear@0
|
190
|
nuclear@0
|
191 /* otherwise it's an array, we need to create the ts_value array, and
|
nuclear@0
|
192 * the simplified vector
|
nuclear@0
|
193 */
|
nuclear@0
|
194 if(!(tsv->vec = malloc(count * sizeof *tsv->vec))) {
|
nuclear@0
|
195 return -1;
|
nuclear@0
|
196 }
|
nuclear@0
|
197 tsv->vec_size = count;
|
nuclear@0
|
198
|
nuclear@0
|
199 for(i=0; i<count; i++) {
|
nuclear@0
|
200 if(tsv->type == ARGS_ARE_INT) { /* only when called by ts_set_valueiv_va */
|
nuclear@0
|
201 tsv->vec[i] = (float)va_arg(ap, int);
|
nuclear@0
|
202 } else {
|
nuclear@0
|
203 tsv->vec[i] = va_arg(ap, double);
|
nuclear@0
|
204 }
|
nuclear@0
|
205 }
|
nuclear@0
|
206
|
nuclear@0
|
207 if(!(tsv->array = malloc(count * sizeof *tsv->array))) {
|
nuclear@0
|
208 free(tsv->vec);
|
nuclear@0
|
209 }
|
nuclear@0
|
210 tsv->array_size = count;
|
nuclear@0
|
211
|
nuclear@0
|
212 for(i=0; i<count; i++) {
|
nuclear@0
|
213 ts_init_value(tsv->array + i);
|
nuclear@0
|
214 if(tsv->type == ARGS_ARE_INT) { /* only when called by ts_set_valueiv_va */
|
nuclear@0
|
215 ts_set_valuei(tsv->array + i, (int)tsv->vec[i]);
|
nuclear@0
|
216 } else {
|
nuclear@0
|
217 ts_set_valuef(tsv->array + i, tsv->vec[i]);
|
nuclear@0
|
218 }
|
nuclear@0
|
219 }
|
nuclear@0
|
220
|
nuclear@0
|
221 tsv->type = TS_VECTOR;
|
nuclear@0
|
222 return 0;
|
nuclear@0
|
223 }
|
nuclear@0
|
224
|
nuclear@0
|
225 int ts_set_valuef(struct ts_value *tsv, int fnum)
|
nuclear@0
|
226 {
|
nuclear@0
|
227 return ts_set_valuefv(tsv, 1, fnum);
|
nuclear@0
|
228 }
|
nuclear@0
|
229
|
nuclear@0
|
230
|
nuclear@0
|
231 int ts_set_valuev(struct ts_value *tsv, int count, ...)
|
nuclear@0
|
232 {
|
nuclear@0
|
233 int res;
|
nuclear@0
|
234 va_list ap;
|
nuclear@0
|
235 va_start(ap, count);
|
nuclear@0
|
236 res = ts_set_valuev_va(tsv, count, ap);
|
nuclear@0
|
237 va_end(ap);
|
nuclear@0
|
238 return res;
|
nuclear@0
|
239 }
|
nuclear@0
|
240
|
nuclear@0
|
241 int ts_set_valuev_va(struct ts_value *tsv, int count, va_list ap)
|
nuclear@0
|
242 {
|
nuclear@1
|
243 int i;
|
nuclear@1
|
244
|
nuclear@0
|
245 if(count <= 1) return -1;
|
nuclear@1
|
246
|
nuclear@1
|
247 if((tsv->array = malloc(count * sizeof *tsv->array))) {
|
nuclear@1
|
248 return -1;
|
nuclear@1
|
249 }
|
nuclear@1
|
250 tsv->array_size = count;
|
nuclear@1
|
251
|
nuclear@1
|
252 for(i=0; i<count; i++) {
|
nuclear@1
|
253 struct ts_value *src = va_arg(ap, struct ts_value*);
|
nuclear@1
|
254 ts_copy_value(tsv->array + i, src);
|
nuclear@1
|
255 }
|
nuclear@1
|
256 return 0;
|
nuclear@0
|
257 }
|
nuclear@1
|
258
|
nuclear@1
|
259
|
nuclear@1
|
260 /* ---- ts_attr implementation ---- */
|
nuclear@1
|
261
|
nuclear@1
|
262 int ts_init_attr(struct ts_attr *attr)
|
nuclear@1
|
263 {
|
nuclear@1
|
264 memset(attr, 0, sizeof *attr);
|
nuclear@1
|
265 return ts_init_value(&attr->val);
|
nuclear@1
|
266 }
|
nuclear@1
|
267
|
nuclear@1
|
268 void ts_destroy_attr(struct ts_attr *attr)
|
nuclear@1
|
269 {
|
nuclear@1
|
270 free(attr->name);
|
nuclear@1
|
271 ts_destroy_value(&attr->val);
|
nuclear@1
|
272 }
|
nuclear@1
|
273
|
nuclear@1
|
274 struct ts_attr *ts_alloc_attr(void)
|
nuclear@1
|
275 {
|
nuclear@1
|
276 struct ts_attr *attr = malloc(sizeof *attr);
|
nuclear@1
|
277 if(!attr || ts_init_attr(attr) == -1) {
|
nuclear@1
|
278 free(attr);
|
nuclear@1
|
279 return 0;
|
nuclear@1
|
280 }
|
nuclear@1
|
281 return attr;
|
nuclear@1
|
282 }
|
nuclear@1
|
283
|
nuclear@1
|
284 void ts_free_attr(struct ts_attr *attr)
|
nuclear@1
|
285 {
|
nuclear@1
|
286 ts_destroy_attr(attr);
|
nuclear@1
|
287 free(attr);
|
nuclear@1
|
288 }
|
nuclear@1
|
289
|
nuclear@1
|
290 int ts_copy_attr(struct ts_attr *dest, struct ts_attr *src)
|
nuclear@1
|
291 {
|
nuclear@1
|
292 if(dest == src) return 0;
|
nuclear@1
|
293
|
nuclear@1
|
294 if(ts_set_attr_name(dest, src->name) == -1) {
|
nuclear@1
|
295 return -1;
|
nuclear@1
|
296 }
|
nuclear@1
|
297
|
nuclear@1
|
298 if(ts_copy_value(&dest->val, &src->val) == -1) {
|
nuclear@1
|
299 ts_destroy_attr(dest);
|
nuclear@1
|
300 return -1;
|
nuclear@1
|
301 }
|
nuclear@1
|
302 return 0;
|
nuclear@1
|
303 }
|
nuclear@1
|
304
|
nuclear@1
|
305 int ts_set_attr_name(struct ts_attr *attr, const char *name)
|
nuclear@1
|
306 {
|
nuclear@1
|
307 char *n = malloc(strlen(name) + 1);
|
nuclear@1
|
308 if(!n) return -1;
|
nuclear@1
|
309 strcpy(n, name);
|
nuclear@1
|
310
|
nuclear@1
|
311 free(attr->name);
|
nuclear@1
|
312 attr->name = n;
|
nuclear@1
|
313 return 0;
|
nuclear@1
|
314 }
|
nuclear@1
|
315
|
nuclear@1
|
316
|
nuclear@1
|
317 /* ---- ts_node implementation ---- */
|
nuclear@1
|
318
|
nuclear@1
|
319 int ts_init_node(struct ts_node *node)
|
nuclear@1
|
320 {
|
nuclear@1
|
321 memset(node, 0, sizeof *node);
|
nuclear@1
|
322 return 0;
|
nuclear@1
|
323 }
|
nuclear@1
|
324
|
nuclear@1
|
325 void ts_destroy_node(struct ts_node *node)
|
nuclear@1
|
326 {
|
nuclear@1
|
327 free(node->name);
|
nuclear@1
|
328
|
nuclear@1
|
329 while(node->attr_list) {
|
nuclear@1
|
330 struct ts_attr *attr = node->attr_list;
|
nuclear@1
|
331 node->attr_list = node->attr_list->next;
|
nuclear@1
|
332 ts_free_attr(attr);
|
nuclear@1
|
333 }
|
nuclear@1
|
334 }
|
nuclear@1
|
335
|
nuclear@1
|
336 struct ts_node *ts_alloc_node(void)
|
nuclear@1
|
337 {
|
nuclear@1
|
338 struct ts_node *node = malloc(sizeof *node);
|
nuclear@1
|
339 if(!node || ts_init_node(node) == -1) {
|
nuclear@1
|
340 free(node);
|
nuclear@1
|
341 return 0;
|
nuclear@1
|
342 }
|
nuclear@1
|
343 return node;
|
nuclear@1
|
344 }
|
nuclear@1
|
345
|
nuclear@1
|
346 void ts_free_node(struct ts_node *node)
|
nuclear@1
|
347 {
|
nuclear@1
|
348 ts_destroy_node(node);
|
nuclear@1
|
349 free(node);
|
nuclear@1
|
350 }
|
nuclear@1
|
351
|
nuclear@1
|
352 void ts_free_tree(struct ts_node *tree)
|
nuclear@1
|
353 {
|
nuclear@1
|
354 while(tree->child_list) {
|
nuclear@1
|
355 struct ts_tree *child = tree->child_list;
|
nuclear@1
|
356 tree->child_list = tree->child_list->next;
|
nuclear@1
|
357 ts_free_tree(child);
|
nuclear@1
|
358 }
|
nuclear@1
|
359
|
nuclear@1
|
360 ts_free_node(tree);
|
nuclear@1
|
361 }
|