From 2041efe5b61d0f2fa9383bff16f75d3e0540f8e9 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Thu, 25 Sep 2008 17:29:00 +0200 Subject: [PATCH] more on config_wordlist * universal replace function * tests * missing declarations --- src/backend/config.h | 6 +++ src/backend/config_typed.c | 47 ++++++++++++++++++ src/backend/config_wordlist.c | 87 +++++++++++++++++++++++++++++++++- tests/22config_highlevel.tests | 51 ++++++++++++++++++++ tests/backend/test-config.c | 44 +++++++++++++++++ 5 files changed, 233 insertions(+), 2 deletions(-) diff --git a/src/backend/config.h b/src/backend/config.h index a603c2cbf..5f711ae0e 100644 --- a/src/backend/config.h +++ b/src/backend/config.h @@ -230,6 +230,12 @@ LUMIERA_CONFIG_TYPES const char* lumiera_config_wordlist_get_nth (const char* key, unsigned nth); +int +lumiera_config_wordlist_find (const char* key, const char* value); + +const char* +lumiera_config_wordlist_replace (const char* key, const char* value, const char* subst1, const char* subst2); + // * {{{ lumiera_config_TYPE_set (const char* key, TYPE*value, const char* fmt) }}} // Highlevel interface for different types, fmt is a printf format specifier for the desired format, when NULL, defaults apply. /** diff --git a/src/backend/config_typed.c b/src/backend/config_typed.c index ae490ff2b..aec8bbc68 100644 --- a/src/backend/config_typed.c +++ b/src/backend/config_typed.c @@ -228,6 +228,53 @@ lumiera_config_string_set (const char* key, const char** value) } +/** + * Wordlist + * words delimited by any of " \t,;" + */ + +const char* +lumiera_config_wordlist_get (const char* key, const char** value) +{ + TRACE (config_typed, "KEY %s", key); + + const char* raw_value = *value = NULL; + + LUMIERA_RDLOCK_SECTION (config_typed, &lumiera_global_config->lock) + { + if (lumiera_config_get (key, &raw_value)) + { + if (raw_value) + { + *value = raw_value; + } + else + LUMIERA_ERROR_SET (config, CONFIG_NO_ENTRY); + + TODO ("remove the ERROR_SET because config_get sets it already? also in all other getters in this file"); + } + } + + return *value; +} + + +LumieraConfigitem +lumiera_config_wordlist_set (const char* key, const char** value) +{ + TRACE (config_typed); + + LumieraConfigitem item = NULL; + + LUMIERA_WRLOCK_SECTION (config_typed, &lumiera_global_config->lock) + { + const char* fmt = "= %s"; TODO ("use the config system (config.format*...) to deduce the desired format for this key"); + item = lumiera_config_set (key, lumiera_tmpbuf_snprintf (SIZE_MAX, fmt, *value)); + } + + return item; +} + /** * Word diff --git a/src/backend/config_wordlist.c b/src/backend/config_wordlist.c index 3bcbf1ca8..cbaa68d86 100644 --- a/src/backend/config_wordlist.c +++ b/src/backend/config_wordlist.c @@ -28,6 +28,7 @@ #include "backend/config.h" //TODO: internal/static forward declarations// +extern LumieraConfig lumiera_global_config; //TODO: System includes// @@ -61,15 +62,91 @@ lumiera_config_wordlist_get_nth (const char* key, unsigned nth) return lumiera_tmpbuf_strndup (value, len); } -#if 0 + int lumiera_config_wordlist_find (const char* key, const char* value) { + const char* itr; + size_t vlen = strlen (value); + size_t len; + + if (!lumiera_config_wordlist_get (key, &itr)) + return -1; + + for (int idx = 0; *itr; itr += len, ++idx) + { + itr += strspn (itr, " \t,;"); + len = strcspn (itr, " \t,;"); + + if (len == vlen && !strncmp (itr, value, vlen)) + return idx; + } + + return -1; } +const char* +lumiera_config_wordlist_replace (const char* key, const char* value, const char* subst1, const char* subst2) +{ + const char* wordlist; + const char* str = NULL; + size_t vlen = strlen (value); + size_t len; + + LUMIERA_WRLOCK_SECTION (config_typed, &lumiera_global_config->lock) + { + if (lumiera_config_get (key, &wordlist)) + { + const char* start = wordlist + strspn (wordlist, " \t,;"); + + for (const char* itr = start; *itr; itr += len) + { + const char* left_end = itr; + itr += strspn (itr, " \t,;"); + len = strcspn (itr, " \t,;"); + + if (len == vlen && !strncmp (itr, value, vlen)) + { + TODO ("figure delimiter from original string out"); + const char* delim = " "; + + /* step over the word */ + itr += len; + itr += strspn (itr, " \t,;"); + + /* getting the delimiters right for the corner cases looks ugly, want to refactor it? just do it */ + str = lumiera_tmpbuf_snprintf (SIZE_MAX, + "%.*s%.*s%s%s%s%s%s%s", + start - wordlist, wordlist, + left_end - start, start, + (left_end - start && subst1 && *subst1) ? delim : "", + (subst1 && *subst1) ? subst1 : "", + ((left_end - start || (subst1 && *subst1)) && subst2 && *subst2) ? delim : "", + (subst2 && *subst2) ? subst2 : "", + ((left_end - start || (subst1 && *subst1) || (subst2 && *subst2)) && *itr) ? delim : "", + itr + ); + + if (!lumiera_config_set (key, lumiera_tmpbuf_snprintf (SIZE_MAX, "=%s", str))) + str = NULL; + + break; + } + } + } + } + + return str; +} + + + +#if 0 + + LumieraConfigitem -lumiera_config_wordlist_set_nth (const char* key, const char** value, unsigned nth) +lumiera_config_wordlist_remove_nth (const char* key, const char** value, unsigned nth) { } @@ -78,6 +155,12 @@ lumiera_config_wordlist_append (const char* key, const char** value, unsigned nt { } +LumieraConfigitem +lumiera_config_wordlist_preprend (const char* key, const char** value, unsigned nth) +{ +} + + LumieraConfigitem lumiera_config_wordlist_add (const char* key, const char** value, unsigned nth) { diff --git a/tests/22config_highlevel.tests b/tests/22config_highlevel.tests index 0349fa8fe..e2400c6ff 100644 --- a/tests/22config_highlevel.tests +++ b/tests/22config_highlevel.tests @@ -151,3 +151,54 @@ TEST "wordlist get middle" wordlist_get_nth 'foo.bar' 'baz barf, gnarf' 1 << END out: 'barf' END +TEST "wordlist find, non existing" wordlist_find 'foo.bar' 'baz barf, gnarf' blah << END +out: '-1' +END + +TEST "wordlist find, first" wordlist_find 'foo.bar' 'baz barf, gnarf' baz << END +out: '0' +END + +TEST "wordlist find, middle" wordlist_find 'foo.bar' 'baz barf, gnarf' barf << END +out: '1' +END + +TEST "wordlist find, last" wordlist_find 'foo.bar' 'baz barf, gnarf' gnarf << END +out: '2' +END + +TEST "wordlist replace, middle, insert after" wordlist_replace 'foo.bar' 'baz barf gnarf' barf barf foof << END +out: ' baz barf foof gnarf' +END + +TEST "wordlist replace, middle, insert before" wordlist_replace 'foo.bar' 'baz barf gnarf' barf foof barf << END +out: ' baz foof barf gnarf' +END + +TEST "wordlist replace, middle, remove" wordlist_replace 'foo.bar' 'baz barf gnarf' barf '' '' << END +out: ' baz gnarf' +END + +TEST "wordlist replace, middle, replace1" wordlist_replace 'foo.bar' 'baz barf gnarf' barf 'foof' '' << END +out: ' baz foof gnarf' +END + +TEST "wordlist replace, middle, replace2" wordlist_replace 'foo.bar' 'baz barf gnarf' barf '' 'foof' << END +out: ' baz foof gnarf' +END + +TEST "wordlist replace, first, insert before" wordlist_replace 'foo.bar' 'baz barf gnarf' baz 'first' 'baz' << END +out: ' first baz barf gnarf' +END + +TEST "wordlist replace, first, replace1" wordlist_replace 'foo.bar' 'baz barf gnarf' baz 'first' '' << END +out: ' first barf gnarf' +END + +TEST "wordlist replace, first, replace2" wordlist_replace 'foo.bar' 'baz barf gnarf' baz '' 'first' << END +out: ' first barf gnarf' +END + +TEST "wordlist replace, last, insert after" wordlist_replace 'foo.bar' 'baz barf gnarf' gnarf 'gnarf' 'last' << END +out: ' baz barf gnarf last' +END diff --git a/tests/backend/test-config.c b/tests/backend/test-config.c index 8f0e5597e..89d6d94ad 100644 --- a/tests/backend/test-config.c +++ b/tests/backend/test-config.c @@ -288,6 +288,7 @@ TEST ("configitem_simple_ctor_dtor") lumiera_config_destroy (); } + TEST ("configitem_simple_content_check") { REQUIRE (argv[2]); @@ -337,5 +338,48 @@ TEST ("wordlist_get_nth") } +TEST ("wordlist_find") +{ + REQUIRE (argv[2]); + REQUIRE (argv[3]); + REQUIRE (argv[4]); + + lumiera_config_init ("./"); + + if (!lumiera_config_wordlist_set (argv[2], &argv[3])) + printf ("failed setting word '%s=%s': %s\n", argv[2], argv[3], lumiera_error ()); + + int n = lumiera_config_wordlist_find (argv[2], argv[4]); + + printf ("'%d'\n", n); + + lumiera_config_destroy (); +} + + +TEST ("wordlist_replace") +{ + REQUIRE (argv[2]); + REQUIRE (argv[3]); + REQUIRE (argv[4]); + REQUIRE (argv[5]); + REQUIRE (argv[6]); + + lumiera_config_init ("./"); + + if (!lumiera_config_wordlist_set (argv[2], &argv[3])) + printf ("failed setting word '%s=%s': %s\n", argv[2], argv[3], lumiera_error ()); + + const char* wordlist = lumiera_config_wordlist_replace (argv[2], argv[4], *argv[5]?argv[5]:NULL, *argv[6]?argv[6]:NULL); + + if (wordlist) + printf ("'%s'\n", wordlist); + else + printf ("%s\n", lumiera_error ()); + + lumiera_config_destroy (); +} + + TESTS_END