lorid

convert chordpro to pdf
git clone git://git.relim.de/lorid.git
Log | Files | Refs | README | LICENSE

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:
Msrc/config.c | 244+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/config.h | 7+++++--
Msrc/lorid.c | 26++++++++++++++++++++++----
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) {