summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-09-14 12:53:39 -0400
committerpommicket <pommicket@gmail.com>2025-09-14 12:53:39 -0400
commitee7e2dbf3d6bc4ef8d4019c666a8960976c1af75 (patch)
treec5b607087786e028f98e34de001fa9b1e0e08773
parentc8ef3a67210c980d5d1ff2c1bd7d8fffd39846b5 (diff)
Parse uint
-rw-r--r--examples/conf.pom9
-rw-r--r--examples/read_conf.c21
-rw-r--r--pom.c50
-rw-r--r--pom.h20
4 files changed, 77 insertions, 23 deletions
diff --git a/examples/conf.pom b/examples/conf.pom
index ed37ed9..6b839d1 100644
--- a/examples/conf.pom
+++ b/examples/conf.pom
@@ -1,7 +1,2 @@
-[number]p
-one = 1
-two = 2x"\?
-three j= "3
-is
-the
- best"
+[number]
+best = "0x127432"
diff --git a/examples/read_conf.c b/examples/read_conf.c
index 18802e3..c4cabfc 100644
--- a/examples/read_conf.c
+++ b/examples/read_conf.c
@@ -12,21 +12,10 @@ int main(int argc, char **argv) {
free(error);
return EXIT_FAILURE;
}
- pom_conf *conf2 = pom_load_string("<inline>", "foo=bar\r\n[j.number]\n"
- "one = I\n"
- "five = V\n", &error);
- if (!conf2) {
- pom_conf_free(conf);
- pom_error_print(error);
- free(error);
- return EXIT_FAILURE;
- }
- pom_conf *copy = pom_conf_copy(conf);
- pom_conf_merge(copy,pom_conf_section(conf2,"j"));
- pom_conf *copy2 = pom_conf_copy(copy);
- pom_conf_print(copy2);
+ uint64_t value;
+ const char *s = pom_conf_get_uint(conf, "number.best", &value);
+ printf("%" PRIu64 "\n", value);
+ if (s) printf(" -> %s\n",s);
+ pom_conf_print(conf);
pom_conf_free(conf);
- pom_conf_free(copy);
- pom_conf_free(copy2);
- pom_conf_free(conf2);
}
diff --git a/pom.c b/pom.c
index ad3919c..87154e8 100644
--- a/pom.c
+++ b/pom.c
@@ -1535,3 +1535,53 @@ pom_conf_copy(const pom_conf *conf) {
}
return new_root;
}
+
+static bool
+parse_uint(const char *s, uint64_t *val) {
+ if (*s == '+') s++;
+ if (*s == 0) {
+ // empty number
+ return false;
+ }
+ uint64_t value = 0;
+ if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) {
+ // hexadecimal
+ for (size_t i = 2; s[i]; i++) {
+ if (parse_hex_digit(s[i]) == -1)
+ return false;
+ }
+ value = (uint64_t) strtoull(s, NULL, 16);
+ } else if (*s == '0') {
+ if (s[1] != 0) {
+ // leading zero
+ return false;
+ }
+ } else {
+ for (size_t i = 0; s[i]; i++) {
+ if (s[i] < '0' || s[i] > '9')
+ return false;
+ }
+ value = (uint64_t) strtoull(s, NULL, 10);
+ }
+ if (value >> 53) {
+ // too big!
+ return false;
+ }
+ *val = value;
+ return true;
+}
+
+const char *
+pom_conf_get_uint(const pom_conf *conf, const char *key, uint64_t *value_uint) {
+ check_conf(conf);
+ if (!key) fatal_error("NULL key passed to %s", __func__);
+ if (!value_uint) fatal_error("NULL value passed to %s", __func__);
+ *value_uint = 0;
+ const char *value_str = pom_conf_get(conf, key);
+ if (!value_str) {
+ return "";
+ }
+ if (parse_uint(value_str, value_uint))
+ return NULL;
+ return value_str;
+}
diff --git a/pom.h b/pom.h
index 1139ee8..5635316 100644
--- a/pom.h
+++ b/pom.h
@@ -230,10 +230,14 @@ bool
pom_conf_location(const pom_conf *conf, const char *key, const char **file, uint64_t *line);
/// Get value of `key` in configuration, or `NULL` if key is not present.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get(const pom_conf *conf, const char *key);
/// Get value of `key` in configuration, or use `dflt` if not present.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_or_default(const pom_conf *conf, const char *key, const char *dflt);
@@ -246,6 +250,8 @@ pom_conf_get_or_default(const pom_conf *conf, const char *key, const char *dflt)
/// (decimal or `0x`/`0X`-prefixed hexadecimal, absolute value less than 2<sup>53</sup>),
/// returns the value of `key`.
/// `*value` is set to 0 in these cases.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_int(const pom_conf *conf, const char *key, int64_t *value);
@@ -257,6 +263,8 @@ pom_conf_get_int(const pom_conf *conf, const char *key, int64_t *value);
/// (decimal or `0x`/`0X`-prefixed hexadecimal, absolute value less than 2<sup>53</sup>),
/// returns the value of `key`.
/// `*value` is still set to `dflt` in this case.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_int_or_default(const pom_conf *conf, const char *key, int64_t *value, int64_t dflt);
@@ -268,6 +276,8 @@ pom_conf_get_int_or_default(const pom_conf *conf, const char *key, int64_t *valu
/// (decimal or `0x`/`0X`-prefixed hexadecimal, less than 2<sup>53</sup>),
/// returns the value of `key`.
/// `*value` is set to 0 in these case cases.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_uint(const pom_conf *conf, const char *key, uint64_t *value);
@@ -279,6 +289,8 @@ pom_conf_get_uint(const pom_conf *conf, const char *key, uint64_t *value);
/// (decimal or `0x`/`0X`-prefixed hexadecimal, less than 2<sup>53</sup>),
/// returns the value of `key`.
/// `*value` is set to 0 in this case.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_uint_or_default(const pom_conf *conf, const char *key, uint64_t *value, uint64_t dflt);
@@ -289,6 +301,8 @@ pom_conf_get_uint_or_default(const pom_conf *conf, const char *key, uint64_t *va
/// If `key` is not set, returns `""`. If `key` is set but not a valid floating-point number,
/// returns the value of `key`.
/// `*value` is set to 0.0 in this case.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_float(const pom_conf *conf, const char *key, double *value);
@@ -299,6 +313,8 @@ pom_conf_get_float(const pom_conf *conf, const char *key, double *value);
/// If `key` is set but not a valid floating-point number,
/// returns the value of `key`.
/// `*value` is still set to `dflt` in this case.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_float_or_default(const pom_conf *conf, const char *key, double *value, double dflt);
@@ -310,6 +326,8 @@ pom_conf_get_float_or_default(const pom_conf *conf, const char *key, double *val
/// (`off`/`false`/`no`/`on`/`true`/`yes`),
/// returns the value of `key`.
/// `*value` is set to `false` in this case.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_bool(const pom_conf *conf, const char *key, bool *value);
@@ -321,6 +339,8 @@ pom_conf_get_bool(const pom_conf *conf, const char *key, bool *value);
/// (`off`/`false`/`no`/`on`/`true`/`yes`),
/// returns the value of `key`.
/// `*value` is still set to `dflt` in this case.
+///
+/// The returned pointer is valid until \ref pom_conf_free is called.
const char *
pom_conf_get_bool_or_default(const pom_conf *conf, const char *key, bool *value, bool dflt);