From c5f2a8f34cf0c14a905edb5cb3f2a9001c9b752e Mon Sep 17 00:00:00 2001 From: cancel Date: Mon, 27 Jan 2020 09:32:04 +0900 Subject: [PATCH] Factor out hard-coded conf file name --- sysmisc.c | 26 +++++++++++++++++++------- sysmisc.h | 13 +++++++++---- tui_main.c | 6 ++++-- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/sysmisc.c b/sysmisc.c index d406aee..1c7332d 100644 --- a/sysmisc.c +++ b/sysmisc.c @@ -222,7 +222,6 @@ typedef enum { static char const *const xdg_config_home_env = "XDG_CONFIG_HOME"; static char const *const home_env = "HOME"; -static char const *const conf_file_name = "/orca.conf"; static Conf_dir_error try_get_conf_dir(oso **out) { char const *xdgcfgdir = getenv(xdg_config_home_env); @@ -244,7 +243,9 @@ static Conf_dir_error try_get_conf_dir(oso **out) { return Conf_dir_no_home; } -FILE *conf_file_open_for_reading(void) { +FILE *conf_file_open_for_reading(char const *conf_file_name) { + if (!conf_file_name) + return NULL; oso *path = NULL; if (try_get_conf_dir(&path)) return NULL; @@ -256,10 +257,15 @@ FILE *conf_file_open_for_reading(void) { return file; } -Conf_save_start_error conf_save_start(Conf_save *p) { +Conf_save_start_error conf_save_start(Conf_save *p, + char const *conf_file_name) { *p = (Conf_save){0}; oso *dir = NULL; Conf_save_start_error err; + if (!conf_file_name) { + err = Conf_save_start_bad_conf_name; + goto cleanup; + } if (try_get_conf_dir(&dir)) { err = Conf_save_start_no_home; goto cleanup; @@ -355,6 +361,8 @@ char const *ezconf_w_errorstring(Ezconf_w_error error) { switch (error) { case Ezconf_w_ok: return "No error"; + case Ezconf_w_bad_conf_name: + return "Bad config file name"; case Ezconf_w_oom: return "Out of memory"; case Ezconf_w_no_home: @@ -386,8 +394,8 @@ char const *ezconf_w_errorstring(Ezconf_w_error error) { return "Unknown"; } -void ezconf_r_start(Ezconf_r *ezcr) { - ezcr->file = conf_file_open_for_reading(); +void ezconf_r_start(Ezconf_r *ezcr, char const* conf_file_name) { + ezcr->file = conf_file_open_for_reading(conf_file_name); ezcr->index = 0; ezcr->value = NULL; } @@ -402,16 +410,20 @@ enum { Ezconf_opt_written = 1 << 0, }; -void ezconf_w_start(Ezconf_w *ezcw, Ezconf_opt *optsbuffer, size_t buffercap) { +void ezconf_w_start(Ezconf_w *ezcw, Ezconf_opt *optsbuffer, size_t buffercap, + char const *conf_file_name) { *ezcw = (Ezconf_w){.save = {0}}; // Weird to silence clang warning ezcw->opts = optsbuffer; ezcw->optscap = buffercap; Ezconf_w_error error = Ezconf_w_unknown_error; - switch (conf_save_start(&ezcw->save)) { + switch (conf_save_start(&ezcw->save, conf_file_name)) { case Conf_save_start_ok: error = Ezconf_w_ok; ezcw->file = ezcw->save.tempfile; break; + case Conf_save_start_bad_conf_name: + error = Ezconf_w_bad_conf_name; + break; case Conf_save_start_alloc_failed: error = Ezconf_w_oom; break; diff --git a/sysmisc.h b/sysmisc.h index bad58e1..c128cd3 100644 --- a/sysmisc.h +++ b/sysmisc.h @@ -31,7 +31,7 @@ Conf_read_result conf_read_line(FILE *file, char *buf, Usz bufsize, bool conf_read_match(FILE **pfile, char const *const *names, Usz nameslen, char *buf, Usz bufsize, Usz *out_index, char **out_value); -FILE *conf_file_open_for_reading(void); +FILE *conf_file_open_for_reading(char const *conf_file_name); typedef struct { FILE *origfile, *tempfile; @@ -40,6 +40,7 @@ typedef struct { typedef enum { Conf_save_start_ok = 0, + Conf_save_start_bad_conf_name, Conf_save_start_alloc_failed, Conf_save_start_no_home, Conf_save_start_mkdir_failed, @@ -56,13 +57,15 @@ typedef enum { Conf_save_commit_rename_failed, } Conf_save_commit_error; -Conf_save_start_error conf_save_start(Conf_save *p); +Conf_save_start_error conf_save_start(Conf_save *p, char const *conf_file_name); // `*p` may be passed in uninitialized or zeroed -- either is fine. If the // return value is `Conf_save_start_ok`, then you must call either // `conf_save_cancel()` or `conf_save_commit()`, otherwise file handles and // strings will be leaked. If the return value is not `Conf_save_start_ok`, // then the contents of `*p` are zeroed, and nothing further has to be called. // +// `conf_file_name` should be a C string like "/myprogram.conf" +// // Note that `origfile` in the `struct Conf_save` may be null even if the call // succeeded and didn't return an error. This is because it's possible for // there to be no existing config file. It might be the first time a config @@ -85,11 +88,12 @@ typedef struct { char buffer[1024]; } Ezconf_r; -void ezconf_r_start(Ezconf_r *ezcr); +void ezconf_r_start(Ezconf_r *ezcr, char const *conf_file_name); bool ezconf_r_step(Ezconf_r *ezcr, char const *const *names, Usz nameslen); typedef enum { Ezconf_w_ok = 0, + Ezconf_w_bad_conf_name, Ezconf_w_oom, Ezconf_w_no_home, Ezconf_w_mkdir_failed, @@ -123,6 +127,7 @@ typedef struct { uint32_t stateflags; } Ezconf_w; -void ezconf_w_start(Ezconf_w *ezcw, Ezconf_opt *optsbuffer, size_t buffercap); +void ezconf_w_start(Ezconf_w *ezcw, Ezconf_opt *optsbuffer, + size_t buffercap, char const *conf_file_name); void ezconf_w_addopt(Ezconf_w *ezcw, char const *key, intptr_t id); bool ezconf_w_step(Ezconf_w *ezcw); diff --git a/tui_main.c b/tui_main.c index 090d9d6..ec2625d 100644 --- a/tui_main.c +++ b/tui_main.c @@ -2490,6 +2490,7 @@ staticni void try_send_to_gui_clipboard(Ged const *a, *io_use_gui_clipboard = false; } +static char const *const conf_file_name = "/orca.conf"; #define CONFOPT_STRING(x) #x, #define CONFOPT_ENUM(x) Confopt_##x, #define CONFOPTS(_) \ @@ -2580,7 +2581,8 @@ staticni void tui_load_conf(Tui *t) { *osc_output_port = NULL; U32 touched = 0; Ezconf_r ez; - for (ezconf_r_start(&ez); ezconf_r_step(&ez, confopts, Confoptslen);) { + for (ezconf_r_start(&ez, conf_file_name); + ezconf_r_step(&ez, confopts, Confoptslen);) { switch (ez.index) { case Confopt_portmidi_output_device: osoput(&portmidi_output_device, ez.value); @@ -2685,7 +2687,7 @@ staticni void tui_load_conf(Tui *t) { staticni void tui_save_prefs(Tui *t) { Ezconf_opt optsbuff[Confoptslen]; Ezconf_w ez; - ezconf_w_start(&ez, optsbuff, ORCA_ARRAY_COUNTOF(optsbuff)); + ezconf_w_start(&ez, optsbuff, ORCA_ARRAY_COUNTOF(optsbuff), conf_file_name); oso *midi_output_device_name = NULL; switch (t->ged.midi_mode.any.type) { case Midi_mode_type_null: