lorid

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

commit e9915c1e0bb9e1a6960dcb194876b593a887c26f
parent a89f8c5ba65fd40c606e43d88a917e2a4b9d58fc
Author: nibo <nibo@relim.de>
Date:   Fri,  7 Mar 2025 18:41:43 +0100

Improve logging

Diffstat:
Msrc/chord_diagram.c | 8++++----
Msrc/chordpro.c | 50+++++++++++++++++++++++---------------------------
Msrc/config.c | 89++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/lorid.c | 2+-
Msrc/out_pdf.c | 31++++++++++++++++---------------
Msrc/out_pdf.h | 2--
Msrc/util.c | 95++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/util.h | 4+++-
8 files changed, 187 insertions(+), 94 deletions(-)

diff --git a/src/chord_diagram.c b/src/chord_diagram.c @@ -594,7 +594,7 @@ chord_diagram_copy_all_but_name(struct ChordDiagram *diagram) copy->u.kd = keyboard_diagram_copy_all_but_name(diagram->u.kd); break; default: - util_log(LOG_ERR, "Invalid ChordDiagram type '%d'", diagram->type); + util_log(NULL, 0, LOG_ERR, "Invalid ChordDiagram type '%d'", diagram->type); return NULL; } return copy; @@ -796,7 +796,7 @@ chord_diagrams_create( case INS_UKULELE: break; default: - util_log(LOG_ERR, "Invalid Instrument enum value '%d'.", config->output->diagram->instrument); + util_log(NULL, 0, LOG_ERR, "Invalid Instrument enum value '%d'.", config->output->diagram->instrument); } diagrams = erealloc(diagrams, (d+1) * sizeof(struct ChordDiagram *)); diagrams[d] = NULL; @@ -821,10 +821,10 @@ chord_diagram_draw( } break; case CDC_KEYBOARD: - util_log(LOG_TODO, "draw_keyboard_chord_diagram()"); + util_log(NULL, 0, LOG_TODO, "draw_keyboard_chord_diagram()"); break; case CDC_CHORD_MAP: - util_log(LOG_TODO, "well"); + util_log(NULL, 0, LOG_TODO, "well"); break; } return true; diff --git a/src/chordpro.c b/src/chordpro.c @@ -400,7 +400,6 @@ cho_rgbcolor_parse(const char *str) tmp[1] = str[2]; primary_color = strtol((char *)&tmp, NULL, 16); if (primary_color == 0) { - // cho_log(ctx, LOG_ERR, "Invalid primary color in rgb color."); free(color); return NULL; } else { @@ -414,7 +413,6 @@ cho_rgbcolor_parse(const char *str) tmp[1] = str[4]; primary_color = strtol((char *)&tmp, NULL, 16); if (primary_color == 0) { - // cho_log(ctx, LOG_ERR, "Invalid primary color in rgb color."); free(color); return NULL; } else { @@ -428,7 +426,6 @@ cho_rgbcolor_parse(const char *str) tmp[1] = str[6]; primary_color = strtol((char *)&tmp, NULL, 16); if (primary_color == 0) { - // cho_log(ctx, LOG_ERR, "Invalid primary color in rgb color."); free(color); return NULL; } else { @@ -444,7 +441,6 @@ cho_rgbcolor_parse(const char *str) tmp[1] = str[1]; primary_color = strtol((char *)&tmp, NULL, 16); if (primary_color == 0) { - // cho_log(ctx, LOG_ERR, "Invalid primary color in rgb color."); free(color); return NULL; } else { @@ -458,7 +454,6 @@ cho_rgbcolor_parse(const char *str) tmp[1] = str[2]; primary_color = strtol((char *)&tmp, NULL, 16); if (primary_color == 0) { - // cho_log(ctx, LOG_ERR, "Invalid primary color in rgb color."); free(color); return NULL; } else { @@ -472,7 +467,6 @@ cho_rgbcolor_parse(const char *str) tmp[1] = str[3]; primary_color = strtol((char *)&tmp, NULL, 16); if (primary_color == 0) { - // cho_log(ctx, LOG_ERR, "Invalid primary color in rgb color."); free(color); return NULL; } else { @@ -480,7 +474,6 @@ cho_rgbcolor_parse(const char *str) } } } else { - // cho_log(ctx, LOG_ERR, "Invalid rgb color."); free(color); return NULL; } @@ -538,8 +531,6 @@ cho_color_parse(const char *str) color->green = 0; color->blue = 0; } else { - // TODO: If this is called by config.c what should 'ctx' have as value - // cho_log(ctx, LOG_ERR, "Invalid color value '%s'.", str); free(color); return NULL; } @@ -1149,7 +1140,7 @@ cho_style_parse( style->font->family = FF_MONOSPACE; presence->font.family = true; } else { - cho_log(ctx, LOG_ERR, "Invalid value in attribute 'font_family/face'."); + cho_log(ctx, LOG_ERR, "Attribute 'font_family/face' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } else if (!strcmp(attrs[a]->name, "size")) { @@ -1163,11 +1154,11 @@ cho_style_parse( style->font->size *= percentage / 100.0; presence->font.size = true; } else { - cho_log(ctx, LOG_ERR, "Invalid percentage in attribute 'size'."); + cho_log(ctx, LOG_ERR, "Attribute 'size' of markup tag '%s' has an invalid percentage '%d'.", tag_name, percentage); return NULL; } } else { - cho_log(ctx, LOG_ERR, "Invalid percentage in attribute 'size'."); + cho_log(ctx, LOG_ERR, "Attribute 'size' of markup tag '%s' has an invalid percentage '%s'.", tag_name, attrs[a]->value); return NULL; } } else if (isdigit(attrs[a]->value[0]) != 0) { @@ -1176,7 +1167,7 @@ cho_style_parse( style->font->size = size; presence->font.size = true; } else { - cho_log(ctx, LOG_ERR, "Invalid number in attribute 'size'."); + cho_log(ctx, LOG_ERR, "Attribute 'size' of markup tag '%s' has an invalid number '%.1f'.", tag_name, size); return NULL; } } else if (!strcmp(attrs[a]->value, "xx-small")) { @@ -1211,7 +1202,7 @@ cho_style_parse( style->font->size *= 0.8; presence->font.size = true; } else { - cho_log(ctx, LOG_ERR, "Invalid value '%s' for the attribute 'size'.", attrs[a]->value); + cho_log(ctx, LOG_ERR, "Attribute 'size' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } else if (!strcmp(attrs[a]->name, "style")) { @@ -1225,7 +1216,7 @@ cho_style_parse( style->font->style = FS_ITALIC; presence->font.style = true; } else { - cho_log(ctx, LOG_ERR, "Invalid value in attribute 'style'."); + cho_log(ctx, LOG_ERR, "Attribute 'style' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } else if (!strcmp(attrs[a]->name, "weight")) { @@ -1236,13 +1227,14 @@ cho_style_parse( style->font->weight = FW_BOLD; presence->font.weight = true; } else { - cho_log(ctx, LOG_ERR, "Invalid value in attribute 'weight'."); + cho_log(ctx, LOG_ERR, "Attribute 'weight' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } else if (!strcmp(attrs[a]->name, "foreground")) { rgb_color = cho_color_parse(attrs[a]->value); if (!rgb_color) { LOG_DEBUG("cho_color_parse failed."); + cho_log(ctx, LOG_ERR, "Attribute 'foreground' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } else { free(style->foreground_color); @@ -1253,6 +1245,7 @@ cho_style_parse( rgb_color = cho_color_parse(attrs[a]->value); if (!rgb_color) { LOG_DEBUG("cho_color_parse failed."); + cho_log(ctx, LOG_ERR, "Attribute 'background' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } else { free(style->background_color); @@ -1270,13 +1263,14 @@ cho_style_parse( style->underline_style = LS_NONE; presence->underline_style = true; } else { - cho_log(ctx, LOG_ERR, "Invalid value in attribute 'underline'."); + cho_log(ctx, LOG_ERR, "Attribute 'underline' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } else if (!strcmp(attrs[a]->name, "underline_colour")) { rgb_color = cho_color_parse(attrs[a]->value); if (!rgb_color) { LOG_DEBUG("cho_color_parse failed."); + cho_log(ctx, LOG_ERR, "Attribute 'underline_colour' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } else { free(style->underline_color); @@ -1294,13 +1288,14 @@ cho_style_parse( style->overline_style = LS_NONE; presence->overline_style = true; } else { - cho_log(ctx, LOG_ERR, "Invalid value in attribute 'overline'."); + cho_log(ctx, LOG_ERR, "Attribute 'overline' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } else if (!strcmp(attrs[a]->name, "overline_colour")) { rgb_color = cho_color_parse(attrs[a]->value); if (!rgb_color) { LOG_DEBUG("cho_color_parse failed."); + cho_log(ctx, LOG_ERR, "Attribute 'overline_colour' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } else { free(style->overline_color); @@ -1319,7 +1314,7 @@ cho_style_parse( style->rise = (style->font->size / 2) * percentage / 100.0; presence->rise = true; } else { - cho_log(ctx, LOG_ERR, "Invalid percentage in attribute 'rise'."); + cho_log(ctx, LOG_ERR, "Attribute 'rise' of markup tag '%s' has an invalid percentage '%d'.", tag_name, percentage); return NULL; } } @@ -1329,11 +1324,11 @@ cho_style_parse( style->rise = rise; presence->rise = true; } else { - cho_log(ctx, LOG_ERR, "Invalid number in attribute 'rise'."); + cho_log(ctx, LOG_ERR, "Attribute 'rise' of markup tag '%s' has an invalid number '%d'.", tag_name, rise); return NULL; } } else { - cho_log(ctx, LOG_ERR, "Invalid value '%s' for the attribute 'rise'.", attrs[a]->value); + cho_log(ctx, LOG_ERR, "Attribute 'rise' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } else { @@ -1347,7 +1342,7 @@ cho_style_parse( style->rise += more; presence->rise = true; } else { - cho_log(ctx, LOG_ERR, "Invalid percentage in attribute 'rise'."); + cho_log(ctx, LOG_ERR, "Attribute 'rise' of markup tag '%s' has an invalid percentage '%d'.", tag_name, percentage); return NULL; } } @@ -1357,11 +1352,11 @@ cho_style_parse( style->rise = rise; presence->rise = true; } else { - cho_log(ctx, LOG_ERR, "Invalid number in attribute 'rise'."); + cho_log(ctx, LOG_ERR, "Attribute 'rise' of markup tag '%s' has an invalid number '%d'.", tag_name, rise); return NULL; } } else { - cho_log(ctx, LOG_ERR, "Invalid value '%s' for the attribute 'rise'.", attrs[a]->value); + cho_log(ctx, LOG_ERR, "Attribute 'rise' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } @@ -1373,13 +1368,14 @@ cho_style_parse( style->strikethrough = false; presence->strikethrough = true; } else { - cho_log(ctx, LOG_ERR, "Invalid value '%s' in attribute 'strikethrough'.", attrs[a]->value); + cho_log(ctx, LOG_ERR, "Attribute 'strikethrough' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } } else if (!strcmp(attrs[a]->name, "strikethrough_colour")) { rgb_color = cho_color_parse(attrs[a]->value); if (!rgb_color) { LOG_DEBUG("cho_color_parse failed."); + cho_log(ctx, LOG_ERR, "Attribute 'strikethrough_colour' of markup tag '%s' has an invalid value '%s'.", tag_name, attrs[a]->value); return NULL; } else { free(style->strikethrough_color); @@ -1390,7 +1386,7 @@ cho_style_parse( style->href = strdup(attrs[a]->value); presence->href = true; } else { - cho_log(ctx, LOG_ERR, "Invalid attribute '%s'.", attrs[a]->name); + cho_log(ctx, LOG_ERR, "Attribute '%s' of markup tag '%s' is invalid.", attrs[a]->name, tag_name); return NULL; } } @@ -1426,7 +1422,7 @@ cho_style_parse( style->underline_style = LS_SINGLE; presence->underline_style = true; } else { - cho_log(ctx, LOG_ERR, "Invalid tag name '%s'.", tag_name); + cho_log(ctx, LOG_ERR, "Markup tag '%s' is invalid.", tag_name); cho_style_free(style); return NULL; } diff --git a/src/config.c b/src/config.c @@ -1,7 +1,9 @@ #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #include <string.h> #include <toml.h> +#include <linux/limits.h> #include "types.h" #include "config.h" #include "chordpro.h" @@ -123,6 +125,23 @@ static struct Note notes_nashville[] = { { .note = "7", .sharp = NULL, .flat = "7b" }, }; +static char g_config_filepath[PATH_MAX]; + +static void +config_log( + enum LogLevel level, + const char *toml_section, + const char *msg, + ... +) +{ + va_list va; + va_start(va, msg); + char str[64]; + sprintf((char *)&str, "section %s: %s", toml_section, msg); + util_vlog(g_config_filepath, 0, level, str, va); +} + static enum TextType config_text_type_parse(const char *str) { @@ -316,7 +335,7 @@ config_notes_load(toml_table_t *notes, const char *system) toml_array_t *arr = toml_table_array(notes, system); int arr_len = toml_array_len(arr); if (arr_len != 7) { - util_log(LOG_ERR, "Custom notation system '%s' in [notation_systems] has to have exactly 7 items. For an example see `lorid --print-default-config`.", system); + config_log(LOG_ERR, "[notation_systems]", "Custom notation system '%s' has to have exactly 7 items. For an example see `lorid --print-default-config`.", system); free(notes); return NULL; } @@ -335,7 +354,7 @@ config_notes_load(toml_table_t *notes, const char *system) if (value.ok) { custom_notes[i]->sharp = value.u.s; if (i == 2 || i == 6) { - util_log(LOG_ERR, "Custom notation system '%s' in [notation_systems] can't have sharp value at array index '%d'.", system, i); + config_log(LOG_ERR, "[notation_systems]", "Custom notation system '%s' can't have sharp value at array index '%d'.", system, i); goto CLEAN; } } @@ -343,7 +362,7 @@ config_notes_load(toml_table_t *notes, const char *system) if (value.ok) { custom_notes[i]->flat = value.u.s; if (i == 0 || i == 3) { - util_log(LOG_ERR, "Custom notation system '%s' in [notation_systems] can't have flat value at array index '%d'.", system, i); + config_log(LOG_ERR, "[notation_systems]", "Custom notation system '%s' can't have flat value at array index '%d'.", system, i); goto CLEAN; } } @@ -545,7 +564,12 @@ config_print_default(void) } static bool -config_load_font(struct Font *font, toml_table_t *table, const char *key_name, struct ChoStylePresence *presence) +config_load_font( + struct Font *font, + toml_table_t *table, + struct ChoStylePresence *presence, + char (*err_buf)[25] +) { enum FontFamily family; enum FontStyle style; @@ -564,7 +588,9 @@ config_load_font(struct Font *font, toml_table_t *table, const char *key_name, s if (family != -1) { font->family = family; } else { - util_log(LOG_ERR, "Config section [output.styles.%s.font] family value is invalid.", key_name); + if (err_buf) { + strcpy((char *)err_buf, "family value is invalid."); + } return false; } free(value.u.s); @@ -576,7 +602,9 @@ config_load_font(struct Font *font, toml_table_t *table, const char *key_name, s if (style != -1) { font->style = style; } else { - util_log(LOG_ERR, "Config section [output.styles.%s.font] style value is invalid.", key_name); + if (err_buf) { + strcpy((char *)err_buf, "style value is invalid."); + } return false; } free(value.u.s); @@ -588,7 +616,9 @@ config_load_font(struct Font *font, toml_table_t *table, const char *key_name, s if (weight != -1) { font->weight = weight; } else { - util_log(LOG_ERR, "Config section [output.styles.%s.font] weight value is invalid.", key_name); + if (err_buf) { + strcpy((char *)err_buf, "weight value is invalid."); + } return false; } free(value.u.s); @@ -605,8 +635,8 @@ static bool config_load_style( struct ChoStyle *style, toml_table_t *table, - const char *key_name, - struct ChoStylePresence *presence + struct ChoStylePresence *presence, + char (*err_buf)[38] ) { toml_value_t value; @@ -614,8 +644,10 @@ config_load_style( enum LineStyle line_style; toml_table_t *font_section = toml_table_table(table, "font"); if (font_section) { - if (!config_load_font(style->font, font_section, key_name, presence)) { + char err[25]; + if (!config_load_font(style->font, font_section, presence, &err)) { LOG_DEBUG("config_load_font failed."); + sprintf((char *)err_buf, "font.%s", err); return false; } } @@ -627,7 +659,7 @@ config_load_style( free(style->foreground_color); style->foreground_color = color; } else { - util_log(LOG_ERR, "Config section [output.styles.%s] foreground color value is invalid.", key_name); + strcpy((char *)err_buf, "foreground color value is invalid."); return false; } free(value.u.s); @@ -640,7 +672,7 @@ config_load_style( free(style->background_color); style->background_color = color; } else { - util_log(LOG_ERR, "Config section [output.styles.%s] background color value is invalid.", key_name); + strcpy((char *)err_buf, "background color value is invalid."); return false; } free(value.u.s); @@ -652,7 +684,7 @@ config_load_style( if (line_style != -1) { style->underline_style = line_style; } else { - util_log(LOG_ERR, "Config section [output.styles.%s] underline style value is invalid.", key_name); + strcpy((char *)err_buf, "underline style value is invalid."); return false; } free(value.u.s); @@ -665,7 +697,7 @@ config_load_style( free(style->underline_color); style->underline_color = color; } else { - util_log(LOG_ERR, "Config section [output.styles.%s] underline color value is invalid.", key_name); + strcpy((char *)err_buf, "underline color value is invalid."); return false; } free(value.u.s); @@ -677,7 +709,7 @@ config_load_style( if (line_style != -1) { style->overline_style = line_style; } else { - util_log(LOG_ERR, "Config section [output.styles.%s] overline style value is invalid.", key_name); + strcpy((char *)err_buf, "overline style value is invalid."); return false; } free(value.u.s); @@ -690,7 +722,7 @@ config_load_style( free(style->overline_color); style->overline_color = color; } else { - util_log(LOG_ERR, "Config section [output.styles.%s] overline color valeu is invalid.", key_name); + strcpy((char *)err_buf, "overline color value is invalid."); return false; } free(value.u.s); @@ -708,7 +740,7 @@ config_load_style( free(style->strikethrough_color); style->strikethrough_color = color; } else { - util_log(LOG_ERR, "Config section [output.styles.%s] strikethrough color value is invalid.", key_name); + strcpy((char *)err_buf, "strikethrough color value is invalid."); return false; } free(value.u.s); @@ -726,7 +758,7 @@ config_load_style( free(style->boxed_color); style->boxed_color = color; } else { - util_log(LOG_ERR, "Config section [output.styles.%s] boxed color value is invalid.", key_name); + strcpy((char *)err_buf, "boxed color value is invalid."); return false; } free(value.u.s); @@ -876,16 +908,17 @@ config_load(const char *filepath) sprintf(path, "%s/.config/lorid/config.toml", home); filepath = path; } + strcpy(g_config_filepath, filepath); FILE *fp = fopen(filepath, "r"); if (!fp) { - util_log(LOG_INFO, "Couldn't open config file '%s'. Using default configuration.", filepath); + 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(LOG_ERR, "Config file is not a valid toml file: %s.", (char *)&errbuf); + util_log(NULL, 0, LOG_ERR, "Config file '%s' is not a valid toml file: %s.", filepath, (char *)&errbuf); return NULL; } toml_table_t *output = toml_table_table(table, "output"); @@ -930,7 +963,7 @@ config_load(const char *filepath) if (value.ok) { instrument = config_instrument_parse(value.u.s); if (instrument == -1) { - util_log(LOG_ERR, "Unknown instrument '%s' in [output.chord_diagram].", value.u.s); + config_log(LOG_ERR, "[output.chord_diagram]", "Unknown instrument '%s'.", value.u.s); return NULL; } config->output->diagram->instrument = instrument; @@ -943,7 +976,7 @@ config_load(const char *filepath) if (notation_system == NS_CUSTOM) { notes = toml_table_table(table, "notation_systems"); if (!notes) { - util_log(LOG_ERR, "Custom notation system '%s' has no corresponding definition in [notation_systems].", value.u.s); + config_log(LOG_ERR, "[output]", "Custom notation system '%s' has no corresponding definition in [notation_systems]"); return NULL; } custom_notes = config_notes_load(notes, value.u.s); @@ -952,7 +985,7 @@ config_load(const char *filepath) config->output->notes = custom_notes; } else { LOG_DEBUG("config_notes_load failed."); - util_log(LOG_ERR, "Couldn't load custom notation system '%s' from [notation_systems] section.", value.u.s); + config_log(LOG_ERR, "[output]", "Couldn't load custom notation system '%s' from [notation_systems] section.", value.u.s); return NULL; } } else { @@ -997,8 +1030,12 @@ config_load(const char *filepath) key = toml_table_table(styles, key_name); if (key) { style = config->output->styles[ttype]; - if (!config_load_style(style, key, key_name, &presences[ttype])) { + char toml_section_name[16+strlen(key_name)+1]; + char err[38]; + sprintf((char *)&toml_section_name, "[output.styles.%s]", key_name); + if (!config_load_style(style, key, &presences[ttype], &err)) { LOG_DEBUG("config_load_style failed."); + config_log(LOG_ERR, toml_section_name, err); return NULL; } } @@ -1021,7 +1058,7 @@ config_load(const char *filepath) if (notation_system == NS_CUSTOM) { notes = toml_table_table(table, "notation_systems"); if (!notes) { - util_log(LOG_ERR, "Custom notation system '%s' has no corresponding definition in [notation_systems].", value.u.s); + config_log(LOG_ERR, "[parser.chords]", "Custom notation system '%s' has no corresponding definition in [notation_systems].", value.u.s); return NULL; } custom_notes = config_notes_load(notes, value.u.s); @@ -1030,7 +1067,7 @@ config_load(const char *filepath) config->parser->notes = custom_notes; } else { LOG_DEBUG("config_notes_load failed."); - util_log(LOG_ERR, "Couldn't load custom notation system '%s' from [notation_systems] section.", value.u.s); + config_log(LOG_ERR, "[parser.chords]", "Couldn't load custom notation system '%s' from [notation_systems] section.", value.u.s); return NULL; } } else { diff --git a/src/lorid.c b/src/lorid.c @@ -115,7 +115,7 @@ main(int argc, char *argv[]) LOG_DEBUG("out_pdf_new failed."); return 1; } - util_log(LOG_INFO, "Writing pdf to file: '%s'.", pdf_filename); + util_log(NULL, 0, LOG_INFO, "Writing pdf to file: '%s'.", pdf_filename); free(pdf_filename); free(output); cho_songs_free(all_songs); diff --git a/src/out_pdf.c b/src/out_pdf.c @@ -8,6 +8,7 @@ #include <fontconfig/fontconfig.h> #include <grapheme.h> #include <math.h> +#include <linux/limits.h> #include "types.h" #include "out_pdf.h" #include "chordpro.h" @@ -278,7 +279,7 @@ fontpath_find(struct Font *font, enum FontType font_type) style.u.i = FC_SLANT_ITALIC; break; default: - util_log(LOG_ERR, "Invalid font style value '%d'.", font->style); + util_log(NULL, 0, LOG_ERR, "Invalid font style value '%d'.", font->style); return NULL; } FcPatternAdd(pattern, FC_SLANT, style, FcFalse); @@ -292,7 +293,7 @@ fontpath_find(struct Font *font, enum FontType font_type) weight.u.i = FC_WEIGHT_BOLD; break; default: - util_log(LOG_ERR, "Invalid font weight value '%d'.", font->weight); + util_log(NULL, 0, LOG_ERR, "Invalid font weight value '%d'.", font->weight); return NULL; } FcPatternAdd(pattern, FC_WEIGHT, weight, FcFalse); @@ -383,7 +384,7 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config) return false; } free(fontpath); - util_log(LOG_INFO, "Loaded font from '%s'.", (*f)->name); + util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", (*f)->name); // cho_font_print(*f); objs_add_obj(&g_fonts, fnt); } else @@ -406,7 +407,7 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config) LOG_DEBUG("pdfioFileCreateFontObjFromFile failed."); return false; } - util_log(LOG_INFO, "Loaded font from '%s'.", fontpath); + util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", fontpath); // cho_font_print(*f); objs_add_obj(&g_fonts, fnt); free(fontpath); @@ -420,12 +421,12 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config) LOG_DEBUG("pdfioFileCreateFontObjFromFile failed."); return false; } - util_log(LOG_INFO, "Loaded font from '%s'.", fontpath); + util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", fontpath); // cho_font_print(*f); objs_add_obj(&g_fonts, fnt); free(fontpath); } else { - util_log(LOG_ERR, "Didn't find font file for following font:"); + util_log(NULL, 0, LOG_ERR, "Didn't find font file for following font:"); cho_font_print(*f); return false; } @@ -454,7 +455,7 @@ pdf_filename_generate_from_songs(struct ChoSong **songs) title = cho_metadata_get(songs[0]->metadata, "title"); if (!title) { /* INFO: unreachable because the parser already checks the presence of the 'title' directive */ - util_log(LOG_ERR, "Song has no title."); + util_log(NULL, 0, LOG_ERR, "Song has no title."); return NULL; } normalized_title = str_normalize(title); @@ -494,7 +495,7 @@ pdf_filepath_create(struct ChoSong **songs, const char *cho_filepath, const char return strdup(out); } else { free(tmp); - util_log(LOG_ERR, "Invalid argument --output/-o value."); + util_log(NULL, 0, LOG_ERR, "Invalid argument --output/-o value."); return NULL; } break; @@ -510,10 +511,10 @@ pdf_filepath_create(struct ChoSong **songs, const char *cho_filepath, const char free(pdf_filepath); return tmp; case F_OTHER: - util_log(LOG_ERR, "Invalid argument --output/-o value. It doesn't refer to a folder or regular file."); + util_log(NULL, 0, LOG_ERR, "Invalid argument --output/-o value. It doesn't refer to a folder or regular file."); return NULL; default: - util_log(LOG_ERR, "Invalid enum FileType value '%d'.", type); + util_log(NULL, 0, LOG_ERR, "Invalid enum FileType value '%d'.", type); return NULL; } } else { @@ -614,7 +615,7 @@ text_find_fitting( do { i = find_whitespace((const char *)&tmp, start); if (i == -1) { - util_log(LOG_ERR, "Can't split text because no whitespace was found."); + util_log(NULL, 0, LOG_ERR, "Can't split text because no whitespace was found."); return -1; } tmp[i] = 0; @@ -1001,7 +1002,7 @@ image_name(struct ChoImage *image) } if (stat(image_path, &s)) { LOG_DEBUG("stat failed."); - util_log(LOG_ERR, "%s: %s", image_path, strerror(errno)); + util_log(NULL, 0, LOG_ERR, "%s: %s", image_path, strerror(errno)); return NULL; } memset(tmp, 0, PATH_MAX); @@ -1048,7 +1049,7 @@ pdf_load_images(struct Obj ***images, pdfio_file_t *file, struct ChoSong **songs LOG_DEBUG("pdfioFileCreateImageObjFromFile failed."); return false; } - util_log(LOG_INFO, "Loaded image from '%s'.", image_filepath); + util_log(NULL, 0, LOG_INFO, "Loaded image from '%s'.", image_filepath); (*images)[i+1] = NULL; } free(name); @@ -1697,7 +1698,7 @@ static const char * numeral_system_western_arabic_to_roman(unsigned int n) { if (n > 999) { - util_log(LOG_ERR, "Converting numbers higher than 999 is not supported."); + util_log(NULL, 0, LOG_ERR, "Converting numbers higher than 999 is not supported."); return NULL; } const char *str; @@ -1793,7 +1794,7 @@ pdf_page_add_page_no(struct PDFContext *ctx, enum NumeralSystem numeral_system) x = MEDIABOX_WIDTH - MARGIN_HORIZONTAL / 2 - width; break; default: - util_log(LOG_ERR, "Invalid Alignment enum value '%d'.", g_config->output->page_no->align); + util_log(NULL, 0, LOG_ERR, "Invalid Alignment enum value '%d'.", g_config->output->page_no->align); return false; } (*texts)[ctx->text]->x = x; diff --git a/src/out_pdf.h b/src/out_pdf.h @@ -13,8 +13,6 @@ #define SECTION_GAP_WIDTH 10.0 #define TOC_DOTS_GAP_WIDTH 10.0 -#define PATH_MAX 4096 - enum LineLocation { LL_OVER, LL_STRIKETHROUGH, diff --git a/src/util.c b/src/util.c @@ -2,6 +2,7 @@ #include <stdlib.h> #include <stdbool.h> #include <stdarg.h> +#include <unistd.h> #include <ctype.h> #include <string.h> #include <sys/stat.h> @@ -41,62 +42,120 @@ erealloc(void *ptr, size_t size) return tmp; } -void -util_log(enum LogLevel level, const char *msg, ...) +static void +log_without_color( + const char *file, + size_t line_no, + enum LogLevel level, + const char *msg, + va_list va +) { - if (level == LOG_INFO && !g_show_info_logs) { - return; + if (file) { + fprintf(stderr, "%s", file); + } + if (line_no > 0) { + fprintf(stderr, ":%ld", line_no); } -#if COLOR == 1 const char *log_level = ""; - const char *color = ""; switch (level) { case LOG_INFO: log_level = "INFO"; - color = "37"; break; case LOG_WARN: log_level = "WARN"; - color = "33"; break; case LOG_ERR: log_level = " ERR"; - color = "31"; break; case LOG_TODO: log_level = "TODO"; - color = "34"; break; } - fprintf(stderr, "\033[1;%sm%s\033[0m: ", color, log_level); - va_list va; - va_start(va, msg); + fprintf(stderr, "%s: ", log_level); + // va_list va; + // va_start(va, msg); vfprintf(stderr, msg, va); fprintf(stderr, "\n"); -#else +} + +static void +log_with_color( + const char *file, + size_t line_no, + enum LogLevel level, + const char *msg, + va_list va +) +{ + if (file) { + fprintf(stderr, "\033[1m%s\033[0m", file); + if (line_no > 0) { + fprintf(stderr, "\033[1;:%ld\033[0m", line_no); + } + } const char *log_level = ""; + const char *color = ""; switch (level) { case LOG_INFO: log_level = "INFO"; + color = "37"; break; case LOG_WARN: log_level = "WARN"; + color = "33"; break; case LOG_ERR: log_level = " ERR"; + color = "31"; break; case LOG_TODO: log_level = "TODO"; + color = "34"; break; } - fprintf(stderr, "%s: ", log_level); - va_list va; - va_start(va, msg); + fprintf(stderr, " \033[1;%sm%s\033[0m: ", color, log_level); vfprintf(stderr, msg, va); fprintf(stderr, "\n"); +} + +void +util_vlog( + const char *file, + size_t line_no, + enum LogLevel level, + const char *msg, + va_list va +) +{ + if (level == LOG_INFO && !g_show_info_logs) { + return; + } +#if COLOR == 1 + if (isatty(2)) { + log_with_color(file, line_no, level, msg, va); + } else { + log_without_color(file, line_no, level, msg, va); + } +#else + log_without_color(file, line_no, level, msg, va); #endif } +void +util_log( + const char *file, + size_t line_no, + enum LogLevel level, + const char *msg, + ... +) +{ + va_list va; + va_start(va, msg); + util_vlog(file, line_no, level, msg, va); +} + bool str_starts_with(const char *str, const char *part) { @@ -487,7 +546,7 @@ size_create(const char *str) size->type = ST_POINT; if (len > 1 && str[len-1] == '%') { if (size->d < 1.0 || size->d > 100.0) { - util_log(LOG_ERR, "invalid percentage."); + util_log(NULL, 0, LOG_ERR, "invalid percentage."); return NULL; } size->d = d / 100.0; diff --git a/src/util.h b/src/util.h @@ -1,3 +1,4 @@ +#include <stdarg.h> #include "types.h" #ifdef DEBUG @@ -32,7 +33,8 @@ void util_log_enable_info_logs(void); void *emalloc(size_t size); void *erealloc(void *ptr, size_t size); -void util_log(enum LogLevel level, const char *msg, ...); +void util_vlog(const char *file, size_t line_no, enum LogLevel level, const char *msg, va_list va); +void util_log(const char *file, size_t line_no, enum LogLevel level, const char *msg, ...); bool str_starts_with(const char *str, const char *part); char *str_normalize(const char *str);