From 52f3b8a860edd07949734f347f7dcec18274ebe7 Mon Sep 17 00:00:00 2001 From: pommicket Date: Sun, 14 Sep 2025 15:50:03 -0400 Subject: get_list --- examples/conf.pom | 6 ++++-- examples/read_conf.c | 9 +++++---- pom.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++---- pom.h | 3 ++- 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); } diff --git a/pom.c b/pom.c index fbbe6e0..1ed3c9b 100644 --- a/pom.c +++ b/pom.c @@ -1,7 +1,3 @@ -/* -TODO: -- get_list -*/ #include "pom.h" #include // 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; +} diff --git a/pom.h b/pom.h index 79bdcd7..aa6d3a9 100644 --- a/pom.h +++ b/pom.h @@ -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; } + -- cgit v1.2.3