commit af0bbfe83e52c25273ef1b4a4caa77211117b43c
parent 0cab9c7e8c41b00b43878ae538f04349fd89a39f
Author: nibo <nibo@relim.de>
Date: Sat, 29 Mar 2025 13:22:12 +0100
Add different ways to create a config
- config_load_from_file()
- config_load_from_data()
- config_load_default()
Diffstat:
3 files changed, 165 insertions(+), 112 deletions(-)
diff --git a/src/config.c b/src/config.c
@@ -426,84 +426,6 @@ config_alignment_to_config_string(enum Alignment align)
return alignments[align];
}
-static struct Config *
-config_load_default(void)
-{
- struct Config *config = emalloc(sizeof(struct Config));
- config->metadata_separator = strdup("; ");
-
- config->parser = emalloc(sizeof(struct ConfigParser));
- config->parser->chords = emalloc(sizeof(struct ConfigChords));
- config->parser->chords->notation_system = NS_COMMON;
- config->parser->chords->mode = PM_STRICT;
- config->parser->notes = config_notes_new_default(NS_COMMON);
-
- config->output = emalloc(sizeof(struct ConfigOutput));
- config->output->notation_system = NS_COMMON;
- config->output->start_song_on_new_page = true;
- config->output->notes = config_notes_new_default(NS_COMMON);
- config->output->chorus = emalloc(sizeof(struct ConfigChorus));
- config->output->chorus->label = strdup("Chorus");
- config->output->chorus->quote = false;
- config->output->diagram = emalloc(sizeof(struct ChordDiagram));
- config->output->diagram->show = true;
- config->output->diagram->instrument = INS_GUITAR;
- config->output->page_no = emalloc(sizeof(struct ConfigPageNo));
- config->output->page_no->show = true;
- config->output->page_no->align = A_CENTER;
- config->output->toc = emalloc(sizeof(struct ConfigToc));
- config->output->toc->show = false;
- config->output->toc->title = strdup("Table Of Contents");
-
- config->output->styles[TT_CHORD] = cho_style_new();
- config->output->styles[TT_CHORD]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_CHORD]->font->weight = FW_BOLD;
- config->output->styles[TT_ANNOT] = cho_style_new();
- config->output->styles[TT_ANNOT]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_ANNOT]->font->style = FS_ITALIC;
- config->output->styles[TT_CHORUS] = cho_style_new();
- config->output->styles[TT_CHORUS]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_FOOTER] = cho_style_new();
- config->output->styles[TT_FOOTER]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_GRID] = cho_style_new();
- config->output->styles[TT_GRID]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_GRID]->font->weight = FW_BOLD;
- config->output->styles[TT_TAB] = cho_style_new();
- config->output->styles[TT_TAB]->font->name = strdup("Courier");
- // config->output->styles[TT_TAB]->font->family = FF_MONOSPACE;
- config->output->styles[TT_TOC] = cho_style_new();
- config->output->styles[TT_TOC]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_TOC]->font->size = 12.0;
- config->output->styles[TT_TOC_TITLE] = cho_style_new();
- config->output->styles[TT_TOC_TITLE]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_TOC_TITLE]->font->weight = FW_BOLD;
- config->output->styles[TT_TOC_TITLE]->font->size = 18.0;
- config->output->styles[TT_TEXT] = cho_style_new();
- config->output->styles[TT_TEXT]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_TITLE] = cho_style_new();
- config->output->styles[TT_TITLE]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_TITLE]->font->weight = FW_BOLD;
- config->output->styles[TT_TITLE]->font->size = 18.0;
- config->output->styles[TT_SUBTITLE] = cho_style_new();
- config->output->styles[TT_SUBTITLE]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_SUBTITLE]->font->size = 12.0;
- config->output->styles[TT_LABEL] = cho_style_new();
- config->output->styles[TT_LABEL]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_LABEL]->font->style = FS_ITALIC;
- config->output->styles[TT_COMMENT] = cho_style_new();
- config->output->styles[TT_COMMENT]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_COMMENT]->background_color->red = 228;
- config->output->styles[TT_COMMENT]->background_color->green = 228;
- config->output->styles[TT_COMMENT]->background_color->blue = 228;
- config->output->styles[TT_COMMENT_ITALIC] = cho_style_new();
- config->output->styles[TT_COMMENT_ITALIC]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_COMMENT_ITALIC]->font->style = FS_ITALIC;
- config->output->styles[TT_COMMENT_BOX] = cho_style_new();
- config->output->styles[TT_COMMENT_BOX]->font->name = strdup(DEFAULT_FONT);
- config->output->styles[TT_COMMENT_BOX]->boxed = true;
- return config;
-}
-
void
config_print_default(void)
{
@@ -884,38 +806,100 @@ lyrics_set_text_style_as_default(
}
struct Config *
-config_load(const char *filepath)
+config_load_default(void)
{
- struct ConfigContext ctx;
- struct Config *config = config_load_default();
- char *home = getenv("HOME");
- char path[26+strlen(home)+1];
- if (!filepath) {
- sprintf(path, "%s/.config/lorid/config.toml", home);
- filepath = path;
- }
- strcpy(ctx.config_filepath, filepath);
+ struct Config *config = emalloc(sizeof(struct Config));
+ config->metadata_separator = strdup("; ");
- FILE *fp = fopen(filepath, "r");
- if (!fp) {
- util_log(NULL, 0, LOG_INFO, "Couldn't open config file '%s'. Using default configuration.", filepath);
- return config;
- }
- char errbuf[200];
- toml_table_t *table = toml_parse_file(fp, (char *)&errbuf, sizeof(errbuf));
- if (!table) {
- LOG_DEBUG("toml_parse_file failed.");
- util_log(NULL, 0, LOG_ERR, "Config file '%s' is not a valid toml file: %s.", filepath, (char *)&errbuf);
- return NULL;
- }
+ config->parser = emalloc(sizeof(struct ConfigParser));
+ config->parser->chords = emalloc(sizeof(struct ConfigChords));
+ config->parser->chords->notation_system = NS_COMMON;
+ config->parser->chords->mode = PM_STRICT;
+ config->parser->notes = config_notes_new_default(NS_COMMON);
+
+ config->output = emalloc(sizeof(struct ConfigOutput));
+ config->output->notation_system = NS_COMMON;
+ config->output->start_song_on_new_page = true;
+ config->output->notes = config_notes_new_default(NS_COMMON);
+ config->output->chorus = emalloc(sizeof(struct ConfigChorus));
+ config->output->chorus->label = strdup("Chorus");
+ config->output->chorus->quote = false;
+ config->output->diagram = emalloc(sizeof(struct ChordDiagram));
+ config->output->diagram->show = true;
+ config->output->diagram->instrument = INS_GUITAR;
+ config->output->page_no = emalloc(sizeof(struct ConfigPageNo));
+ config->output->page_no->show = true;
+ config->output->page_no->align = A_CENTER;
+ config->output->toc = emalloc(sizeof(struct ConfigToc));
+ config->output->toc->show = false;
+ config->output->toc->title = strdup("Table Of Contents");
+
+ config->output->styles[TT_CHORD] = cho_style_new();
+ config->output->styles[TT_CHORD]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_CHORD]->font->weight = FW_BOLD;
+ config->output->styles[TT_ANNOT] = cho_style_new();
+ config->output->styles[TT_ANNOT]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_ANNOT]->font->style = FS_ITALIC;
+ config->output->styles[TT_CHORUS] = cho_style_new();
+ config->output->styles[TT_CHORUS]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_FOOTER] = cho_style_new();
+ config->output->styles[TT_FOOTER]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_GRID] = cho_style_new();
+ config->output->styles[TT_GRID]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_GRID]->font->weight = FW_BOLD;
+ config->output->styles[TT_TAB] = cho_style_new();
+ config->output->styles[TT_TAB]->font->name = strdup("Courier");
+ // config->output->styles[TT_TAB]->font->family = FF_MONOSPACE;
+ config->output->styles[TT_TOC] = cho_style_new();
+ config->output->styles[TT_TOC]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_TOC]->font->size = 12.0;
+ config->output->styles[TT_TOC_TITLE] = cho_style_new();
+ config->output->styles[TT_TOC_TITLE]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_TOC_TITLE]->font->weight = FW_BOLD;
+ config->output->styles[TT_TOC_TITLE]->font->size = 18.0;
+ config->output->styles[TT_TEXT] = cho_style_new();
+ config->output->styles[TT_TEXT]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_TITLE] = cho_style_new();
+ config->output->styles[TT_TITLE]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_TITLE]->font->weight = FW_BOLD;
+ config->output->styles[TT_TITLE]->font->size = 18.0;
+ config->output->styles[TT_SUBTITLE] = cho_style_new();
+ config->output->styles[TT_SUBTITLE]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_SUBTITLE]->font->size = 12.0;
+ config->output->styles[TT_LABEL] = cho_style_new();
+ config->output->styles[TT_LABEL]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_LABEL]->font->style = FS_ITALIC;
+ config->output->styles[TT_COMMENT] = cho_style_new();
+ config->output->styles[TT_COMMENT]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_COMMENT]->background_color->red = 228;
+ config->output->styles[TT_COMMENT]->background_color->green = 228;
+ config->output->styles[TT_COMMENT]->background_color->blue = 228;
+ config->output->styles[TT_COMMENT_ITALIC] = cho_style_new();
+ config->output->styles[TT_COMMENT_ITALIC]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_COMMENT_ITALIC]->font->style = FS_ITALIC;
+ config->output->styles[TT_COMMENT_BOX] = cho_style_new();
+ config->output->styles[TT_COMMENT_BOX]->font->name = strdup(DEFAULT_FONT);
+ config->output->styles[TT_COMMENT_BOX]->boxed = true;
+ return config;
+}
+
+static struct Config *
+config_load(toml_table_t *toml, const char *filepath)
+{
+ bool error;
+ struct Config *config;
+ struct ConfigContext ctx;
toml_value_t value;
- value = toml_table_string(table, "metadata_separator");
+ toml_table_t *output, *parser;
+
+ ctx.config_filepath = filepath ? strdup(filepath) : NULL;
+ config = config_load_default();
+ value = toml_table_string(toml, "metadata_separator");
if (value.ok) {
free(config->metadata_separator);
config->metadata_separator = value.u.s;
}
- toml_table_t *output = toml_table_table(table, "output");
- bool error;
+ output = toml_table_table(toml, "output");
if (output) {
toml_table_t *styles, *notes, *chorus, *diagram, *toc, *page_no;
enum NotationSystem notation_system;
@@ -968,7 +952,7 @@ config_load(const char *filepath)
if (value.ok) {
notation_system = config_notation_system_parse(value.u.s);
if (notation_system == NS_CUSTOM) {
- notes = toml_table_table(table, "notation_systems");
+ notes = toml_table_table(toml, "notation_systems");
if (!notes) {
config_log(&ctx, LOG_ERR, "[output]", "Custom notation system '%s' has no corresponding definition in [notation_systems]");
return NULL;
@@ -1038,7 +1022,7 @@ config_load(const char *filepath)
lyrics_set_text_style_as_default(presences, config->output->styles);
}
}
- toml_table_t *parser = toml_table_table(table, "parser");
+ parser = toml_table_table(toml, "parser");
if (parser) {
toml_table_t *chords = toml_table_table(parser, "chords");
if (chords) {
@@ -1049,7 +1033,7 @@ config_load(const char *filepath)
if (value.ok) {
notation_system = config_notation_system_parse(value.u.s);
if (notation_system == NS_CUSTOM) {
- notes = toml_table_table(table, "notation_systems");
+ notes = toml_table_table(toml, "notation_systems");
if (!notes) {
config_log(&ctx, LOG_ERR, "[parser.chords]", "Custom notation system '%s' has no corresponding definition in [notation_systems].", value.u.s);
return NULL;
@@ -1080,11 +1064,59 @@ config_load(const char *filepath)
}
}
}
+ free(ctx.config_filepath);
+ return config;
+}
+
+struct Config *
+config_load_from_file(const char *filepath)
+{
+ struct Config *config = NULL;
+ toml_table_t *table = NULL;
+ FILE *fp = fopen(filepath, "r");
+ if (!fp) {
+ LOG_DEBUG("fopen failed.");
+ // util_log(NULL, 0, LOG_ERR, "Cannot open file '%s'.", filepath);
+ return NULL;
+ }
+ char errbuf[200];
+ table = toml_parse_file(fp, (char *)&errbuf, sizeof(errbuf));
+ if (!table) {
+ LOG_DEBUG("toml_parse_file failed.");
+ util_log(NULL, 0, LOG_ERR, "Config file '%s' is not a valid toml file: %s.", filepath, (char *)&errbuf);
+ goto CLEAN;
+ }
+ config = config_load(table, filepath);
+ if (!config) {
+ LOG_DEBUG("config_load failed.");
+ goto CLEAN;
+ }
+ CLEAN:
toml_free(table);
fclose(fp);
return config;
}
+struct Config *
+config_load_from_data(const char *data)
+{
+ struct Config *config = NULL;
+ toml_table_t *table = NULL;
+ char errbuf[200];
+ table = toml_parse((char *)data, (char *)&errbuf, sizeof(errbuf));
+ if (!table) {
+ LOG_DEBUG("toml_parse failed.");
+ util_log(NULL, 0, LOG_ERR, "Config data is not valid toml: %s.", (char *)&errbuf);
+ return NULL;
+ }
+ config = config_load(table, NULL);
+ if (!config) {
+ LOG_DEBUG("config_load failed.");
+ }
+ toml_free(table);
+ return config;
+}
+
void
config_free(struct Config *config)
{
diff --git a/src/config.h b/src/config.h
@@ -11,10 +11,13 @@
#endif /* DEBUG */
struct ConfigContext {
- char config_filepath[PATH_MAX];
+ char *config_filepath;
};
-struct Config *config_load(const char *filepath);
+struct Config *config_load_default(void);
+struct Config *config_load_from_file(const char *filepath);
+struct Config *config_load_from_data(const char *data);
+
void config_free(struct Config *config);
void config_print_default(void);
diff --git a/src/lorid.c b/src/lorid.c
@@ -28,6 +28,7 @@ main(int argc, char *argv[])
struct ChoSong **all_songs = NULL;
struct ChoSong **songs = NULL;
struct ChoSong **so;
+ struct Config *config;
int s = 0;
FILE *fp;
while ((o = getopt_long(argc, argv, "pc:o:Vvh", long_options, &option_index)) != -1) {
@@ -54,10 +55,27 @@ main(int argc, char *argv[])
return system("man lorid");
}
}
- struct Config *config = config_load(config_filepath);
- if (!config) {
- LOG_DEBUG("config_load failed.");
- return 1;
+ if (config_filepath) {
+ config = config_load_from_file(config_filepath);
+ if (!config) {
+ util_log(NULL, 0, LOG_ERR, "Failed to load the config file '%s'.", config_filepath);
+ return 1;
+ }
+ } else {
+ char *home = getenv("HOME");
+ if (!home) {
+ LOG_DEBUG("getenv failed.");
+ util_log(NULL, 0, LOG_ERR, "Failed to read the environment variable 'HOME'.");
+ return 1;
+ }
+ char default_config_path[26+strlen(home)+1];
+ sprintf(default_config_path, "%s/.config/lorid/config.toml", home);
+ printf("default config path '%s'\n", default_config_path);
+ config = config_load_from_file(default_config_path);
+ if (!config) {
+ printf("Loading default config instead of reading from a file.\n");
+ config = config_load_default();
+ }
}
free(config_filepath);
if (argc == optind) {