libtreestore
changeset 3:48d75df3ef04
picking this up again, converted to cmake, and started a text format reader/writer
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 10 Nov 2016 16:19:44 +0200 |
parents | e1a825be0eee |
children | bb873449cf59 |
files | .hgignore CMakeLists.txt Makefile include/treestore.h src/text.c src/treestore.c src/treestore.h src/treestorepp.h |
diffstat | 8 files changed, 496 insertions(+), 236 deletions(-) [+] |
line diff
1.1 --- a/.hgignore Sat Apr 12 13:50:01 2014 +0300 1.2 +++ b/.hgignore Thu Nov 10 16:19:44 2016 +0200 1.3 @@ -2,4 +2,8 @@ 1.4 \.d$ 1.5 \.swp$ 1.6 \.so\. 1.7 +\.so$ 1.8 \.a$ 1.9 +CMakeFiles/ 1.10 +\.cmake$ 1.11 +\.txt$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/CMakeLists.txt Thu Nov 10 16:19:44 2016 +0200 2.3 @@ -0,0 +1,36 @@ 2.4 +cmake_minimum_required(VERSION 3.0) 2.5 +project(libtreestore) 2.6 + 2.7 +include(GNUInstallDirs) 2.8 + 2.9 +set(SO_MAJOR 0) 2.10 +set(SO_MINOR 1) 2.11 + 2.12 +file(GLOB src "src/*.c") 2.13 +file(GLOB hdr "src/*.h") 2.14 +file(GLOB pubhdr "include/*.h") 2.15 + 2.16 +add_library(treestore SHARED ${src} ${hdr} ${pubhdr}) 2.17 +add_library(treestore-static STATIC ${src} ${hdr} ${pubhdr}) 2.18 + 2.19 +set_target_properties(treestore PROPERTIES VERSION ${SO_MAJOR}.${SO_MINOR}) 2.20 +set_target_properties(treestore PROPERTIES SOVERSION ${SO_MAJOR}) 2.21 + 2.22 +if(NOT WIN32) 2.23 + set_target_properties(treestore-static PROPERTIES OUTPUT_NAME treestore) 2.24 +endif() 2.25 + 2.26 +target_include_directories(treestore PUBLIC include) 2.27 +target_include_directories(treestore-static PUBLIC include) 2.28 + 2.29 +install(TARGETS treestore 2.30 + RUNTIME DESTINATION bin 2.31 + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 2.32 + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) 2.33 + 2.34 +install(TARGETS treestore-static 2.35 + RUNTIME DESTINATION bin 2.36 + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 2.37 + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) 2.38 + 2.39 +install(FILES ${pubhdr} DESTINATION include)
3.1 --- a/Makefile Sat Apr 12 13:50:01 2014 +0300 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,89 +0,0 @@ 3.4 -PREFIX = /usr/local 3.5 - 3.6 -csrc = $(wildcard src/*.c) 3.7 -ccsrc = $(wildcard src/*.cc) 3.8 -cobj = $(csrc:.c=.o) 3.9 -ccobj = $(ccsrc:.cc=.o) 3.10 -obj = $(cobj) $(ccobj) 3.11 -dep = $(obj:.o=.d) 3.12 - 3.13 -cname = treestore 3.14 -ccname = treestorepp 3.15 - 3.16 -capi_major = 0 3.17 -capi_minor = 1 3.18 -ccapi_major = 0 3.19 -ccapi_minor = 1 3.20 - 3.21 -clib_a = lib$(cname).a 3.22 -cclib_a = lib$(ccname).a 3.23 - 3.24 -ifeq ($(shell uname -s), Darwin) 3.25 - clib_so = lib$(cname).dylib 3.26 - cclib_so = lib$(ccname).dylib 3.27 - cshared = -dynamiclib 3.28 - ccshared = -dynamiclib 3.29 -else 3.30 - clib_so = lib$(cname).so.$(capi_major).$(capi_minor) 3.31 - csoname = lib$(cname).so.$(capi_major) 3.32 - cdevlink = lib$(cname).so 3.33 - cclib_so = lib$(ccname).so.$(ccapi_major).$(ccapi_minor) 3.34 - ccsoname = lib$(ccname).so.$(ccapi_major) 3.35 - ccdevlink = lib$(ccname).so 3.36 - 3.37 - cshared = -shared -Wl,-soname=$(csoname) 3.38 - ccshared = -shared -Wl,-soname=$(ccsoname) 3.39 - pic = -fPIC 3.40 -endif 3.41 - 3.42 -dbg = -g 3.43 -cxx11 = -std=c++11 -DTS_USE_CPP11 3.44 - 3.45 -CFLAGS = -pedantic -Wall $(dbg) $(opt) $(pic) 3.46 -CXXFLAGS = $(cxx11) $(CFLAGS) 3.47 - 3.48 -.PHONY: all 3.49 -all: $(clib_so) $(clib_a) $(cclib_so) $(cclib_a) 3.50 - 3.51 -$(clib_a): $(cobj) 3.52 - $(AR) rcs $@ $(cobj) 3.53 - 3.54 -$(clib_so): $(cobj) 3.55 - $(CC) -o $@ $(cshared) $(cobj) $(LDFLAGS) 3.56 - 3.57 -$(cclib_a): $(ccobj) 3.58 - $(AR) rcs $@ $(ccobj) 3.59 - 3.60 -$(cclib_so): $(ccobj) 3.61 - $(CXX) -o $@ $(ccshared) $(ccobj) $(LDFLAGS) 3.62 - 3.63 --include $(dep) 3.64 - 3.65 -%.d: %.c 3.66 - @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ 3.67 - 3.68 -%.d: %.cc 3.69 - @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@ 3.70 - 3.71 -.PHONY: clean 3.72 -clean: 3.73 - rm -f $(obj) $(clib_so) $(cclib_so) $(clib_a) $(cclib_a) 3.74 - 3.75 -.PHONY: cleandep 3.76 -cleandep: clean 3.77 - rm -f $(dep) 3.78 - 3.79 - 3.80 -.PHONY: install 3.81 -install: all 3.82 - mkdir -p $(DESTDIR)$(PREFIX)/include $(DESTDIR)$(PREFIX)/lib 3.83 - cp src/treestore.h src/treestorepp.h $(DESTDIR)$(PREFIX)/include 3.84 - cp $(clib_a) $(clib_so) $(cclib_a) $(cclib_so) $(DESTDIR)$(PREFIX)/lib 3.85 - [ -n "$(csoname)" ] && \ 3.86 - cd $(DESTDIR)$(PREFIX) && \ 3.87 - rm -f $(csoname) $(cdevlink) $(ccsoname) $(ccdevlink) && \ 3.88 - ln -s $(clib_so) $(csoname) && \ 3.89 - ln -s $(cclib_so) $(ccsoname) && \ 3.90 - ln -s $(csoname) $(cdevlink) && \ 3.91 - ln -s $(ccsoname) $(ccdevlink) || \ 3.92 - true
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/include/treestore.h Thu Nov 10 16:19:44 2016 +0200 4.3 @@ -0,0 +1,114 @@ 4.4 +#ifndef TREESTORE_H_ 4.5 +#define TREESTORE_H_ 4.6 + 4.7 +#include <stdarg.h> 4.8 + 4.9 +#ifdef __cplusplus 4.10 +extern "C" { 4.11 +#endif 4.12 + 4.13 +enum ts_value_type { TS_UNKNOWN, TS_NUMBER, TS_VECTOR, TS_ARRAY }; 4.14 + 4.15 +/** treestore node attribute value */ 4.16 +struct ts_value { 4.17 + enum ts_value_type type; 4.18 + 4.19 + char *str; /**< all values have a string representation */ 4.20 + int inum; /**< numeric values TS_NUMBER will have this set */ 4.21 + float fnum; /**< numeric values TS_NUMBER will have this set */ 4.22 + 4.23 + /** vector values (arrays containing ONLY numbers) will have this set */ 4.24 + float *vec; /**< elements of the vector */ 4.25 + int vec_size; /**< size of the vector (in elements), same as array_size */ 4.26 + 4.27 + /** array values (including vectors) will have this set */ 4.28 + struct ts_value *array; /**< elements of the array */ 4.29 + int array_size; /**< size of the array (in elements) */ 4.30 +}; 4.31 + 4.32 +int ts_init_value(struct ts_value *tsv); 4.33 +void ts_destroy_value(struct ts_value *tsv); 4.34 + 4.35 +struct ts_value *ts_alloc_value(void); /**< also calls ts_init_value */ 4.36 +void ts_free_value(struct ts_value *tsv); /**< also calls ts_destroy_value */ 4.37 + 4.38 +/** perform a deep-copy of a ts_value */ 4.39 +int ts_copy_value(struct ts_value *dest, struct ts_value *src); 4.40 + 4.41 +/** ts_set_value will try to parse the string and initialize the value type fields */ 4.42 +int ts_set_value(struct ts_value *tsv, const char *str); 4.43 + 4.44 +/** set a ts_value from a list of integers */ 4.45 +int ts_set_valueiv(struct ts_value *tsv, int count, ...); 4.46 +int ts_set_valueiv_va(struct ts_value *tsv, int count, va_list ap); 4.47 +int ts_set_valuei(struct ts_value *tsv, int inum); /**< equiv: ts_set_valueiv(val, 1, inum) */ 4.48 + 4.49 +/** set a ts_value from a list of floats */ 4.50 +int ts_set_valuefv(struct ts_value *tsv, int count, ...); 4.51 +int ts_set_valuefv_va(struct ts_value *tsv, int count, va_list ap); 4.52 +int ts_set_valuef(struct ts_value *tsv, int fnum); /**< equiv: ts_set_valuefv(val, 1, fnum) */ 4.53 + 4.54 +/** set a ts_value from a list of ts_value pointers. they are deep-copied as per ts_copy_value */ 4.55 +int ts_set_valuev(struct ts_value *tsv, int count, ...); 4.56 +int ts_set_valuev_va(struct ts_value *tsv, int count, va_list ap); 4.57 + 4.58 + 4.59 +/** treestore node attribute */ 4.60 +struct ts_attr { 4.61 + char *name; 4.62 + struct ts_value val; 4.63 + 4.64 + struct ts_attr *next; 4.65 +}; 4.66 + 4.67 +int ts_init_attr(struct ts_attr *attr); 4.68 +void ts_destroy_attr(struct ts_attr *attr); 4.69 + 4.70 +struct ts_attr *ts_alloc_attr(void); /**< also calls ts_init_attr */ 4.71 +void ts_free_attr(struct ts_attr *attr); /**< also calls ts_destroy_attr */ 4.72 + 4.73 +/** perform a deep-copy of a ts_attr */ 4.74 +int ts_copy_attr(struct ts_attr *dest, struct ts_attr *src); 4.75 + 4.76 +int ts_set_attr_name(struct ts_attr *attr, const char *name); 4.77 + 4.78 + 4.79 + 4.80 +/** treestore node */ 4.81 +struct ts_node { 4.82 + char *name; 4.83 + 4.84 + int attr_count; 4.85 + struct ts_attr *attr_list, *attr_tail; 4.86 + 4.87 + int child_count; 4.88 + struct ts_node *child_list, *child_tail; 4.89 + struct ts_node *parent; 4.90 + 4.91 + struct ts_node *next; /* next sibling */ 4.92 +}; 4.93 + 4.94 +int ts_init_node(struct ts_node *node); 4.95 +void ts_destroy_node(struct ts_node *node); 4.96 + 4.97 +struct ts_node *ts_alloc_node(void); /**< also calls ts_init_node */ 4.98 +void ts_free_node(struct ts_node *n); /**< also calls ts_destroy_node */ 4.99 + 4.100 +/** recursively destroy all the nodes of the tree */ 4.101 +void ts_free_tree(struct ts_node *tree); 4.102 + 4.103 +void ts_add_attr(struct ts_node *node, struct ts_attr *attr); 4.104 +struct ts_attr *ts_get_attr(struct ts_node *node, const char *name); 4.105 + 4.106 +void ts_add_child(struct ts_node *node, struct ts_node *child); 4.107 +int ts_remove_child(struct ts_node *node, struct ts_node *child); 4.108 +struct ts_node *ts_get_child(struct ts_node *node, const char *name); 4.109 + 4.110 +struct ts_node *ts_load(const char *fname); 4.111 +int ts_save(struct ts_node *tree, const char *fname); 4.112 + 4.113 +#ifdef __cplusplus 4.114 +} 4.115 +#endif 4.116 + 4.117 +#endif /* TREESTORE_H_ */
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/text.c Thu Nov 10 16:19:44 2016 +0200 5.3 @@ -0,0 +1,235 @@ 5.4 +#include <stdio.h> 5.5 +#include <stdlib.h> 5.6 +#include <string.h> 5.7 +#include <ctype.h> 5.8 +#include "treestore.h" 5.9 + 5.10 +enum { TOK_SYM, TOK_ID, TOK_NUM, TOK_STR }; 5.11 + 5.12 +static struct ts_node *read_node(FILE *fp); 5.13 +static int next_token(FILE *fp, char *buf, int bsz); 5.14 + 5.15 +static void print_attr(struct ts_attr *attr, FILE *fp, int level); 5.16 +static void print_value(struct ts_value *value, FILE *fp); 5.17 +static int tree_level(struct ts_node *n); 5.18 +static const char *indent(int x); 5.19 + 5.20 +struct ts_node *ts_text_load(FILE *fp) 5.21 +{ 5.22 + char token[256]; 5.23 + struct ts_node *node; 5.24 + 5.25 + if(next_token(fp, token, sizeof token) != TOK_ID || 5.26 + !(next_token(fp, token, sizeof token) == TOK_SYM && token[0] == '{')) { 5.27 + fprintf(stderr, "ts_text_load: invalid file format\n"); 5.28 + return 0; 5.29 + } 5.30 + if(!(node = read_node(fp))) { 5.31 + return 0; 5.32 + } 5.33 + if(!(node->name = strdup(token))) { 5.34 + perror("failed to allocate node name"); 5.35 + free(node); 5.36 + return 0; 5.37 + } 5.38 + return node; 5.39 +} 5.40 + 5.41 + 5.42 +#define EXPECT(type) \ 5.43 + if(next_token(fp, token, sizeof token) != (type)) goto err 5.44 +#define EXPECT_SYM(c) \ 5.45 + if(next_token(fp, token, sizeof token) != TOK_SYM || token[0] != (c)) goto err 5.46 + 5.47 +static struct ts_node *read_node(FILE *fp) 5.48 +{ 5.49 + char token[256]; 5.50 + struct ts_node *node; 5.51 + 5.52 + if(!(node = ts_alloc_node())) { 5.53 + perror("failed to allocate treestore node"); 5.54 + return 0; 5.55 + } 5.56 + 5.57 + while(next_token(fp, token, sizeof token) == TOK_ID) { 5.58 + char *id; 5.59 + 5.60 + if(!(id = strdup(token))) { 5.61 + goto err; 5.62 + } 5.63 + 5.64 + EXPECT(TOK_SYM); 5.65 + 5.66 + if(token[0] == '=') { 5.67 + /* attribute */ 5.68 + struct ts_attr *attr; 5.69 + int toktype; 5.70 + 5.71 + if(!(attr = ts_alloc_attr())) { 5.72 + goto err; 5.73 + } 5.74 + 5.75 + if((toktype = next_token(fp, token, sizeof token)) == -1) { 5.76 + ts_free_attr(attr); 5.77 + goto err; 5.78 + } 5.79 + attr->name = id; 5.80 + ts_set_value(&attr->val, token); 5.81 + 5.82 + ts_add_attr(node, attr); 5.83 + 5.84 + } else if(token[0] == '{') { 5.85 + /* child */ 5.86 + struct ts_node *child; 5.87 + 5.88 + if(!(child = read_node(fp))) { 5.89 + ts_free_node(node); 5.90 + return 0; 5.91 + } 5.92 + child->name = id; 5.93 + 5.94 + ts_add_child(node, child); 5.95 + 5.96 + } else { 5.97 + fprintf(stderr, "unexpected token: %s\n", token); 5.98 + goto err; 5.99 + } 5.100 + } 5.101 + 5.102 +err: 5.103 + fprintf(stderr, "treestore read_node failed\n"); 5.104 + ts_free_node(node); 5.105 + return 0; 5.106 +} 5.107 + 5.108 +static int next_token(FILE *fp, char *buf, int bsz) 5.109 +{ 5.110 + int c; 5.111 + char *ptr; 5.112 + 5.113 + // skip whitespace 5.114 + while((c = fgetc(fp)) != -1 && isspace(c)) { 5.115 + if(c == '#') { // skip to end of line 5.116 + while((c = fgetc(fp)) != -1 && c != '\n'); 5.117 + if(c == -1) return -1; 5.118 + } 5.119 + } 5.120 + if(c == -1) return -1; 5.121 + 5.122 + buf[0] = c; 5.123 + buf[1] = 0; 5.124 + 5.125 + if(isdigit(c)) { 5.126 + // token is a number 5.127 + ptr = buf + 1; 5.128 + while((c = fgetc(fp)) != -1 && isdigit(c)) { 5.129 + *ptr++ = c; 5.130 + } 5.131 + if(c != -1) ungetc(c, fp); 5.132 + *ptr = 0; 5.133 + return TOK_NUM; 5.134 + } 5.135 + if(isalpha(c)) { 5.136 + // token is an identifier 5.137 + ptr = buf + 1; 5.138 + while((c = fgetc(fp)) != -1 && isalnum(c)) { 5.139 + *ptr++ = c; 5.140 + } 5.141 + if(c != -1) ungetc(c, fp); 5.142 + *ptr = 0; 5.143 + return TOK_ID; 5.144 + } 5.145 + if(c == '"') { 5.146 + // token is a string constant 5.147 + ptr = buf; 5.148 + while((c = fgetc(fp)) != -1 && c != '"' && c != '\r' && c != '\n') { 5.149 + *ptr++ = c; 5.150 + } 5.151 + if(c != '"') { 5.152 + return -1; 5.153 + } 5.154 + *ptr = 0; 5.155 + return TOK_STR; 5.156 + } 5.157 + 5.158 + return TOK_SYM; 5.159 +} 5.160 + 5.161 +int ts_text_save(struct ts_node *tree, FILE *fp) 5.162 +{ 5.163 + struct ts_node *c; 5.164 + struct ts_attr *attr; 5.165 + int lvl = tree_level(tree); 5.166 + 5.167 + fprintf(fp, "%s%s {\n", indent(lvl), tree->name); 5.168 + 5.169 + attr = tree->attr_list; 5.170 + while(attr) { 5.171 + print_attr(attr, fp, lvl); 5.172 + attr = attr->next; 5.173 + } 5.174 + 5.175 + c = tree->child_list; 5.176 + while(c) { 5.177 + ts_text_save(c, fp); 5.178 + } 5.179 + 5.180 + fprintf(fp, "%s}\n", indent(lvl)); 5.181 +} 5.182 + 5.183 +static void print_attr(struct ts_attr *attr, FILE *fp, int level) 5.184 +{ 5.185 + fprintf(fp, "%s%s = ", indent(level + 1), attr->name); 5.186 + print_value(&attr->val, fp); 5.187 + fputc('\n', fp); 5.188 +} 5.189 + 5.190 +static void print_value(struct ts_value *value, FILE *fp) 5.191 +{ 5.192 + int i; 5.193 + 5.194 + switch(value->type) { 5.195 + case TS_NUMBER: 5.196 + fprintf(fp, "%g", value->fnum); 5.197 + break; 5.198 + 5.199 + case TS_VECTOR: 5.200 + fputc('[', fp); 5.201 + for(i=0; i<value->vec_size; i++) { 5.202 + if(i == 0) { 5.203 + fprintf(fp, "%g", value->vec[i]); 5.204 + } else { 5.205 + fprintf(fp, ", %g", value->vec[i]); 5.206 + } 5.207 + } 5.208 + fputc(']', fp); 5.209 + break; 5.210 + 5.211 + case TS_ARRAY: 5.212 + fputc('[', fp); 5.213 + for(i=0; i<value->array_size; i++) { 5.214 + if(i > 0) { 5.215 + fprintf(fp, ", "); 5.216 + } 5.217 + print_value(value->array + i, fp); 5.218 + } 5.219 + fputc(']', fp); 5.220 + break; 5.221 + 5.222 + default: 5.223 + fputs(value->str, fp); 5.224 + } 5.225 +} 5.226 + 5.227 +static int tree_level(struct ts_node *n) 5.228 +{ 5.229 + if(!n->parent) return 0; 5.230 + return tree_level(n->parent) + 1; 5.231 +} 5.232 + 5.233 +static const char *indent(int x) 5.234 +{ 5.235 + static const char *buf = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; 5.236 + const char *end = buf + sizeof buf - 1; 5.237 + return x > sizeof buf - 1 ? buf : end - x; 5.238 +}
6.1 --- a/src/treestore.c Sat Apr 12 13:50:01 2014 +0300 6.2 +++ b/src/treestore.c Thu Nov 10 16:19:44 2016 +0200 6.3 @@ -1,8 +1,12 @@ 6.4 #include <stdio.h> 6.5 #include <stdlib.h> 6.6 #include <string.h> 6.7 +#include <errno.h> 6.8 #include "treestore.h" 6.9 6.10 +struct ts_node *ts_text_load(FILE *fp); 6.11 +int ts_text_save(struct ts_node *tree, FILE *fp); 6.12 + 6.13 /* ---- ts_value implementation ---- */ 6.14 6.15 int ts_init_value(struct ts_value *tsv) 6.16 @@ -359,3 +363,106 @@ 6.17 6.18 ts_free_node(tree); 6.19 } 6.20 + 6.21 +void ts_add_attr(struct ts_node *node, struct ts_attr *attr) 6.22 +{ 6.23 + attr->next = 0; 6.24 + if(node->attr_list) { 6.25 + node->attr_tail->next = attr; 6.26 + node->attr_tail = attr; 6.27 + } else { 6.28 + node->attr_list = node->attr_tail = attr; 6.29 + } 6.30 +} 6.31 + 6.32 +struct ts_attr *ts_get_attr(struct ts_node *node, const char *name) 6.33 +{ 6.34 + struct ts_attr *attr = node->attr_list; 6.35 + while(attr) { 6.36 + if(strcmp(attr->name, name) == 0) { 6.37 + return attr; 6.38 + } 6.39 + attr = attr->next; 6.40 + } 6.41 + return 0; 6.42 +} 6.43 + 6.44 +void ts_add_child(struct ts_node *node, struct ts_node *child) 6.45 +{ 6.46 + if(child->parent) { 6.47 + if(child->parent == node) return; 6.48 + ts_remove_child(child->parent, child); 6.49 + } 6.50 + child->parent = node; 6.51 + child->next = 0; 6.52 + 6.53 + if(node->child_list) { 6.54 + node->child_tail->next = child; 6.55 + node->child_tail = child; 6.56 + } else { 6.57 + node->child_list = node->child_tail = child; 6.58 + } 6.59 +} 6.60 + 6.61 +int ts_remove_child(struct ts_node *node, struct ts_node *child) 6.62 +{ 6.63 + struct ts_node dummy, *iter = &dummy; 6.64 + dummy.next = node->child_list; 6.65 + 6.66 + while(iter->next && iter->next != child) { 6.67 + iter = iter->next; 6.68 + } 6.69 + if(!iter->next) { 6.70 + return -1; 6.71 + } 6.72 + 6.73 + child->parent = 0; 6.74 + 6.75 + iter->next = child->next; 6.76 + if(!iter->next) { 6.77 + node->child_tail = iter; 6.78 + } 6.79 + node->child_list = dummy.next; 6.80 + return 0; 6.81 +} 6.82 + 6.83 +struct ts_node *ts_get_child(struct ts_node *node, const char *name) 6.84 +{ 6.85 + struct ts_node *res = node->child_list; 6.86 + while(res) { 6.87 + if(strcmp(res->name, name) == 0) { 6.88 + return res; 6.89 + } 6.90 + res = res->next; 6.91 + } 6.92 + return 0; 6.93 +} 6.94 + 6.95 +struct ts_node *ts_load(const char *fname) 6.96 +{ 6.97 + FILE *fp; 6.98 + struct ts_node *root; 6.99 + 6.100 + if(!(fp = fopen(fname, "rb"))) { 6.101 + fprintf(stderr, "ts_load: failed to open file: %s: %s\n", fname, strerror(errno)); 6.102 + return 0; 6.103 + } 6.104 + 6.105 + root = ts_text_load(fp); 6.106 + fclose(fp); 6.107 + return root; 6.108 +} 6.109 + 6.110 +int ts_save(struct ts_node *tree, const char *fname) 6.111 +{ 6.112 + FILE *fp; 6.113 + int res; 6.114 + 6.115 + if(!(fp = fopen(fname, "wb"))) { 6.116 + fprintf(stderr, "ts_save: failed to open file: %s: %s\n", fname, strerror(errno)); 6.117 + return 0; 6.118 + } 6.119 + res = ts_text_save(tree, fp); 6.120 + fclose(fp); 6.121 + return res; 6.122 +}
7.1 --- a/src/treestore.h Sat Apr 12 13:50:01 2014 +0300 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,103 +0,0 @@ 7.4 -#ifndef TREESTORE_H_ 7.5 -#define TREESTORE_H_ 7.6 - 7.7 -#include <stdarg.h> 7.8 - 7.9 -#ifdef __cplusplus 7.10 -extern "C" { 7.11 -#endif 7.12 - 7.13 -enum ts_value_type { TS_UNKNOWN, TS_NUMBER, TS_VECTOR, TS_ARRAY }; 7.14 - 7.15 -/** treestore node attribute value */ 7.16 -struct ts_value { 7.17 - enum ts_value_type type; 7.18 - 7.19 - char *str; /**< all values have a string representation */ 7.20 - int inum; /**< numeric values (TS_INT/TS_FLOAT) will have this set */ 7.21 - float fnum; /**< numeric values (TS_INT/TS_FLOAT) will have this set */ 7.22 - 7.23 - /** vector values (arrays containing ONLY numbers) will have this set */ 7.24 - float *vec; /**< elements of the vector */ 7.25 - int vec_size; /**< size of the vector (in elements), same as array_size */ 7.26 - 7.27 - /** array values (including vectors) will have this set */ 7.28 - struct ts_value *array; /**< elements of the array */ 7.29 - int array_size; /**< size of the array (in elements) */ 7.30 -}; 7.31 - 7.32 -int ts_init_value(struct ts_value *tsv); 7.33 -void ts_destroy_value(struct ts_value *tsv); 7.34 - 7.35 -struct ts_value *ts_alloc_value(void); /**< also calls ts_init_value */ 7.36 -void ts_free_value(struct ts_value *tsv); /**< also calls ts_destroy_value */ 7.37 - 7.38 -/** perform a deep-copy of a ts_value */ 7.39 -int ts_copy_value(struct ts_value *dest, struct ts_value *src); 7.40 - 7.41 -/** ts_set_value will try to parse the string and initialize the value type fields */ 7.42 -int ts_set_value(struct ts_value *tsv, const char *str); 7.43 - 7.44 -/** set a ts_value from a list of integers */ 7.45 -int ts_set_valueiv(struct ts_value *tsv, int count, ...); 7.46 -int ts_set_valueiv_va(struct ts_value *tsv, int count, va_list ap); 7.47 -int ts_set_valuei(struct ts_value *tsv, int inum); /**< equiv: ts_set_valueiv(val, 1, inum) */ 7.48 - 7.49 -/** set a ts_value from a list of floats */ 7.50 -int ts_set_valuefv(struct ts_value *tsv, int count, ...); 7.51 -int ts_set_valuefv_va(struct ts_value *tsv, int count, va_list ap); 7.52 -int ts_set_valuef(struct ts_value *tsv, int fnum); /**< equiv: ts_set_valuefv(val, 1, fnum) */ 7.53 - 7.54 -/** set a ts_value from a list of ts_value pointers. they are deep-copied as per ts_copy_value */ 7.55 -int ts_set_valuev(struct ts_value *tsv, int count, ...); 7.56 -int ts_set_valuev_va(struct ts_value *tsv, int count, va_list ap); 7.57 - 7.58 - 7.59 -/** treestore node attribute */ 7.60 -struct ts_attr { 7.61 - char *name; 7.62 - struct ts_value val; 7.63 - 7.64 - struct ts_attr *next; 7.65 -}; 7.66 - 7.67 -int ts_init_attr(struct ts_attr *attr); 7.68 -void ts_destroy_attr(struct ts_attr *attr); 7.69 - 7.70 -struct ts_attr *ts_alloc_attr(void); /**< also calls ts_init_attr */ 7.71 -void ts_free_attr(struct ts_attr *attr); /**< also calls ts_destroy_attr */ 7.72 - 7.73 -/** perform a deep-copy of a ts_attr */ 7.74 -int ts_copy_attr(struct ts_attr *dest, struct ts_attr *src); 7.75 - 7.76 -int ts_set_attr_name(struct ts_attr *attr, const char *name); 7.77 - 7.78 - 7.79 - 7.80 -/** treestore node */ 7.81 -struct ts_node { 7.82 - char *name; 7.83 - 7.84 - int attr_count; 7.85 - struct ts_attr *attr_list, *attr_tail; 7.86 - 7.87 - int child_count; 7.88 - struct ts_node *child_list, *child_tail; 7.89 - struct ts_node *parent; 7.90 - 7.91 - struct ts_node *next; /* next sibling */ 7.92 -}; 7.93 - 7.94 -int ts_init_node(struct ts_node *node); 7.95 -void ts_destroy_node(struct ts_node *node); 7.96 - 7.97 -struct ts_node *ts_alloc_node(void); /**< also calls ts_init_node */ 7.98 -void ts_free_node(struct ts_node *n); /**< also calls ts_destroy_node */ 7.99 - 7.100 -void ts_free_tree(struct ts_node *tree); 7.101 - 7.102 -#ifdef __cplusplus 7.103 -} 7.104 -#endif 7.105 - 7.106 -#endif /* TREESTORE_H_ */
8.1 --- a/src/treestorepp.h Sat Apr 12 13:50:01 2014 +0300 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,44 +0,0 @@ 8.4 -#ifndef TREESTOREPP_H_ 8.5 -#define TREESTOREPP_H_ 8.6 - 8.7 -#include "treestore.h" 8.8 - 8.9 -/// wraps a C ts_value in a convenient class 8.10 -class TSValue { 8.11 -private: 8.12 - ts_value *ctsv; 8.13 - 8.14 -public: 8.15 - TSValue(); 8.16 - ~TSValue(); 8.17 - 8.18 - TSValue(const TSValue &tsv); 8.19 - TSValue &operator =(const TSValue &tsv); 8.20 - 8.21 -#ifdef TS_USE_CPP11 8.22 - TSValue(const TSValue &&tsv); 8.23 - TSValue &operator =(const TSValue &&tsv); 8.24 -#endif 8.25 - 8.26 - bool set(const char *str); 8.27 - bool set_int(int inum); 8.28 - bool set_int(int count, ...); 8.29 - bool set_float(float fnum); 8.30 - bool set_float(int count, ...); 8.31 - bool set_array(int count, const TSValue &v0, ...); 8.32 - 8.33 - const char *get() const; 8.34 - 8.35 - int get_int() const; 8.36 - int *get_intv() const; 8.37 - 8.38 - float get_float() const; 8.39 - float *get_floatv() const; 8.40 - 8.41 - const TSValue *get_array() const; 8.42 - int get_array_size() const; 8.43 - 8.44 - int get_vec_size() const; //< equiv: get_array_size */ 8.45 -}; 8.46 - 8.47 -#endif // TREESTOREPP_H_