summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-09-14 15:50:03 -0400
committerpommicket <pommicket@gmail.com>2025-09-14 15:50:03 -0400
commit52f3b8a860edd07949734f347f7dcec18274ebe7 (patch)
treeeae3c11786011212e2822ecc5f065377f22c4682
parent72b9ca7d05e8150bae98fda96221de3d985654f8 (diff)
get_list
-rw-r--r--examples/conf.pom6
-rw-r--r--examples/read_conf.c9
-rw-r--r--pom.c53
-rw-r--r--pom.h3
-rwxr-xr-xpre-commit.sh1
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 <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;
+}
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; }
+