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) {