Sun, 14 Jul 2013 17:11:34 +0200
added properties load/store functions
test/main.c | file | annotate | diff | comparison | revisions | |
test/prop_tests.c | file | annotate | diff | comparison | revisions | |
test/prop_tests.h | file | annotate | diff | comparison | revisions | |
ucx/map.h | file | annotate | diff | comparison | revisions | |
ucx/properties.c | file | annotate | diff | comparison | revisions | |
ucx/properties.h | file | annotate | diff | comparison | revisions | |
ucx/string.c | file | annotate | diff | comparison | revisions | |
ucx/string.h | file | annotate | diff | comparison | revisions |
1.1 --- a/test/main.c Fri Jul 12 20:50:18 2013 +0200 1.2 +++ b/test/main.c Sun Jul 14 17:11:34 2013 +0200 1.3 @@ -176,6 +176,9 @@ 1.4 ucx_test_register(suite, test_ucx_prop_parse_multi); 1.5 ucx_test_register(suite, test_ucx_prop_parse_part); 1.6 ucx_test_register(suite, test_ucx_prop_parse_long); 1.7 + ucx_test_register(suite, test_ucx_prop_parse2map); 1.8 + ucx_test_register(suite, test_ucx_properties_load); 1.9 + ucx_test_register(suite, test_ucx_properties_store); 1.10 1.11 /* UcxBuffer Tests */ 1.12 ucx_test_register(suite, test_ucx_buffer_seektell);
2.1 --- a/test/prop_tests.c Fri Jul 12 20:50:18 2013 +0200 2.2 +++ b/test/prop_tests.c Sun Jul 14 17:11:34 2013 +0200 2.3 @@ -43,7 +43,7 @@ 2.4 } 2.5 2.6 UCX_TEST_IMPLEMENT(test_ucx_prop_parse) { 2.7 - char *tests[] = { 2.8 + const char *tests[] = { 2.9 "name = value\n", 2.10 "name=value\n", 2.11 "n=value\n", 2.12 @@ -56,7 +56,7 @@ 2.13 "name = value\n\n" 2.14 }; 2.15 2.16 - char *names[] = { 2.17 + const char *names[] = { 2.18 "name", 2.19 "name", 2.20 "n", 2.21 @@ -69,7 +69,7 @@ 2.22 "name" 2.23 }; 2.24 2.25 - char *values[] = { 2.26 + const char *values[] = { 2.27 "value", 2.28 "value", 2.29 "value", 2.30 @@ -90,13 +90,13 @@ 2.31 for(int i=0;i<10;i++) { 2.32 UcxPropParser *parser = ucx_prop_new(); 2.33 2.34 - ucx_prop_fill(parser, tests[i], strlen(tests[i])); 2.35 + ucx_prop_fill(parser, (char*)tests[i], strlen(tests[i])); 2.36 UCX_TEST_ASSERT(parser->buffer == tests[i], "fill failed"); 2.37 UCX_TEST_ASSERT(parser->buflen == strlen(tests[i]), "wrong buflen"); 2.38 2.39 int r = ucx_prop_parse(parser, &name, &value); 2.40 - sstr_t n = sstr(names[i]); 2.41 - sstr_t v = sstr(values[i]); 2.42 + sstr_t n = sstr((char*)names[i]); 2.43 + sstr_t v = sstr((char*)values[i]); 2.44 UCX_TEST_ASSERT(r == 1, "parse returned 0"); 2.45 UCX_TEST_ASSERT((!sstrcmp(name, n)), "wrong property name"); 2.46 UCX_TEST_ASSERT((!sstrcmp(value, v)), "wrong property value"); 2.47 @@ -114,7 +114,7 @@ 2.48 } 2.49 2.50 UCX_TEST_IMPLEMENT(test_ucx_prop_parse_multi) { 2.51 - char *names[] = { 2.52 + const char *names[] = { 2.53 "a", 2.54 "b", 2.55 "c", 2.56 @@ -125,7 +125,7 @@ 2.57 "key3" 2.58 }; 2.59 2.60 - char *values[] = { 2.61 + const char *values[] = { 2.62 "a value", 2.63 "b value", 2.64 "core", 2.65 @@ -136,7 +136,7 @@ 2.66 "value3" 2.67 }; 2.68 2.69 - char *str = "#\n" 2.70 + const char *str = "#\n" 2.71 "# properties\n" 2.72 "# contains key/value pairs\n" 2.73 "#\n" 2.74 @@ -157,15 +157,16 @@ 2.75 2.76 UCX_TEST_BEGIN 2.77 2.78 - ucx_prop_fill(parser, str, strlen(str)); 2.79 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.80 2.81 sstr_t name; 2.82 sstr_t value; 2.83 for(int i=0;i<8;i++) { 2.84 int r = ucx_prop_parse(parser, &name, &value); 2.85 UCX_TEST_ASSERT(r == 1, "parse returned 0"); 2.86 - UCX_TEST_ASSERT((!sstrcmp(name, sstr(names[i]))), "wrong name"); 2.87 - UCX_TEST_ASSERT((!sstrcmp(value, sstr(values[i]))), "wrong value"); 2.88 + UCX_TEST_ASSERT((!sstrcmp(name, sstr((char*)names[i]))), "wrong name"); 2.89 + UCX_TEST_ASSERT((!sstrcmp(value, sstr((char*)values[i]))), 2.90 + "wrong value"); 2.91 } 2.92 int r = ucx_prop_parse(parser, &name, &value); 2.93 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.94 @@ -177,7 +178,7 @@ 2.95 2.96 UCX_TEST_IMPLEMENT(test_ucx_prop_parse_part) { 2.97 UcxPropParser *parser = ucx_prop_new(); 2.98 - char *str; 2.99 + const char *str; 2.100 int r; 2.101 sstr_t name; 2.102 sstr_t value; 2.103 @@ -185,100 +186,100 @@ 2.104 UCX_TEST_BEGIN 2.105 2.106 str = ""; 2.107 - ucx_prop_fill(parser, str, strlen(str)); 2.108 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.109 r = ucx_prop_parse(parser, &name, &value); 2.110 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.111 2.112 str = " \n"; 2.113 - ucx_prop_fill(parser, str, strlen(str)); 2.114 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.115 r = ucx_prop_parse(parser, &name, &value); 2.116 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.117 2.118 str = "name"; 2.119 - ucx_prop_fill(parser, str, strlen(str)); 2.120 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.121 r = ucx_prop_parse(parser, &name, &value); 2.122 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.123 2.124 str = " "; 2.125 - ucx_prop_fill(parser, str, strlen(str)); 2.126 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.127 r = ucx_prop_parse(parser, &name, &value); 2.128 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.129 2.130 str = "= "; 2.131 - ucx_prop_fill(parser, str, strlen(str)); 2.132 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.133 r = ucx_prop_parse(parser, &name, &value); 2.134 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.135 2.136 str = "value"; 2.137 - ucx_prop_fill(parser, str, strlen(str)); 2.138 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.139 r = ucx_prop_parse(parser, &name, &value); 2.140 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.141 2.142 str = "\n"; 2.143 - ucx_prop_fill(parser, str, strlen(str)); 2.144 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.145 r = ucx_prop_parse(parser, &name, &value); 2.146 UCX_TEST_ASSERT(r == 1, "parse returned 0"); 2.147 - UCX_TEST_ASSERT((!sstrcmp(name, sstr("name"))), "wrong name"); 2.148 - UCX_TEST_ASSERT((!sstrcmp(value, sstr("value"))), "wrong value"); 2.149 + UCX_TEST_ASSERT((!sstrcmp(name, sstr((char*)"name"))), "wrong name"); 2.150 + UCX_TEST_ASSERT((!sstrcmp(value, sstr((char*)"value"))), "wrong value"); 2.151 2.152 // second round 2.153 str = "#comment\n"; 2.154 - ucx_prop_fill(parser, str, strlen(str)); 2.155 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.156 r = ucx_prop_parse(parser, &name, &value); 2.157 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.158 2.159 str = "#comment\nname = "; 2.160 - ucx_prop_fill(parser, str, strlen(str)); 2.161 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.162 r = ucx_prop_parse(parser, &name, &value); 2.163 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.164 2.165 str = "value\na = b\n"; 2.166 - ucx_prop_fill(parser, str, strlen(str)); 2.167 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.168 r = ucx_prop_parse(parser, &name, &value); 2.169 UCX_TEST_ASSERT(r == 1, "parse returned 0"); 2.170 - UCX_TEST_ASSERT((!sstrcmp(name, sstr("name"))), "wrong name"); 2.171 - UCX_TEST_ASSERT((!sstrcmp(value, sstr("value"))), "wrong value"); 2.172 + UCX_TEST_ASSERT((!sstrcmp(name, sstr((char*)"name"))), "wrong name"); 2.173 + UCX_TEST_ASSERT((!sstrcmp(value, sstr((char*)"value"))), "wrong value"); 2.174 2.175 r = ucx_prop_parse(parser, &name, &value); 2.176 UCX_TEST_ASSERT(r == 1, "parse returned 0"); 2.177 - UCX_TEST_ASSERT((!sstrcmp(name, sstr("a"))), "wrong name"); 2.178 - UCX_TEST_ASSERT((!sstrcmp(value, sstr("b"))), "wrong value"); 2.179 + UCX_TEST_ASSERT((!sstrcmp(name, sstr((char*)"a"))), "wrong name"); 2.180 + UCX_TEST_ASSERT((!sstrcmp(value, sstr((char*)"b"))), "wrong value"); 2.181 2.182 str = "# comment\n#\n#\ntests = "; 2.183 - ucx_prop_fill(parser, str, strlen(str)); 2.184 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.185 r = ucx_prop_parse(parser, &name, &value); 2.186 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.187 2.188 str = "test1 "; 2.189 - ucx_prop_fill(parser, str, strlen(str)); 2.190 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.191 r = ucx_prop_parse(parser, &name, &value); 2.192 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.193 2.194 str = "test2 test3 test4\n"; 2.195 - sstr_t testv = sstr("test1 test2 test3 test4"); 2.196 - ucx_prop_fill(parser, str, strlen(str)); 2.197 + sstr_t testv = sstr((char*)"test1 test2 test3 test4"); 2.198 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.199 r = ucx_prop_parse(parser, &name, &value); 2.200 UCX_TEST_ASSERT(r == 1, "parse returned 0"); 2.201 - UCX_TEST_ASSERT((!sstrcmp(name, sstr("tests"))), "wrong name"); 2.202 + UCX_TEST_ASSERT((!sstrcmp(name, sstr((char*)"tests"))), "wrong name"); 2.203 UCX_TEST_ASSERT((!sstrcmp(value, testv)), "wrong value"); 2.204 2.205 // test if parse finds a name/value after a tmp comment 2.206 str = "# just a comment"; 2.207 - ucx_prop_fill(parser, str, strlen(str)); 2.208 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.209 r = ucx_prop_parse(parser, &name, &value); 2.210 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.211 2.212 str = " in 3"; 2.213 - ucx_prop_fill(parser, str, strlen(str)); 2.214 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.215 r = ucx_prop_parse(parser, &name, &value); 2.216 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.217 2.218 str = " parts\na = 1\n"; 2.219 - ucx_prop_fill(parser, str, strlen(str)); 2.220 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.221 r = ucx_prop_parse(parser, &name, &value); 2.222 UCX_TEST_ASSERT(r == 1, "parse returned 0"); 2.223 - UCX_TEST_ASSERT((!sstrcmp(name, sstr("a"))), "wrong name"); 2.224 - UCX_TEST_ASSERT((!sstrcmp(value, sstr("1"))), "wrong value"); 2.225 + UCX_TEST_ASSERT((!sstrcmp(name, sstr((char*)"a"))), "wrong name"); 2.226 + UCX_TEST_ASSERT((!sstrcmp(value, sstr((char*)"1"))), "wrong value"); 2.227 2.228 UCX_TEST_END 2.229 2.230 @@ -320,8 +321,8 @@ 2.231 r = ucx_prop_parse(parser, &name, &value); 2.232 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.233 2.234 - char *str = " = "; 2.235 - ucx_prop_fill(parser, str, strlen(str)); 2.236 + const char *str = " = "; 2.237 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.238 r = ucx_prop_parse(parser, &name, &value); 2.239 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.240 2.241 @@ -338,7 +339,7 @@ 2.242 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.243 2.244 str = "\n#comment\nkey = value\n"; 2.245 - ucx_prop_fill(parser, str, strlen(str)); 2.246 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.247 r = ucx_prop_parse(parser, &name, &value); 2.248 sstr_t n = sstrn(long_name, name_len); 2.249 sstr_t v = sstrn(long_value, value_len); 2.250 @@ -348,8 +349,8 @@ 2.251 2.252 r = ucx_prop_parse(parser, &name, &value); 2.253 UCX_TEST_ASSERT(r == 1, "parse returned 0"); 2.254 - UCX_TEST_ASSERT((!sstrcmp(name, sstr("key"))), "wrong name"); 2.255 - UCX_TEST_ASSERT((!sstrcmp(value, sstr("value"))), "wrong value"); 2.256 + UCX_TEST_ASSERT((!sstrcmp(name, sstr((char*)"key"))), "wrong name"); 2.257 + UCX_TEST_ASSERT((!sstrcmp(value, sstr((char*)"value"))), "wrong value"); 2.258 2.259 r = ucx_prop_parse(parser, &name, &value); 2.260 UCX_TEST_ASSERT(r == 0, "parse returned 1"); 2.261 @@ -360,3 +361,182 @@ 2.262 free(long_value); 2.263 ucx_prop_free(parser); 2.264 } 2.265 + 2.266 +UCX_TEST_IMPLEMENT(test_ucx_prop_parse2map) { 2.267 + UcxMap *map = ucx_map_new(16); 2.268 + UcxPropParser *parser = ucx_prop_new(); 2.269 + 2.270 + UCX_TEST_BEGIN 2.271 + 2.272 + const char *str = "key1 = value1\nkey2 = value2\n\n#comment\n\nkey3 = value3\n"; 2.273 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.274 + 2.275 + int r = ucx_prop_parse2map(parser, map); 2.276 + 2.277 + UCX_TEST_ASSERT(r == 0, "parse2map failed"); 2.278 + UCX_TEST_ASSERT(map->count == 3, "wrong number of properties"); 2.279 + 2.280 + char *v1 = (char*)ucx_map_cstr_get(map, "key1"); 2.281 + char *v2 = (char*)ucx_map_cstr_get(map, "key2"); 2.282 + char *v3 = (char*)ucx_map_cstr_get(map, "key3"); 2.283 + 2.284 + UCX_TEST_ASSERT(v1, "value for key1 not found"); 2.285 + UCX_TEST_ASSERT(v2, "value for key2 not found"); 2.286 + UCX_TEST_ASSERT(v3, "value for key3 not found"); 2.287 + 2.288 + UCX_TEST_ASSERT((!strcmp(v1, "value1")), "wrong value for key1"); 2.289 + UCX_TEST_ASSERT((!strcmp(v2, "value2")), "wrong value for key2"); 2.290 + UCX_TEST_ASSERT((!strcmp(v3, "value3")), "wrong value for key3"); 2.291 + 2.292 + // second test 2.293 + ucx_map_free(map); 2.294 + free(v1); 2.295 + free(v2); 2.296 + free(v3); 2.297 + map = ucx_map_new(16); 2.298 + 2.299 + str = "\n#comment\n"; 2.300 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.301 + 2.302 + r = ucx_prop_parse2map(parser, map); 2.303 + UCX_TEST_ASSERT(r == 0, "parse2map failed"); 2.304 + UCX_TEST_ASSERT(map->count == 0, "wrong number of properties"); 2.305 + 2.306 + str = "key1 = value1\nsyntax error line\n"; 2.307 + ucx_prop_fill(parser, (char*)str, strlen(str)); 2.308 + 2.309 + r = ucx_prop_parse2map(parser, map); 2.310 + UCX_TEST_ASSERT(r == 1, "parse2map should return 1"); 2.311 + UCX_TEST_ASSERT(map->count == 1, "wrong number of properties"); 2.312 + 2.313 + char *v = (char*)ucx_map_cstr_get(map, "key1"); 2.314 + UCX_TEST_ASSERT((!strcmp(v, "value1")), "wrong value"); 2.315 + 2.316 + UCX_TEST_END 2.317 + 2.318 + ucx_prop_free(parser); 2.319 +} 2.320 + 2.321 +UCX_TEST_IMPLEMENT(test_ucx_properties_load) { 2.322 + UCX_TEST_BEGIN 2.323 + FILE *f = tmpfile(); 2.324 + UCX_TEST_ASSERT(f, "test file cannot be opened, test aborted"); 2.325 + 2.326 + fprintf(f, "# properties file\n\nkey1 = value1\nkey2 = value2\n"); 2.327 + fprintf(f, "\n\nkey3 = value3\n\n"); 2.328 + 2.329 + size_t name_len = 512; 2.330 + char *long_name = (char*)malloc(name_len); 2.331 + memset(long_name, 'k', 512); 2.332 + 2.333 + size_t value_len = 2048; 2.334 + char *long_value = (char*)malloc(value_len); 2.335 + memset(long_value, 'v', 2048); 2.336 + 2.337 + fwrite(long_name, 1, name_len, f); 2.338 + fprintf(f, " = "); 2.339 + fwrite(long_value, 1, value_len, f); 2.340 + fprintf(f, " \n"); 2.341 + 2.342 + fprintf(f, "\n\n\n\nlast_key = property value\n"); 2.343 + 2.344 + fflush(f); 2.345 + fseek(f, 0, SEEK_SET); 2.346 + 2.347 + UcxMap *map = ucx_map_new(8); 2.348 + int r = ucx_properties_load(map, f); 2.349 + 2.350 + UCX_TEST_ASSERT(r == 0, "ucx_properties_load failed"); 2.351 + UCX_TEST_ASSERT(map->count == 5, "wrong number of properties"); 2.352 + 2.353 + char *v1 = (char*)ucx_map_cstr_get(map, "key1"); 2.354 + char *v2 = (char*)ucx_map_cstr_get(map, "key2"); 2.355 + char *v3 = (char*)ucx_map_cstr_get(map, "key3"); 2.356 + char *lv = (char*)ucx_map_sstr_get(map, sstrn(long_name, name_len)); 2.357 + char *lk = (char*)ucx_map_cstr_get(map, "last_key"); 2.358 + 2.359 + UCX_TEST_ASSERT(v1, "value for key1 not found"); 2.360 + UCX_TEST_ASSERT(v2, "value for key2 not found"); 2.361 + UCX_TEST_ASSERT(v3, "value for key3 not found"); 2.362 + UCX_TEST_ASSERT(lv, "value for long key not found"); 2.363 + UCX_TEST_ASSERT(lk, "value for last_key not found"); 2.364 + 2.365 + UCX_TEST_ASSERT((!strcmp(v1, "value1")), "wrong value for key1"); 2.366 + UCX_TEST_ASSERT((!strcmp(v2, "value2")), "wrong value for key2"); 2.367 + UCX_TEST_ASSERT((!strcmp(v3, "value3")), "wrong value for key3"); 2.368 + sstr_t long1 = sstrn(long_value, value_len); 2.369 + sstr_t long2 = sstr(lv); 2.370 + UCX_TEST_ASSERT((!sstrcmp(long1, long2)), "wrong value for long key"); 2.371 + UCX_TEST_ASSERT(!strcmp(lk, "property value"), "wrong value for last_key"); 2.372 + 2.373 + free(v1); 2.374 + free(v2); 2.375 + free(v3); 2.376 + free(lv); 2.377 + free(lk); 2.378 + ucx_map_free(map); 2.379 + fclose(f); 2.380 + 2.381 + UCX_TEST_END 2.382 +} 2.383 + 2.384 +UCX_TEST_IMPLEMENT(test_ucx_properties_store) { 2.385 + UcxMap *map1 = ucx_map_new(16); 2.386 + ucx_map_cstr_put(map1, "key1", "value1"); 2.387 + ucx_map_cstr_put(map1, "key2", "value2"); 2.388 + ucx_map_cstr_put(map1, "key3", "value3"); 2.389 + ucx_map_cstr_put(map1, "key4", "value4"); 2.390 + ucx_map_cstr_put(map1, "property.key1", "some value 1"); 2.391 + ucx_map_cstr_put(map1, "property.key2", "some value 2"); 2.392 + ucx_map_cstr_put(map1, "property.key3", "some value 3"); 2.393 + ucx_map_cstr_put(map1, "property.key4", "some value 4"); 2.394 + 2.395 + UCX_TEST_BEGIN 2.396 + 2.397 + FILE *f = tmpfile(); 2.398 + fprintf(f, "#\n# test property file\n#\n#\n"); 2.399 + ucx_properties_store(map1, f); 2.400 + 2.401 + fflush(f); 2.402 + fseek(f, 0, SEEK_SET); 2.403 + UcxMap *map2 = ucx_map_new(16); 2.404 + ucx_properties_load(map2, f); 2.405 + 2.406 + UCX_TEST_ASSERT(map2->count == 8, "wrong number of properties in map2"); 2.407 + 2.408 + char *v1 = (char*)ucx_map_cstr_get(map2, "key1"); 2.409 + char *v2 = (char*)ucx_map_cstr_get(map2, "key2"); 2.410 + char *v3 = (char*)ucx_map_cstr_get(map2, "key3"); 2.411 + char *v4 = (char*)ucx_map_cstr_get(map2, "key4"); 2.412 + char *v5 = (char*)ucx_map_cstr_get(map2, "property.key1"); 2.413 + char *v6 = (char*)ucx_map_cstr_get(map2, "property.key2"); 2.414 + char *v7 = (char*)ucx_map_cstr_get(map2, "property.key3"); 2.415 + char *v8 = (char*)ucx_map_cstr_get(map2, "property.key4"); 2.416 + 2.417 + UCX_TEST_ASSERT(v1 && v2 && v3 && v4 && v5 && v6 && v7 && v8, 2.418 + "missing values"); 2.419 + 2.420 + UCX_TEST_ASSERT((!strcmp(v1, "value1")), "wrong value 1"); 2.421 + UCX_TEST_ASSERT((!strcmp(v2, "value2")), "wrong value 2"); 2.422 + UCX_TEST_ASSERT((!strcmp(v3, "value3")), "wrong value 3"); 2.423 + UCX_TEST_ASSERT((!strcmp(v4, "value4")), "wrong value 4"); 2.424 + UCX_TEST_ASSERT((!strcmp(v5, "some value 1")), "wrong value 5"); 2.425 + UCX_TEST_ASSERT((!strcmp(v6, "some value 2")), "wrong value 6"); 2.426 + UCX_TEST_ASSERT((!strcmp(v7, "some value 3")), "wrong value 7"); 2.427 + UCX_TEST_ASSERT((!strcmp(v8, "some value 4")), "wrong value 8"); 2.428 + 2.429 + free(v1); 2.430 + free(v2); 2.431 + free(v3); 2.432 + free(v4); 2.433 + free(v5); 2.434 + free(v6); 2.435 + free(v7); 2.436 + free(v8); 2.437 + ucx_map_free(map2); 2.438 + fclose(f); 2.439 + 2.440 + UCX_TEST_END 2.441 + 2.442 + ucx_map_free(map1); 2.443 +}
3.1 --- a/test/prop_tests.h Fri Jul 12 20:50:18 2013 +0200 3.2 +++ b/test/prop_tests.h Sun Jul 14 17:11:34 2013 +0200 3.3 @@ -41,6 +41,9 @@ 3.4 UCX_TEST_DECLARE(test_ucx_prop_parse_multi); 3.5 UCX_TEST_DECLARE(test_ucx_prop_parse_part); 3.6 UCX_TEST_DECLARE(test_ucx_prop_parse_long); 3.7 +UCX_TEST_DECLARE(test_ucx_prop_parse2map); 3.8 +UCX_TEST_DECLARE(test_ucx_properties_load); 3.9 +UCX_TEST_DECLARE(test_ucx_properties_store); 3.10 3.11 #ifdef __cplusplus 3.12 }
4.1 --- a/ucx/map.h Fri Jul 12 20:50:18 2013 +0200 4.2 +++ b/ucx/map.h Sun Jul 14 17:11:34 2013 +0200 4.3 @@ -94,11 +94,11 @@ 4.4 void* ucx_map_remove(UcxMap *map, UcxKey key); 4.5 4.6 #define ucx_map_sstr_put(m, s, d) \ 4.7 - ucx_map_put(m, ucx_key(s.ptr, s.length), d) 4.8 + ucx_map_put(m, ucx_key(s.ptr, s.length), (void*)d) 4.9 #define ucx_map_cstr_put(m, s, d) \ 4.10 - ucx_map_put(m, ucx_key((void*)s, strlen(s)), d) 4.11 + ucx_map_put(m, ucx_key((void*)s, strlen(s)), (void*)d) 4.12 #define ucx_map_int_put(m, i, d) \ 4.13 - ucx_map_put(m, ucx_key((void*)&i, sizeof(i)), d) 4.14 + ucx_map_put(m, ucx_key((void*)&i, sizeof(i)), (void*)d) 4.15 4.16 #define ucx_map_sstr_get(m, s) \ 4.17 ucx_map_get(m, ucx_key(s.ptr, s.length))
5.1 --- a/ucx/properties.c Fri Jul 12 20:50:18 2013 +0200 5.2 +++ b/ucx/properties.c Sun Jul 14 17:11:34 2013 +0200 5.3 @@ -45,6 +45,7 @@ 5.4 parser->tmp = NULL; 5.5 parser->tmplen = 0; 5.6 parser->tmpcap = 0; 5.7 + parser->error = 0; 5.8 parser->delimiter = '='; 5.9 parser->comment1 = '#'; 5.10 parser->comment2 = 0; 5.11 @@ -106,7 +107,7 @@ 5.12 parser->pos = newlen; 5.13 5.14 /* 5.15 - * if ret == 0 the tmp buffer contained just space or comment 5.16 + * if ret == 0 the tmp buffer contained just space or a comment 5.17 * we parse again with the original buffer to get a name/value 5.18 * or a new tmp buffer 5.19 */ 5.20 @@ -126,10 +127,7 @@ 5.21 char delimiter = parser->delimiter; 5.22 5.23 // get one line and parse it 5.24 - while(1) { 5.25 - if(parser->pos >= parser->buflen) { 5.26 - return 0; 5.27 - } 5.28 + while(parser->pos < parser->buflen) { 5.29 char *buf = parser->buffer + parser->pos; 5.30 size_t len = parser->buflen - parser->pos; 5.31 5.32 @@ -160,7 +158,7 @@ 5.33 } 5.34 5.35 if(c != '\n') { 5.36 - // we have not enough data for a line 5.37 + // we don't have enough data for a line 5.38 // store remaining bytes in temporary buffer for next round 5.39 parser->tmpcap = len + 128; 5.40 parser->tmp = (char*)malloc(parser->tmpcap); 5.41 @@ -174,31 +172,96 @@ 5.42 if(delimiter_index == 0) { 5.43 line = sstrtrim(line); 5.44 if(line.length != 0) { 5.45 - // syntax error 5.46 - // TODO 5.47 + parser->error = 1; 5.48 } 5.49 - parser->pos += i + 1; 5.50 - continue; 5.51 + } else { 5.52 + sstr_t n = sstrn(buf, delimiter_index); 5.53 + sstr_t v = sstrn(buf+delimiter_index+1, i-delimiter_index-1); 5.54 + n = sstrtrim(n); 5.55 + v = sstrtrim(v); 5.56 + if(n.length != 0 || v.length != 0) { 5.57 + *name = n; 5.58 + *value = v; 5.59 + parser->pos += i + 1; 5.60 + return 1; 5.61 + } else { 5.62 + parser->error = 1; 5.63 + } 5.64 } 5.65 5.66 - sstr_t n = sstrn(buf, delimiter_index); 5.67 - sstr_t v = sstrn(buf + delimiter_index + 1, i - delimiter_index - 1); 5.68 - n = sstrtrim(n); 5.69 - v = sstrtrim(v); 5.70 - if(n.length == 0 || v.length == 0) { 5.71 - // syntax error 5.72 - // TODO 5.73 - parser->pos += i + 1; 5.74 - continue; 5.75 - } 5.76 - 5.77 - *name = n; 5.78 - *value = v; 5.79 - 5.80 parser->pos += i + 1; 5.81 - break; 5.82 } 5.83 5.84 - return 1; 5.85 + return 0; 5.86 } 5.87 5.88 +int ucx_prop_parse2map(UcxPropParser *parser, UcxMap *map) { 5.89 + sstr_t name; 5.90 + sstr_t value; 5.91 + while(ucx_prop_parse(parser, &name, &value)) { 5.92 + name = sstrdup_alloc(map->allocator, name); 5.93 + if(!name.ptr) { 5.94 + return 1; 5.95 + } 5.96 + value = sstrdup_alloc(map->allocator, value); 5.97 + if(!value.ptr) { 5.98 + map->allocator->free(map->allocator->pool, value.ptr); 5.99 + return 1; 5.100 + } 5.101 + if(ucx_map_sstr_put(map, name, value.ptr)) { 5.102 + map->allocator->free(map->allocator->pool, name.ptr); 5.103 + map->allocator->free(map->allocator->pool, value.ptr); 5.104 + return 1; 5.105 + } 5.106 + } 5.107 + if(parser->error) { 5.108 + return 1; 5.109 + } else { 5.110 + return 0; 5.111 + } 5.112 +} 5.113 + 5.114 +int ucx_properties_load(UcxMap *map, FILE *file) { 5.115 + UcxPropParser *parser = ucx_prop_new(); 5.116 + if(!parser || !map || !file) { 5.117 + return 1; 5.118 + } 5.119 + 5.120 + int error = 0; 5.121 + size_t r; 5.122 + char buf[1024]; 5.123 + while((r = fread(buf, 1, 1024, file)) != 0) { 5.124 + ucx_prop_fill(parser, buf, r); 5.125 + if(ucx_prop_parse2map(parser, map)) { 5.126 + error = 1; 5.127 + break; 5.128 + } 5.129 + } 5.130 + 5.131 + ucx_prop_free(parser); 5.132 + return error; 5.133 +} 5.134 + 5.135 +int ucx_properties_store(UcxMap *map, FILE *file) { 5.136 + UcxMapIterator iter = ucx_map_iterator(map); 5.137 + char *k, *v; 5.138 + sstr_t key, value; 5.139 + size_t written; 5.140 + 5.141 + UCX_MAP_FOREACH(v, iter) { 5.142 + k = (char*) iter.cur->key.data; 5.143 + key = sstrn(k, iter.cur->key.len); 5.144 + value = sstr(v); 5.145 + 5.146 + written = 0; 5.147 + written += fwrite(key.ptr, 1, key.length, file); 5.148 + written += fwrite(" = ", 1, 3, file); 5.149 + written += fwrite(value.ptr, 1, value.length, file); 5.150 + written += fwrite("\n", 1, 1, file); 5.151 + 5.152 + if (written != key.length + value.length + 4) return 1; 5.153 + } 5.154 + 5.155 + return 0; 5.156 +} 5.157 +
6.1 --- a/ucx/properties.h Fri Jul 12 20:50:18 2013 +0200 6.2 +++ b/ucx/properties.h Sun Jul 14 17:11:34 2013 +0200 6.3 @@ -43,6 +43,7 @@ 6.4 char *tmp; 6.5 size_t tmplen; 6.6 size_t tmpcap; 6.7 + int error; 6.8 char delimiter; 6.9 char comment1; 6.10 char comment2; 6.11 @@ -54,6 +55,10 @@ 6.12 void ucx_prop_free(UcxPropParser *parser); 6.13 void ucx_prop_fill(UcxPropParser *parser, char *buf, size_t len); 6.14 int ucx_prop_parse(UcxPropParser *parser, sstr_t *name, sstr_t *value); 6.15 +int ucx_prop_parse2map(UcxPropParser *parser, UcxMap *map); 6.16 + 6.17 +int ucx_properties_load(UcxMap *map, FILE *file); 6.18 +int ucx_properties_store(UcxMap *map, FILE *file); 6.19 6.20 #ifdef __cplusplus 6.21 }
7.1 --- a/ucx/string.c Fri Jul 12 20:50:18 2013 +0200 7.2 +++ b/ucx/string.c Sun Jul 14 17:11:34 2013 +0200 7.3 @@ -31,6 +31,7 @@ 7.4 #include <stdarg.h> 7.5 7.6 #include "string.h" 7.7 +#include "allocator.h" 7.8 7.9 sstr_t sstr(char *s) { 7.10 sstr_t string; 7.11 @@ -180,16 +181,30 @@ 7.12 sstr_t sstrdup(sstr_t s) { 7.13 sstr_t newstring; 7.14 newstring.ptr = (char*) malloc(s.length + 1); 7.15 - newstring.length = 0; 7.16 if (newstring.ptr) { 7.17 newstring.length = s.length; 7.18 newstring.ptr[newstring.length] = 0; 7.19 - 7.20 + 7.21 memcpy(newstring.ptr, s.ptr, s.length); 7.22 } else { 7.23 newstring.length = 0; 7.24 } 7.25 + 7.26 + return newstring; 7.27 +} 7.28 7.29 +sstr_t sstrdup_alloc(UcxAllocator *allocator, sstr_t s) { 7.30 + sstr_t newstring; 7.31 + newstring.ptr = (char*)allocator->malloc(allocator->pool, s.length + 1); 7.32 + if (newstring.ptr) { 7.33 + newstring.length = s.length; 7.34 + newstring.ptr[newstring.length] = 0; 7.35 + 7.36 + memcpy(newstring.ptr, s.ptr, s.length); 7.37 + } else { 7.38 + newstring.length = 0; 7.39 + } 7.40 + 7.41 return newstring; 7.42 } 7.43
8.1 --- a/ucx/string.h Fri Jul 12 20:50:18 2013 +0200 8.2 +++ b/ucx/string.h Sun Jul 14 17:11:34 2013 +0200 8.3 @@ -30,6 +30,7 @@ 8.4 #define _SSTRING_H 8.5 8.6 #include "ucx.h" 8.7 +#include "allocator.h" 8.8 #include <stddef.h> 8.9 8.10 /* use macros for literals only */ 8.11 @@ -117,6 +118,7 @@ 8.12 int sstrcmp(sstr_t s1, sstr_t s2); 8.13 8.14 sstr_t sstrdup(sstr_t s); 8.15 +sstr_t sstrdup_alloc(UcxAllocator *allocator, sstr_t s); 8.16 8.17 sstr_t sstrtrim(sstr_t string); 8.18