libtreestore

annotate src/treestore.c @ 0:740fec9866b1

treestore initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 11 Apr 2014 08:56:46 +0300
parents
children a31eae25c0e6
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@0 243 if(count <= 1) return -1;
nuclear@0 244 return -1; /* TODO */
nuclear@0 245 }