(broken-commit) - added load and store functions, tests failing

Thu, 04 Oct 2012 16:03:18 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 04 Oct 2012 16:03:18 +0200
changeset 42
ff3dd1ee7dee
parent 41
7f90a03e186e
child 43
02f38adea013

(broken-commit) - added load and store functions, tests failing

some evil crash happens when executing the test - remove the strcmp calls in the test case for the store and load function and everything "works"

the error must be somewhere else - maybe something that should not be freed is freed during the test

test/main.c file | annotate | diff | comparison | revisions
test/map_tests.c file | annotate | diff | comparison | revisions
test/map_tests.h file | annotate | diff | comparison | revisions
ucx/map.c file | annotate | diff | comparison | revisions
ucx/map.h file | annotate | diff | comparison | revisions
ucx/string.h file | annotate | diff | comparison | revisions
ucx/ucx.h file | annotate | diff | comparison | revisions
--- a/test/main.c	Thu Oct 04 14:08:31 2012 +0200
+++ b/test/main.c	Thu Oct 04 16:03:18 2012 +0200
@@ -147,6 +147,7 @@
         ucx_test_register(suite, test_ucx_map_get);
         ucx_test_register(suite, test_ucx_map_iterator);
         ucx_test_register(suite, test_ucx_map_iterator_chain);
+        ucx_test_register(suite, test_ucx_map_store_load);
         
         /* sstring Tests */
         ucx_test_register(suite, test_sstrsplit);
--- a/test/map_tests.c	Thu Oct 04 14:08:31 2012 +0200
+++ b/test/map_tests.c	Thu Oct 04 16:03:18 2012 +0200
@@ -136,3 +136,55 @@
     UCX_TEST_END
     ucx_map_free(map);
 }
+
+UCX_TEST_IMPLEMENT(test_ucx_map_store_load) {
+    UcxMap *map = ucx_map_new(4);
+
+    ucx_map_cstr_put(map, "test", "test");
+    ucx_map_cstr_put(map, "key", "value");
+    ucx_map_cstr_put(map, "other.very.long.key", "value");
+    ucx_map_cstr_put(map, "testkey", "testvalue");
+    ucx_map_cstr_put(map, "simple", "not a key but an extremely long value "
+            "to test if the buffer extension works as designed");
+
+    FILE *f = fopen("test_ucx_map_store", "w");
+    int r;
+
+    fwrite(" # comment test", 1, 15, f);
+    r = ucx_map_store(map, f);
+    fwrite("#discard this", 1, 13, f);
+
+    fclose(f);
+    ucx_map_free(map);
+    map = ucx_map_new(1);
+    f = fopen("test_ucx_map_store", "r");
+    r += ucx_map_load(map, f);
+
+    UCX_TEST_BEGIN
+    char *value;
+    UCX_TEST_ASSERT(r == 0, "IO errors, test cannot be performed");
+
+    value = ucx_map_cstr_get(map, "test");
+    UCX_TEST_ASSERT(strcmp(value, "test") == 0, "value error for key: test");
+
+    value = ucx_map_cstr_get(map, "key");
+    UCX_TEST_ASSERT(strcmp(value, "value") == 0, "value error for key: key");
+
+    value = ucx_map_cstr_get(map, "other.very.long.key");
+    UCX_TEST_ASSERT(strcmp(value, "value") == 0,
+            "value error for key: other.very.long.key");
+
+    value = ucx_map_cstr_get(map, "testkey");
+    UCX_TEST_ASSERT(strcmp(value, "testvalue") == 0,
+            "value error for key: testkey");
+
+    value = ucx_map_cstr_get(map, "simple");
+    UCX_TEST_ASSERT(strcmp(value, "not a key but an extremely long value "
+            "to test if the buffer extension works as designed") == 0,
+            "value error for key: simple");
+
+    UCX_TEST_END
+    fclose(f);
+
+    unlink("test_ucx_map_store");
+}
--- a/test/map_tests.h	Thu Oct 04 14:08:31 2012 +0200
+++ b/test/map_tests.h	Thu Oct 04 16:03:18 2012 +0200
@@ -18,6 +18,7 @@
 UCX_TEST_DECLARE(test_ucx_map_get)
 UCX_TEST_DECLARE(test_ucx_map_iterator)
 UCX_TEST_DECLARE(test_ucx_map_iterator_chain)
+UCX_TEST_DECLARE(test_ucx_map_store_load)
 
 
 #ifdef	__cplusplus
