diff options
author | pommicket <pommicket@gmail.com> | 2025-09-14 15:50:03 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2025-09-14 15:50:03 -0400 |
commit | 52f3b8a860edd07949734f347f7dcec18274ebe7 (patch) | |
tree | eae3c11786011212e2822ecc5f065377f22c4682 | |
parent | 72b9ca7d05e8150bae98fda96221de3d985654f8 (diff) |
get_list
-rw-r--r-- | examples/conf.pom | 6 | ||||
-rw-r--r-- | examples/read_conf.c | 9 | ||||
-rw-r--r-- | pom.c | 53 | ||||
-rw-r--r-- | pom.h | 3 | ||||
-rwxr-xr-x | pre-commit.sh | 1 |
5 files changed, 61 insertions, 11 deletions
diff --git a/examples/conf.pom b/examples/conf.pom index 4f4aa8c..e66cde0 100644 --- a/examples/conf.pom +++ b/examples/conf.pom @@ -1,2 +1,4 @@ -[number] -best = "2" +things = "ten, + great\,things, + i\\really, + love" diff --git a/examples/read_conf.c b/examples/read_conf.c index 24fade0..be1f97a 100644 --- a/examples/read_conf.c +++ b/examples/read_conf.c @@ -13,10 +13,11 @@ int main(int argc, char **argv) { free(error); return EXIT_FAILURE; } - double value; - const char *s = pom_conf_get_float_or_default(conf, "number.best", &value, 3.6); - printf("%f\n", value); - if (s) printf(" -> %s\n",s); + char **list = pom_conf_get_list(conf, "things"); + for (size_t i = 0; list[i]; i++) { + printf("%s\n",list[i]); + } + free(list); pom_conf_print(conf); pom_conf_free(conf); } @@ -1,7 +1,3 @@ -/* -TODO: -- get_list -*/ #include "pom.h" #include <stdio.h> // still needed for sprintf, even if POM_NO_STDIO is defined. @@ -1788,3 +1784,52 @@ pom_conf_get_bool_or_default(const pom_conf *conf, const char *key, bool *value_ return NULL; return value_str; } + +char ** +pom_conf_get_list(const pom_conf *conf, const char *key) { + check_conf(conf); + if (!key) fatal_error("NULL key passed to %s", __func__); + const char *value_str = pom_conf_get(conf, key); + if (!value_str) return NULL; + size_t max_entries = 1; // upper bound on # of entries + for (const char *p = value_str; *p; p++) + max_entries += *p == ','; + if (max_entries > SIZE_MAX / 16) { + // too many entries (avoid arithmetic overflow) + return NULL; + } + size_t bytes_needed = (max_entries+1) * sizeof (char *) + + strlen(value_str) + 1; + char **list = malloc(bytes_needed); + if (!list) return NULL; + char **entry = list; + char *strings = (char *)(list + max_entries+1); + const char *p = value_str; + while (true) { + while (strchr(" \t\n", *p)) p++; + const char *end = p; + char *out = *entry++ = strings; + for (; *end; end++) { + if (*end == '\\' && (end[1] == ',' || end[1] == '\\')) { + end++; + *out++ = *end; + } else if (*end == ',' || *end == '\0') { + break; + } else { + *out++ = *end; + } + } + *out = 0; + while (out > strings && strchr(" \t\n", out[-1])) + *--out = 0; + strings = out + 1; + if (*end == '\0') break; + p = end + 1; + } + // remove last entry if it's empty + if (entry > list && *entry[-1] == 0) { + entry[-1] = NULL; + } + *entry = NULL; + return list; +} @@ -105,7 +105,8 @@ typedef struct pom_item { /// Currently supported languages: /// /// - `en-US` -void pom_set_error_language(const char *lang); +void +pom_set_error_language(const char *lang); /// Load a configuration using a `read`-like function. /// diff --git a/pre-commit.sh b/pre-commit.sh index 85253dd..bda1666 100755 --- a/pre-commit.sh +++ b/pre-commit.sh @@ -2,3 +2,4 @@ # Ensure no doxygen errors which doxygen >/dev/null 2>/dev/null && { doxygen || exit 1; } + |