diff --git a/src/backend/config.h b/src/backend/config.h index 96e519c0d..0b50c7da2 100644 --- a/src/backend/config.h +++ b/src/backend/config.h @@ -261,6 +261,15 @@ const char* lumiera_config_wordlist_replace (const char* key, const char* value, const char* subst1, const char* subst2); +/** + * Add a word to the end of a wordlist if it doesnt exist already + * @param key key under which this wordlist is stored + * @param value new word to add + * @return internal representation of the wordlist in a tmpbuf or NULL in case of an error + */ +const char* +lumiera_config_wordlist_add (const char* key, const char* value); + // * {{{ 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_wordlist.c b/src/backend/config_wordlist.c index acee07562..548a4d824 100644 --- a/src/backend/config_wordlist.c +++ b/src/backend/config_wordlist.c @@ -91,6 +91,9 @@ lumiera_config_wordlist_replace (const char* key, const char* value, const char* size_t vlen = strlen (value); size_t len; + if (!value) + return NULL; + LUMIERA_MUTEX_SECTION (config_typed, &lumiera_global_config->lock) { if (lumiera_config_get (key, &wordlist)) @@ -138,15 +141,56 @@ lumiera_config_wordlist_replace (const char* key, const char* value, const char* } +const char* +lumiera_config_wordlist_add (const char* key, const char* value) +{ + const char* wordlist = NULL; + + if (value && *value) + { + LUMIERA_MUTEX_SECTION (config_typed, &lumiera_global_config->lock) + { + if (lumiera_config_get (key, &wordlist)) + { + size_t vlen = strlen (value); + size_t len; + + for (const char* itr = wordlist; *itr; itr += len) + { + itr += strspn (itr, " \t,;"); + len = strcspn (itr, " \t,;"); + + if (len == vlen && !strncmp (itr, value, vlen)) + goto end; + } + + TODO ("figure delimiter from original string out"); + const char* delim = " "; + + wordlist = lumiera_tmpbuf_snprintf (SIZE_MAX, "%s%s%s", + wordlist, + wordlist[strspn (wordlist, " \t,;")]?delim:"", + value); + + if (!lumiera_config_set (key, lumiera_tmpbuf_snprintf (SIZE_MAX, "=%s", wordlist))) + wordlist = NULL; + } + end:; + } + } + + return wordlist; +} + #if 0 - -LumieraConfigitem -lumiera_config_wordlist_remove_nth (const char* key, const char** value, unsigned nth) +const char* +lumiera_config_wordlist_remove_nth (const char* key, unsigned nth) { } + LumieraConfigitem lumiera_config_wordlist_append (const char* key, const char** value, unsigned nth) { @@ -158,10 +202,6 @@ lumiera_config_wordlist_preprend (const char* key, const char** value, unsigned } -LumieraConfigitem -lumiera_config_wordlist_add (const char* key, const char** value, unsigned nth) -{ -} #endif diff --git a/tests/22config_highlevel.tests b/tests/22config_highlevel.tests index e2400c6ff..3d131da3e 100644 --- a/tests/22config_highlevel.tests +++ b/tests/22config_highlevel.tests @@ -202,3 +202,23 @@ END TEST "wordlist replace, last, insert after" wordlist_replace 'foo.bar' 'baz barf gnarf' gnarf 'gnarf' 'last' << END out: ' baz barf gnarf last' END + +TEST "wordlist add 2 words" wordlist_add 'foo.bar' 'baz barf gnarf' first second << END +out: ' baz barf gnarf first' +out: ' baz barf gnarf first second' +END + +TEST "wordlist add same word" wordlist_add 'foo.bar' 'baz barf gnarf' same same << END +out: ' baz barf gnarf same' +out: ' baz barf gnarf same' +END + +TEST "wordlist add to empty list" wordlist_add 'foo.bar' '' first second << END +out: ' first' +out: ' first second' +END + +TEST "wordlist add to empty list, same" wordlist_add 'foo.bar' '' same same << END +out: ' same' +out: ' same' +END diff --git a/tests/backend/test-config.c b/tests/backend/test-config.c index 89d6d94ad..deffa7c00 100644 --- a/tests/backend/test-config.c +++ b/tests/backend/test-config.c @@ -381,5 +381,33 @@ TEST ("wordlist_replace") } +TEST ("wordlist_add") +{ + REQUIRE (argv[2]); + REQUIRE (argv[3]); + REQUIRE (argv[4]); + REQUIRE (argv[5]); + + 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_add (argv[2], argv[4]); + if (wordlist) + printf ("'%s'\n", wordlist); + else + printf ("%s\n", lumiera_error ()); + + wordlist = lumiera_config_wordlist_add (argv[2], argv[5]); + if (wordlist) + printf ("'%s'\n", wordlist); + else + printf ("%s\n", lumiera_error ()); + + lumiera_config_destroy (); +} + + TESTS_END