Thu, 04 Oct 2012 16:03:18 +0200
(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 |
1.1 --- a/test/main.c Thu Oct 04 14:08:31 2012 +0200 1.2 +++ b/test/main.c Thu Oct 04 16:03:18 2012 +0200 1.3 @@ -147,6 +147,7 @@ 1.4 ucx_test_register(suite, test_ucx_map_get); 1.5 ucx_test_register(suite, test_ucx_map_iterator); 1.6 ucx_test_register(suite, test_ucx_map_iterator_chain); 1.7 + ucx_test_register(suite, test_ucx_map_store_load); 1.8 1.9 /* sstring Tests */ 1.10 ucx_test_register(suite, test_sstrsplit);
2.1 --- a/test/map_tests.c Thu Oct 04 14:08:31 2012 +0200 2.2 +++ b/test/map_tests.c Thu Oct 04 16:03:18 2012 +0200 2.3 @@ -136,3 +136,55 @@ 2.4 UCX_TEST_END 2.5 ucx_map_free(map); 2.6 } 2.7 + 2.8 +UCX_TEST_IMPLEMENT(test_ucx_map_store_load) { 2.9 + UcxMap *map = ucx_map_new(4); 2.10 + 2.11 + ucx_map_cstr_put(map, "test", "test"); 2.12 + ucx_map_cstr_put(map, "key", "value"); 2.13 + ucx_map_cstr_put(map, "other.very.long.key", "value"); 2.14 + ucx_map_cstr_put(map, "testkey", "testvalue"); 2.15 + ucx_map_cstr_put(map, "simple", "not a key but an extremely long value " 2.16 + "to test if the buffer extension works as designed"); 2.17 + 2.18 + FILE *f = fopen("test_ucx_map_store", "w"); 2.19 + int r; 2.20 + 2.21 + fwrite(" # comment test", 1, 15, f); 2.22 + r = ucx_map_store(map, f); 2.23 + fwrite("#discard this", 1, 13, f); 2.24 + 2.25 + fclose(f); 2.26 + ucx_map_free(map); 2.27 + map = ucx_map_new(1); 2.28 + f = fopen("test_ucx_map_store", "r"); 2.29 + r += ucx_map_load(map, f); 2.30 + 2.31 + UCX_TEST_BEGIN 2.32 + char *value; 2.33 + UCX_TEST_ASSERT(r == 0, "IO errors, test cannot be performed"); 2.34 + 2.35 + value = ucx_map_cstr_get(map, "test"); 2.36 + UCX_TEST_ASSERT(strcmp(value, "test") == 0, "value error for key: test"); 2.37 + 2.38 + value = ucx_map_cstr_get(map, "key"); 2.39 + UCX_TEST_ASSERT(strcmp(value, "value") == 0, "value error for key: key"); 2.40 + 2.41 + value = ucx_map_cstr_get(map, "other.very.long.key"); 2.42 + UCX_TEST_ASSERT(strcmp(value, "value") == 0, 2.43 + "value error for key: other.very.long.key"); 2.44 + 2.45 + value = ucx_map_cstr_get(map, "testkey"); 2.46 + UCX_TEST_ASSERT(strcmp(value, "testvalue") == 0, 2.47 + "value error for key: testkey"); 2.48 + 2.49 + value = ucx_map_cstr_get(map, "simple"); 2.50 + UCX_TEST_ASSERT(strcmp(value, "not a key but an extremely long value " 2.51 + "to test if the buffer extension works as designed") == 0, 2.52 + "value error for key: simple"); 2.53 + 2.54 + UCX_TEST_END 2.55 + fclose(f); 2.56 + 2.57 + unlink("test_ucx_map_store"); 2.58 +}
3.1 --- a/test/map_tests.h Thu Oct 04 14:08:31 2012 +0200 3.2 +++ b/test/map_tests.h Thu Oct 04 16:03:18 2012 +0200 3.3 @@ -18,6 +18,7 @@ 3.4 UCX_TEST_DECLARE(test_ucx_map_get) 3.5 UCX_TEST_DECLARE(test_ucx_map_iterator) 3.6 UCX_TEST_DECLARE(test_ucx_map_iterator_chain) 3.7 +UCX_TEST_DECLARE(test_ucx_map_store_load) 3.8 3.9 3.10 #ifdef __cplusplus
4.1 --- a/ucx/map.c Thu Oct 04 14:08:31 2012 +0200 4.2 +++ b/ucx/map.c Thu Oct 04 16:03:18 2012 +0200 4.3 @@ -189,3 +189,83 @@ 4.4 4.5 return 1; 4.6 } 4.7 + 4.8 +int ucx_map_load(UcxMap *map, FILE *f) { 4.9 + 4.10 + char c; int r, n; 4.11 + 4.12 + char *key, *value; 4.13 + 4.14 + while ((c = (char) fgetc(f)) > 0) { 4.15 + /* Discard leading spaces and comments */ 4.16 + if (c == ' ') continue; 4.17 + if (c == '#' || c == '!') { 4.18 + while ((c = (char) fgetc(f)) > 0) { 4.19 + if (c == '\n') break; 4.20 + } 4.21 + continue; 4.22 + } 4.23 + 4.24 + /* read into key buffer */ 4.25 + n = 16; 4.26 + key = malloc(n); 4.27 + r = 0; 4.28 + do { 4.29 + if (c == '=') break; 4.30 + if (r > n - 2) { 4.31 + n *= 2; 4.32 + key = realloc(key, n); 4.33 + } 4.34 + key[r] = c; 4.35 + r++; 4.36 + } while ((c = (char) fgetc(f)) > 0); 4.37 + if (c == 0) { 4.38 + free(key); 4.39 + return 1; 4.40 + } 4.41 + key[r] = 0; 4.42 + 4.43 + /* read into value buffer */ 4.44 + n = 64; 4.45 + value = malloc(n); 4.46 + r = 0; 4.47 + while ((c = (char) fgetc(f)) > 0) { 4.48 + if (c == '\n') break; 4.49 + if (r > n - 1) { 4.50 + n *= 2; 4.51 + value = realloc(value, n); 4.52 + } 4.53 + value[r] = c; 4.54 + r++; 4.55 + } 4.56 + value = realloc(value, r+1); 4.57 + value[r] = 0; 4.58 + 4.59 + ucx_map_cstr_put(map, key, value); 4.60 + free(key); 4.61 + } 4.62 + 4.63 + return 0; 4.64 +} 4.65 + 4.66 +int ucx_map_store(UcxMap *map, FILE *f) { 4.67 + UcxMapIterator iter = ucx_map_iterator(map); 4.68 + char *k, *v; 4.69 + sstr_t key, value; 4.70 + int written; 4.71 + 4.72 + UCX_MAP_FOREACH(v, iter) { 4.73 + k = (char*) iter.cur->key.data; 4.74 + key = sstr(k); value = sstr(v); 4.75 + 4.76 + written = 0; 4.77 + written += fwrite(key.ptr, 1, key.length, f); 4.78 + written += fwrite(" = ", 1, 3, f); 4.79 + written += fwrite(value.ptr, 1, value.length, f); 4.80 + written += fwrite("\n", 1, 1, f); 4.81 + 4.82 + if (written != key.length + value.length + 4) return 1; 4.83 + } 4.84 + 4.85 + return 0; 4.86 +}
5.1 --- a/ucx/map.h Thu Oct 04 14:08:31 2012 +0200 5.2 +++ b/ucx/map.h Thu Oct 04 16:03:18 2012 +0200 5.3 @@ -14,7 +14,7 @@ 5.4 #endif 5.5 5.6 #define UCX_MAP_FOREACH(elm,iter) \ 5.7 - for(elm;ucx_map_iter_next(&iter,(void*)&elm)==0;) 5.8 + for(;ucx_map_iter_next(&iter,(void*)&elm)==0;) 5.9 5.10 typedef struct UcxMap UcxMap; 5.11 typedef struct UcxKey UcxKey; 5.12 @@ -64,6 +64,15 @@ 5.13 5.14 int ucx_map_iter_next(UcxMapIterator *i, void **elm); 5.15 5.16 +/* use for string maps only, values are not encoded */ 5.17 +int ucx_map_load(UcxMap *map, FILE *f); 5.18 +int ucx_map_store(UcxMap *map, FILE *f); 5.19 + 5.20 +/* TODO: 5.21 +int ucx_map_load_enc(UcxMap *map, FILE *f, copy_func decoder, void* decdata); 5.22 +int ucx_map_store_enc(UcxMap *map, FILE *f, copy_func encoder, void* encdata); 5.23 + */ 5.24 + 5.25 #ifdef __cplusplus 5.26 } 5.27 #endif
6.1 --- a/ucx/string.h Thu Oct 04 14:08:31 2012 +0200 6.2 +++ b/ucx/string.h Thu Oct 04 16:03:18 2012 +0200 6.3 @@ -10,6 +10,7 @@ 6.4 6.5 #include <stddef.h> 6.6 6.7 +/* use macros for literals only */ 6.8 #define S(s) { s, sizeof(s)-1 } 6.9 #define ST(s) sstrn(s, sizeof(s)-1) 6.10
7.1 --- a/ucx/ucx.h Thu Oct 04 14:08:31 2012 +0200 7.2 +++ b/ucx/ucx.h Thu Oct 04 16:03:18 2012 +0200 7.3 @@ -17,9 +17,6 @@ 7.4 #define UCX_FOREACH(type,list,elem) \ 7.5 for (type elem = list ; elem != NULL ; elem = elem->next) 7.6 7.7 -/* source,data -> errno */ 7.8 -typedef int(*ucx_callback)(void*,void*); 7.9 - 7.10 /* element1,element2,custom data -> {-1,0,1} */ 7.11 typedef int(*cmp_func)(void*,void*,void*); 7.12