--- a/ucx/map.c	Thu Oct 04 14:08:31 2012 +0200
+++ b/ucx/map.c	Thu Oct 04 16:03:18 2012 +0200
@@ -189,3 +189,83 @@
     
     return 1;
 }
+
+int ucx_map_load(UcxMap *map, FILE *f) {
+
+    char c; int r, n;
+
+    char *key, *value;
+
+    while ((c = (char) fgetc(f)) > 0) {
+        /* Discard leading spaces and comments */
+        if (c == ' ') continue;
+        if (c == '#' || c == '!') {
+            while ((c = (char) fgetc(f)) > 0) {
+                if (c == '\n') break;
+            }
+            continue;
+        }
+
+        /* read into key buffer */
+        n = 16;
+        key = malloc(n);
+        r = 0;
+        do {
+            if (c == '=') break;
+            if (r > n - 2) {
+                n *= 2;
+                key = realloc(key, n);
+            }
+            key[r] = c;
+            r++;
+        } while ((c = (char) fgetc(f)) > 0);
+        if (c == 0) {
+            free(key);
+            return 1;
+        }
+        key[r] = 0;
+
+        /* read into value buffer */
+        n = 64;
+        value = malloc(n);
+        r = 0;
+        while ((c = (char) fgetc(f)) > 0) {
+            if (c == '\n') break;
+            if (r > n - 1) {
+                n *= 2;
+                value = realloc(value, n);
+            }
+            value[r] = c;
+            r++;
+        }
+        value = realloc(value, r+1);
+        value[r] = 0;
+
+        ucx_map_cstr_put(map, key, value);
+        free(key);
+    }
+
+    return 0;
+}
+
+int ucx_map_store(UcxMap *map, FILE *f) {
+    UcxMapIterator iter = ucx_map_iterator(map);
+    char *k, *v;
+    sstr_t key, value;
+    int written;
+
+    UCX_MAP_FOREACH(v, iter) {
+        k = (char*) iter.cur->key.data;
+        key = sstr(k); value = sstr(v);
+
+        written = 0;
+        written += fwrite(key.ptr, 1, key.length, f);
+        written += fwrite(" = ", 1, 3, f);
+        written += fwrite(value.ptr, 1, value.length, f);
+        written += fwrite("\n", 1, 1, f);
+
+        if (written != key.length + value.length + 4) return 1;
+    }
+
+    return 0;
+}
--- a/ucx/map.h	Thu Oct 04 14:08:31 2012 +0200
+++ b/ucx/map.h	Thu Oct 04 16:03:18 2012 +0200
@@ -14,7 +14,7 @@
 #endif
 
 #define UCX_MAP_FOREACH(elm,iter) \
-        for(elm;ucx_map_iter_next(&iter,(void*)&elm)==0;)
+        for(;ucx_map_iter_next(&iter,(void*)&elm)==0;)
 
 typedef struct UcxMap          UcxMap;
 typedef struct UcxKey          UcxKey;
@@ -64,6 +64,15 @@
 
 int ucx_map_iter_next(UcxMapIterator *i, void **elm);
 
+/* use for string maps only, values are not encoded */
+int ucx_map_load(UcxMap *map, FILE *f);
+int ucx_map_store(UcxMap *map, FILE *f);
+
+/* TODO:
+int ucx_map_load_enc(UcxMap *map, FILE *f, copy_func decoder, void* decdata);
+int ucx_map_store_enc(UcxMap *map, FILE *f, copy_func encoder, void* encdata);
+ */
+
 #ifdef	__cplusplus
 }
 #endif
--- a/ucx/string.h	Thu Oct 04 14:08:31 2012 +0200
+++ b/ucx/string.h	Thu Oct 04 16:03:18 2012 +0200
@@ -10,6 +10,7 @@
 
 #include <stddef.h>
 
+/* use macros for literals only */
 #define S(s) { s, sizeof(s)-1 }
 #define ST(s) sstrn(s, sizeof(s)-1)
 
--- a/ucx/ucx.h	Thu Oct 04 14:08:31 2012 +0200
+++ b/ucx/ucx.h	Thu Oct 04 16:03:18 2012 +0200
@@ -17,9 +17,6 @@
 #define UCX_FOREACH(type,list,elem) \
         for (type elem = list ; elem != NULL ; elem = elem->next)
     
-/* source,data -> errno */
-typedef int(*ucx_callback)(void*,void*);
-
 /* element1,element2,custom data -> {-1,0,1} */
 typedef int(*cmp_func)(void*,void*,void*);
 

mercurial