From ffb0ed186bd33d916633e9501250522b94423766 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 12 Jun 2023 16:44:28 -0700 Subject: til_settings: pivot settings path printing to til_str This eliminates more open_memstream() usage in favor of the new til_str stuff. While here I've split up the path construction API exposing the til_str oriented variants, rather than only providing a FILE*-oriented API. This way you just use the FILE* stuff when convenient (like printing to stdout/stderr) and go til_str_t when you're building up a buffer. Such is life in a sans-open_memstream-world. Also while here the FILE*-oriented settings path printers were renamed s/print/fprint/g hence touching setup.c --- src/setup.c | 4 +-- src/til_settings.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++-------- src/til_settings.h | 7 +++-- 3 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/setup.c b/src/setup.c index f2b50e3..cf39f08 100644 --- a/src/setup.c +++ b/src/setup.c @@ -96,7 +96,7 @@ int setup_interactively(til_settings_t *settings, int (*setup_func)(const til_se /* multiple choice */ if (!defaults) { - til_setting_desc_print_path(desc, stdout); + til_setting_desc_fprint_path(desc, stdout); printf(":\n %s:\n", desc->spec.name); } @@ -116,7 +116,7 @@ int setup_interactively(til_settings_t *settings, int (*setup_func)(const til_se } else { /* arbitrarily typed input */ if (!defaults) { - til_setting_desc_print_path(desc, stdout); + til_setting_desc_fprint_path(desc, stdout); printf(":\n %s [%s]: ", desc->spec.name, desc->spec.preferred); } } diff --git a/src/til_settings.c b/src/til_settings.c index b7ebe4d..49ef3d1 100644 --- a/src/til_settings.c +++ b/src/til_settings.c @@ -453,16 +453,23 @@ 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_desc_fprint_path(const til_setting_desc_t *desc, FILE *out) { - int r; + til_str_t *str; + int r; assert(desc); assert(out); - r = til_settings_print_path(desc->container, out); - if (r < 0) + str = til_str_new(""); + if (!str) + return -ENOMEM; + + r = til_settings_strprint_path(desc->container, str); + if (r < 0) { + til_str_free(str); 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. @@ -474,12 +481,19 @@ int til_setting_desc_print_path(const til_setting_desc_t *desc, FILE *out) * down from desc->container, only up the parents. */ if (desc->spec.key) { - r = fprintf(out, "/%s", desc->spec.key); - if (r < 0) + r = til_str_appendf(str, "/%s", desc->spec.key); + if (r < 0) { + til_str_free(str); return r; + } } - return 0; + if (fputs(til_str_buf(str, NULL), out) == EOF) + r = -EPIPE; + + til_str_free(str); + + return r; } @@ -623,13 +637,13 @@ int til_settings_label_setting(const til_settings_t *settings, const til_setting } -int til_settings_print_path(const til_settings_t *settings, FILE *out) +int til_settings_strprint_path(const til_settings_t *settings, til_str_t *str) { const til_settings_t *p, *parents[64]; size_t i, n_parents; assert(settings); - assert(out); + assert(str); for (p = settings, n_parents = 0; p != NULL; p = p->parent) n_parents++; @@ -646,12 +660,12 @@ int til_settings_print_path(const til_settings_t *settings, FILE *out) int r; if (parents[i]->prefix) { - r = fprintf(out, "%s", parents[i]->prefix); + r = til_str_appendf(str, "%s", parents[i]->prefix); if (r < 0) return r; } - r = fprintf(out, "/%s", parents[i]->label); + r = til_str_appendf(str, "/%s", parents[i]->label); if (r < 0) return r; @@ -659,7 +673,7 @@ int til_settings_print_path(const til_settings_t *settings, FILE *out) parents[i]->entries[0]->desc && parents[i]->entries[0]->desc->spec.as_label) { - r = fprintf(out, "/%s", parents[i]->entries[0]->value); + r = til_str_appendf(str, "/%s", parents[i]->entries[0]->value); if (r < 0) return r; } @@ -667,3 +681,45 @@ int til_settings_print_path(const til_settings_t *settings, FILE *out) return 0; } + + +int til_settings_path_as_buf(const til_settings_t *settings, char **res_buf, size_t *res_bufsz) +{ + til_str_t *str; + int r; + + assert(settings); + assert(res_buf); + + str = til_str_new(""); + if (!str) + return -ENOMEM; + + r = til_settings_strprint_path(settings, str); + if (r < 0) + return r; + + *res_buf = til_str_to_buf(str, res_bufsz); + + return 0; +} + + + +int til_settings_fprint_path(const til_settings_t *settings, FILE *out) +{ + char *buf; + int r = 0; + + assert(settings); + assert(out); + + r = til_settings_path_as_buf(settings, &buf, NULL); + if (r < 0) + return r; + + if (fputs(buf, out) == EOF) + r = -EPIPE; + + free(buf); +} diff --git a/src/til_settings.h b/src/til_settings.h index 6ff791c..43bbee1 100644 --- a/src/til_settings.h +++ b/src/til_settings.h @@ -6,6 +6,7 @@ typedef struct til_setting_t til_setting_t; typedef struct til_settings_t til_settings_t; typedef struct til_setup_t til_setup_t; +typedef struct til_str_t til_str_t; /* Individual setting specification */ typedef struct til_setting_spec_t { @@ -57,10 +58,12 @@ 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_desc_fprint_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); +int til_settings_strprint_path(const til_settings_t *settings, til_str_t *str); +int til_settings_path_as_buf(const til_settings_t *settings, char **res_buf, size_t *res_bufsz); +int til_settings_fprint_path(const til_settings_t *settings, FILE *out); #ifndef TIL_SETTINGS_STR #define _TIL_SETTINGS_STR(s) #s -- cgit v1.2.1