libtreestore
diff src/treestore.c @ 4:bb873449cf59
fixed ts_set_value and added convenience value-get functions
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 13 Nov 2016 19:46:01 +0200 |
parents | 48d75df3ef04 |
children | f3ade599cfbb |
line diff
1.1 --- a/src/treestore.c Thu Nov 10 16:19:44 2016 +0200 1.2 +++ b/src/treestore.c Sun Nov 13 19:46:01 2016 +0200 1.3 @@ -93,9 +93,15 @@ 1.4 return -1; 1.5 } 1.6 1.7 +struct val_list_node { 1.8 + struct ts_value val; 1.9 + struct val_list_node *next; 1.10 +}; 1.11 1.12 int ts_set_value(struct ts_value *tsv, const char *str) 1.13 { 1.14 + char *endp; 1.15 + 1.16 if(tsv->str) { 1.17 ts_destroy_value(tsv); 1.18 if(ts_init_value(tsv) == -1) { 1.19 @@ -103,10 +109,58 @@ 1.20 } 1.21 } 1.22 1.23 + tsv->type = TS_STRING; 1.24 if(!(tsv->str = malloc(strlen(str) + 1))) { 1.25 return -1; 1.26 } 1.27 strcpy(tsv->str, str); 1.28 + 1.29 + /* try to parse the string and see if it fits any of the value types */ 1.30 + if(*str == '[' || *str == '{') { 1.31 + /* try to parse as a vector */ 1.32 + struct val_list_node *list = 0, *tail = 0, *node; 1.33 + int nelem = 0; 1.34 + char endsym = *str++ + 2; /* ']' is '[' + 2 and '}' is '{' + 2 */ 1.35 + 1.36 + while(*str && *str != endsym) { 1.37 + float val = strtod(str, &endp); 1.38 + if(endp == str || !(node = malloc(sizeof *node))) { 1.39 + break; 1.40 + } 1.41 + ts_init_value(&node->val); 1.42 + ts_set_valuef(&node->val, val); 1.43 + node->next = 0; 1.44 + 1.45 + if(list) { 1.46 + tail->next = node; 1.47 + tail = node; 1.48 + } else { 1.49 + list = tail = node; 1.50 + } 1.51 + ++nelem; 1.52 + str = endp; 1.53 + } 1.54 + 1.55 + if(nelem && (tsv->array = malloc(nelem * sizeof *tsv->array)) && 1.56 + (tsv->vec = malloc(nelem * sizeof *tsv->vec))) { 1.57 + int idx = 0; 1.58 + while(list) { 1.59 + node = list; 1.60 + list = list->next; 1.61 + 1.62 + tsv->array[idx] = node->val; 1.63 + tsv->vec[idx] = node->val.fnum; 1.64 + ++idx; 1.65 + free(node); 1.66 + } 1.67 + tsv->type = TS_VECTOR; 1.68 + } 1.69 + 1.70 + } else if((tsv->fnum = strtod(str, &endp)), endp != str) { 1.71 + /* it's a number I guess... */ 1.72 + tsv->type = TS_NUMBER; 1.73 + } 1.74 + 1.75 return 0; 1.76 } 1.77 1.78 @@ -226,7 +280,7 @@ 1.79 return 0; 1.80 } 1.81 1.82 -int ts_set_valuef(struct ts_value *tsv, int fnum) 1.83 +int ts_set_valuef(struct ts_value *tsv, float fnum) 1.84 { 1.85 return ts_set_valuefv(tsv, 1, fnum); 1.86 } 1.87 @@ -387,6 +441,51 @@ 1.88 return 0; 1.89 } 1.90 1.91 +const char *ts_get_attr_str(struct ts_node *node, const char *aname, const char *def_val) 1.92 +{ 1.93 + struct ts_attr *attr = ts_get_attr(node, aname); 1.94 + if(!attr || !attr->val.str) { 1.95 + return def_val; 1.96 + } 1.97 + return attr->val.str; 1.98 +} 1.99 + 1.100 +float ts_get_attr_num(struct ts_node *node, const char *aname, float def_val) 1.101 +{ 1.102 + struct ts_attr *attr = ts_get_attr(node, aname); 1.103 + if(!attr || attr->val.type != TS_NUMBER) { 1.104 + return def_val; 1.105 + } 1.106 + return attr->val.fnum; 1.107 +} 1.108 + 1.109 +int ts_get_attr_int(struct ts_node *node, const char *aname, int def_val) 1.110 +{ 1.111 + struct ts_attr *attr = ts_get_attr(node, aname); 1.112 + if(!attr || attr->val.type != TS_NUMBER) { 1.113 + return def_val; 1.114 + } 1.115 + return attr->val.inum; 1.116 +} 1.117 + 1.118 +float *ts_get_attr_vec(struct ts_node *node, const char *aname, float *def_val) 1.119 +{ 1.120 + struct ts_attr *attr = ts_get_attr(node, aname); 1.121 + if(!attr || !attr->val.vec) { 1.122 + return def_val; 1.123 + } 1.124 + return attr->val.vec; 1.125 +} 1.126 + 1.127 +struct ts_value *ts_get_attr_array(struct ts_node *node, const char *aname, struct ts_value *def_val) 1.128 +{ 1.129 + struct ts_attr *attr = ts_get_attr(node, aname); 1.130 + if(!attr || !attr->val.array) { 1.131 + return def_val; 1.132 + } 1.133 + return attr->val.array; 1.134 +} 1.135 + 1.136 void ts_add_child(struct ts_node *node, struct ts_node *child) 1.137 { 1.138 if(child->parent) {