summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2023-05-26 18:31:42 -0700
committerVito Caputo <vcaputo@pengaru.com>2023-05-26 18:31:42 -0700
commit7b26b18e69e7e1af3eeb5176e3575eb049451f44 (patch)
tree0e041fa3764297920659fbc9be734c0ee04caa16
parent1a89d30e76d2bdb8268c17073d8a780b5adf3049 (diff)
til_settings: add some settings and desc path printers
These print to a stdio FILE*, which for now is harmless since setup_interactively() will be the only consumer (... for now). If one needed the path in a buffer, they could use open_memstream() and pass that FILE* to the printers. And since commit 40feb61 there's already a dependency on the function, but it's icky to dig deeper into that portability trap. Although it seemed like rototiller actually compiled on MacOS at Gene's house, so maybe open_memstream() isn't as problematic as it once was. Anywhow, this commit only adds the path printing helpers, nothing is using them yet.
-rw-r--r--src/til_settings.c70
-rw-r--r--src/til_settings.h2
2 files changed, 72 insertions, 0 deletions
diff --git a/src/til_settings.c b/src/til_settings.c
index e42aae8..510dbaf 100644
--- a/src/til_settings.c
+++ b/src/til_settings.c
@@ -441,6 +441,36 @@ til_setting_desc_t * til_setting_desc_free(const til_setting_desc_t *desc)
}
+int til_setting_desc_print_path(const til_setting_desc_t *desc, FILE *out)
+{
+ int r;
+
+ assert(desc);
+ assert(out);
+
+ r = til_settings_print_path(desc->container, out);
+ if (r < 0)
+ return r;
+
+ /* XXX: spec.as_label handling is done in til_settings_print_path() since it
+ * must apply anywhere within a path, potentially in a recurring fashion.
+ * So all we're dealing with here is tacking a potentially named desc onto the end,
+ * treating named descs as a sort of leaf of the path. Though the desc may actually
+ * describe a setting w/nested settings, i.e. it doesn't actually have to be a leaf
+ * for this to be correct. When its a parent of nested settings scenario, its key
+ * would have been used to label the nested settings, but this print won't traverse
+ * down from desc->container, only up the parents.
+ */
+ if (desc->spec.key) {
+ r = fprintf(out, "/%s", desc->spec.key);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+
/* TODO: spec checking in general needs refinement and to be less intolerant of
* creative experimentation.
*/
@@ -579,3 +609,43 @@ int til_settings_label_setting(const til_settings_t *settings, const til_setting
return -ENOENT;
}
+
+
+int til_settings_print_path(const til_settings_t *settings, FILE *out)
+{
+ const til_settings_t *p, *parents[64];
+ size_t i, n_parents;
+
+ assert(settings);
+ assert(out);
+
+ for (p = settings, n_parents = 0; p != NULL; p = p->parent)
+ n_parents++;
+
+ /* XXX: if this limitation becomes a problem we can always malloc()
+ * space, but I can't imagine such deep settings heirarchies being real.
+ */
+ assert(n_parents <= nelems(parents));
+
+ for (i = 0, p = settings; i < n_parents; p = p->parent, i++)
+ parents[n_parents - i - 1] = p;
+
+ for (i = 0; i < n_parents; i++) {
+ int r;
+
+ r = fprintf(out, "/%s", parents[i]->label);
+ if (r < 0)
+ return r;
+
+ if (parents[i]->num > 0 &&
+ parents[i]->entries[0]->desc &&
+ parents[i]->entries[0]->desc->spec.as_label) {
+
+ r = fprintf(out, "/%s", parents[i]->entries[0]->value);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/til_settings.h b/src/til_settings.h
index 2e2afe9..858ff66 100644
--- a/src/til_settings.h
+++ b/src/til_settings.h
@@ -56,8 +56,10 @@ int til_settings_apply_desc_generators(const til_settings_t *settings, const til
int til_setting_desc_new(const til_settings_t *settings, const til_setting_spec_t *spec, const til_setting_desc_t **res_desc);
til_setting_desc_t * til_setting_desc_free(const til_setting_desc_t *desc);
+int til_setting_desc_print_path(const til_setting_desc_t *desc, FILE *out);
int til_setting_spec_check(const til_setting_spec_t *spec, const char *value);
int til_settings_label_setting(const til_settings_t *settings, const til_setting_t *setting, char **res_label);
+int til_settings_print_path(const til_settings_t *settings, FILE *out);
#ifndef TIL_SETTINGS_STR
#define _TIL_SETTINGS_STR(s) #s
© All Rights Reserved