libtreestore

annotate src/treestore.c @ 1:a31eae25c0e6

partial implementation of ts_node and ts_attr
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 12 Apr 2014 13:46:00 +0300
parents 740fec9866b1
children e1a825be0eee
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 }