config: add LOG_CONTEXTUAL_{ERR,WARN,ERRNO}

These work like LOG_AND_NOTIFY_* but add contextual information: path
of the conf file, line number, section name, key/option name and the
value.
This commit is contained in:
Daniel Eklöf 2021-11-05 17:13:39 +01:00
parent 534e9d8bef
commit 176b85cb10
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 170 additions and 295 deletions

462
config.c
View file

@ -133,78 +133,113 @@ struct context {
bool errors_are_fatal; bool errors_are_fatal;
}; };
static void NOINLINE PRINTF(5) static const enum user_notification_kind log_class_to_notify_kind[LOG_CLASS_COUNT] = {
log_and_notify(struct context *ctx, enum log_class log_class, [LOG_CLASS_WARNING] = USER_NOTIFICATION_WARNING,
const char *file, int lineno, const char *fmt, ...) [LOG_CLASS_ERROR] = USER_NOTIFICATION_ERROR,
};
static void NOINLINE VPRINTF(5)
log_and_notify_va(struct config *conf, enum log_class log_class,
const char *file, int lineno, const char *fmt, va_list va)
{ {
enum user_notification_kind kind; xassert(log_class < ALEN(log_class_to_notify_kind));
enum user_notification_kind kind = log_class_to_notify_kind[log_class];
switch (log_class) { if (kind == 0) {
case LOG_CLASS_WARNING: kind = USER_NOTIFICATION_WARNING; break;
case LOG_CLASS_ERROR: kind = USER_NOTIFICATION_ERROR; break;
case LOG_CLASS_INFO:
case LOG_CLASS_DEBUG:
case LOG_CLASS_NONE:
default:
BUG("unsupported log class: %d", (int)log_class); BUG("unsupported log class: %d", (int)log_class);
return; return;
} }
va_list va1, va2; char *formatted_msg = xvasprintf(fmt, va);
va_start(va1, fmt); log_msg(log_class, LOG_MODULE, file, lineno, formatted_msg);
va_copy(va2, va1);
log_msg_va(log_class, LOG_MODULE, file, lineno, fmt, va1);
char *text = xvasprintf(fmt, va2);
tll_push_back( tll_push_back(
ctx->conf->notifications, conf->notifications,
((struct user_notification){.kind = kind, .text = text})); ((struct user_notification){.kind = kind, .text = formatted_msg}));
va_end(va2);
va_end(va1);
} }
static void NOINLINE PRINTF(5) static void NOINLINE PRINTF(5)
log_errno_and_notify(struct context *ctx, enum log_class log_class, log_and_notify(struct config *conf, enum log_class log_class,
const char *file, int lineno, const char *fmt, ...) const char *file, int lineno, const char *fmt, ...)
{ {
int errno_copy = errno; va_list va;
va_start(va, fmt);
va_list va1, va2, va3; log_and_notify_va(conf, log_class, file, lineno, fmt, va);
va_start(va1, fmt); va_end(va);
va_copy(va2, va1);
va_copy(va3, va2);
log_errno_provided_va(
log_class, LOG_MODULE, file, lineno, errno_copy, fmt, va1);
int len = vsnprintf(NULL, 0, fmt, va2);
int errno_len = snprintf(NULL, 0, ": %s", strerror(errno_copy));
char *text = xmalloc(len + errno_len + 1);
vsnprintf(text, len + errno_len + 1, fmt, va3);
snprintf(&text[len], errno_len + 1, ": %s", strerror(errno_copy));
tll_push_back(
ctx->conf->notifications,
((struct user_notification){
.kind = USER_NOTIFICATION_ERROR, .text = text}));
va_end(va3);
va_end(va2);
va_end(va1);
} }
static void NOINLINE PRINTF(5)
log_contextual(struct context *ctx, enum log_class log_class,
const char *file, int lineno, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
char *formatted_msg = xvasprintf(fmt, va);
va_end(va);
log_and_notify(
ctx->conf, log_class, file, lineno, "%s:%d: [%s].%s: %s: %s",
ctx->path, ctx->lineno, ctx->section, ctx->key, ctx->value,
formatted_msg);
free(formatted_msg);
}
static void NOINLINE VPRINTF(4)
log_and_notify_errno_va(struct config *conf, const char *file, int lineno,
const char *fmt, va_list va)
{
int errno_copy = errno;
char *formatted_msg = xvasprintf(fmt, va);
log_and_notify(
conf, LOG_CLASS_ERROR, file, lineno,
"%s: %s", formatted_msg, strerror(errno_copy));
free(formatted_msg);
}
static void NOINLINE PRINTF(4)
log_and_notify_errno(struct config *conf, const char *file, int lineno,
const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
log_and_notify_errno_va(conf, file, lineno, fmt, va);
va_end(va);
}
static void NOINLINE PRINTF(4)
log_contextual_errno(struct context *ctx, const char *file, int lineno,
const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
char *formatted_msg = xvasprintf(fmt, va);
va_end(va);
log_and_notify_errno(
ctx->conf, file, lineno, "%s:%d: [%s].%s: %s: %s",
ctx->path, ctx->lineno, ctx->section, ctx->key, ctx->value,
formatted_msg);
free(formatted_msg);
}
#define LOG_CONTEXTUAL_ERR(...) \
log_contextual(ctx, LOG_CLASS_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define LOG_CONTEXTUAL_WARN(...) \
log_contextual(ctx, LOG_CLASS_WARNING, __FILE__, __LINE__, __VA_ARGS__)
#define LOG_CONTEXTUAL_ERRNO(...) \
log_contextual_errno(ctx, __FILE__, __LINE__, __VA_ARGS__)
#define LOG_AND_NOTIFY_ERR(...) \ #define LOG_AND_NOTIFY_ERR(...) \
log_and_notify(ctx, LOG_CLASS_ERROR, __FILE__, __LINE__, __VA_ARGS__) log_and_notify(conf, LOG_CLASS_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define LOG_AND_NOTIFY_WARN(...) \ #define LOG_AND_NOTIFY_WARN(...) \
log_and_notify(ctx, LOG_CLASS_WARNING, __FILE__, __LINE__, __VA_ARGS__) log_and_notify(conf, LOG_CLASS_WARNING, __FILE__, __LINE__, __VA_ARGS__)
#define LOG_AND_NOTIFY_ERRNO(...) \ #define LOG_AND_NOTIFY_ERRNO(...) \
log_errno_and_notify(ctx, LOG_CLASS_ERROR, __FILE__, __LINE__, __VA_ARGS__) log_and_notify_errno(conf, __FILE__, __LINE__, __VA_ARGS__)
static char * static char *
get_shell(void) get_shell(void)
@ -471,8 +506,7 @@ value_to_wchars(struct context *ctx, wchar_t **res)
size_t chars = mbstowcs(NULL, ctx->value, 0); size_t chars = mbstowcs(NULL, ctx->value, 0);
if (chars == (size_t)-1) { if (chars == (size_t)-1) {
LOG_AND_NOTIFY_ERR("%s:%d: [%s].%s: %s is not a valid string value", LOG_CONTEXTUAL_ERR("not a valid string value");
ctx->path, ctx->lineno, ctx->section, ctx->key, ctx->value);
return false; return false;
} }
@ -486,16 +520,12 @@ value_to_color(struct context *ctx, uint32_t *color, bool allow_alpha)
{ {
unsigned long value; unsigned long value;
if (!value_to_ulong(ctx, 16, &value)) { if (!value_to_ulong(ctx, 16, &value)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not a valid color value");
"%s:%d: [%s].%s: %s is not a valid color value",
ctx->path, ctx->lineno, ctx->section, ctx->key, ctx->value);
return false; return false;
} }
if (!allow_alpha && (value & 0xff000000) != 0) { if (!allow_alpha && (value & 0xff000000) != 0) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("color value must not have an alpha component");
"%s:%d: [%s].%s: %s: color value must not have an alpha component",
ctx->path, ctx->lineno, ctx->section, ctx->key, ctx->value);
return false; return false;
} }
@ -516,9 +546,7 @@ value_to_two_colors(struct context *ctx,
const char *second_as_str = strtok(NULL, " "); const char *second_as_str = strtok(NULL, " ");
if (first_as_str == NULL || second_as_str == NULL) { if (first_as_str == NULL || second_as_str == NULL) {
LOG_AND_NOTIFY_ERR("%s:%d: [%s].%s: %s: invalid double color value", LOG_CONTEXTUAL_ERR("invalid double color value");
ctx->path, ctx->lineno, ctx->section, ctx->key,
ctx->value);
goto out; goto out;
} }
@ -550,10 +578,7 @@ value_to_pt_or_px(struct context *ctx, struct pt_or_px *res)
long value = strtol(s, &end, 10); long value = strtol(s, &end, 10);
if (!(errno == 0 && end == s + len - 2)) { if (!(errno == 0 && end == s + len - 2)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid px value (must be on the form 12px)");
"%s:%d: [%s].%s: %s: invalid px value "
"(must be on the form 12px)",
ctx->path, ctx->lineno, ctx->section, ctx->key, ctx->value);
return false; return false;
} }
res->pt = 0; res->pt = 0;
@ -561,9 +586,7 @@ value_to_pt_or_px(struct context *ctx, struct pt_or_px *res)
} else { } else {
double value; double value;
if (!value_to_double(ctx, &value)) { if (!value_to_double(ctx, &value)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid decimal value");
"%s:%d: [%s].%s: %s: invalid decimal value",
ctx->path, ctx->lineno, ctx->section, ctx->key, ctx->value);
return false; return false;
} }
res->pt = value; res->pt = value;
@ -594,9 +617,8 @@ value_to_fonts(struct context *ctx)
struct config_font font_data; struct config_font font_data;
if (!config_font_parse(font, &font_data)) { if (!config_font_parse(font, &font_data)) {
LOG_AND_NOTIFY_ERR( ctx->value = font;
"%s:%d: [%s].%s: %s: invalid font specification", LOG_CONTEXTUAL_ERR("invalid font specification");
ctx->path, ctx->lineno, ctx->section, ctx->key, font);
goto err; goto err;
} }
@ -673,9 +695,7 @@ value_to_spawn_template(struct context *ctx,
char **argv = NULL; char **argv = NULL;
if (!tokenize_cmdline(ctx->value, &argv)) { if (!tokenize_cmdline(ctx->value, &argv)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("syntax error in command line");
"%s:%d: [%s].%s: %s: syntax error in command line",
ctx->path, ctx->lineno, ctx->section, ctx->key, ctx->value);
return false; return false;
} }
@ -724,9 +744,7 @@ parse_section_main(struct context *ctx)
const char *home_dir = get_user_home_dir(); const char *home_dir = get_user_home_dir();
if (home_dir == NULL) { if (home_dir == NULL) {
LOG_AND_NOTIFY_ERRNO( LOG_CONTEXTUAL_ERRNO("failed to expand '~'");
"%s:%d: [main].include: %s: failed to expand '~'",
path, lineno, value);
return false; return false;
} }
@ -736,9 +754,7 @@ parse_section_main(struct context *ctx)
include_path = value; include_path = value;
if (include_path[0] != '/') { if (include_path[0] != '/') {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not an absolute path");
"%s:%d: [main].include: %s: not an absolute path",
path, lineno, include_path);
free(_include_path); free(_include_path);
return false; return false;
} }
@ -746,9 +762,7 @@ parse_section_main(struct context *ctx)
FILE *include = fopen(include_path, "r"); FILE *include = fopen(include_path, "r");
if (include == NULL) { if (include == NULL) {
LOG_AND_NOTIFY_ERRNO( LOG_CONTEXTUAL_ERRNO("failed to open");
"%s:%d: [main].include: %s: failed to open",
path, lineno, include_path);
free(_include_path); free(_include_path);
return false; return false;
} }
@ -792,9 +806,7 @@ parse_section_main(struct context *ctx)
else if (strcmp(key, "initial-window-size-pixels") == 0) { else if (strcmp(key, "initial-window-size-pixels") == 0) {
unsigned width, height; unsigned width, height;
if (sscanf(value, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) { if (sscanf(value, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid size (must be on the form WIDTHxHEIGHT)");
"%s:%d: [main].initial-window-size-pixels: %s: invalid size "
"(must be on the form WIDTHxHEIGHT)", path, lineno, value);
return false; return false;
} }
@ -806,9 +818,7 @@ parse_section_main(struct context *ctx)
else if (strcmp(key, "initial-window-size-chars") == 0) { else if (strcmp(key, "initial-window-size-chars") == 0) {
unsigned width, height; unsigned width, height;
if (sscanf(value, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) { if (sscanf(value, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid size (must be on the form WIDTHxHEIGHT)");
"%s:%d: [main].initial-window-size-chars: %s: invalid size "
"(must be on the form WIDTHxHEIGHT)", path, lineno, value);
return false; return false;
} }
@ -826,10 +836,8 @@ parse_section_main(struct context *ctx)
bool invalid_mode = !center && mode[0] != '\0'; bool invalid_mode = !center && mode[0] != '\0';
if ((ret != 2 && ret != 3) || invalid_mode) { if ((ret != 2 && ret != 3) || invalid_mode) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR(
"%s:%d: [main].pad: %s: invalid padding " "invalid padding (must be on the form PAD_XxPAD_Y [center])");
"(must be on the form PAD_XxPAD_Y [center])",
path, lineno, value);
return false; return false;
} }
@ -841,9 +849,7 @@ parse_section_main(struct context *ctx)
else if (strcmp(key, "resize-delay-ms") == 0) { else if (strcmp(key, "resize-delay-ms") == 0) {
unsigned long ms; unsigned long ms;
if (!value_to_ulong(ctx, 10, &ms)) { if (!value_to_ulong(ctx, 10, &ms)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%d: [main].resize-delay-ms: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
@ -887,10 +893,7 @@ parse_section_main(struct context *ctx)
memset(&conf->bell, 0, sizeof(conf->bell)); memset(&conf->bell, 0, sizeof(conf->bell));
} }
else { else {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'set-urgency', 'notify' or 'none'");
"%s%d: [main].bell: %s: "
"not one of 'set-urgency', 'notify' or 'none'",
path, lineno, value);
return false; return false;
} }
} }
@ -903,10 +906,7 @@ parse_section_main(struct context *ctx)
else if (strcmp(value, "fullscreen") == 0) else if (strcmp(value, "fullscreen") == 0)
conf->startup_mode = STARTUP_FULLSCREEN; conf->startup_mode = STARTUP_FULLSCREEN;
else { else {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'windows', 'maximized' or 'fullscreen'");
"%s:%d: [main].initial-window-mode: %s: not one of "
"'windows', 'maximized' or 'fullscreen'",
path, lineno, value);
return false; return false;
} }
} }
@ -966,9 +966,7 @@ parse_section_main(struct context *ctx)
else if (strcmp(key, "workers") == 0) { else if (strcmp(key, "workers") == 0) {
unsigned long count; unsigned long count;
if (!value_to_ulong(ctx, 10, &count)) { if (!value_to_ulong(ctx, 10, &count)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%d: [main].workers: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
conf->render_worker_count = count; conf->render_worker_count = count;
@ -1027,10 +1025,7 @@ parse_section_main(struct context *ctx)
} }
} }
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'none', 'primary', 'clipboard' or 'both");
"%s:%d: [main].selection-target: %s: not one of "
"'none', 'primary', 'clipboard' or 'both",
path, lineno, value);
return false; return false;
} }
@ -1043,9 +1038,7 @@ parse_section_main(struct context *ctx)
else if (strcmp(value, "always") == 0) else if (strcmp(value, "always") == 0)
conf->url.osc8_underline = OSC8_UNDERLINE_ALWAYS; conf->url.osc8_underline = OSC8_UNDERLINE_ALWAYS;
else { else {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'url-mode', or 'always'");
"%s:%u: [main].osc8-underline: %s: not one of "
"'url-mode', or 'always'", path, lineno, value);
return false; return false;
} }
} }
@ -1054,8 +1047,7 @@ parse_section_main(struct context *ctx)
conf->box_drawings_uses_font_glyphs = value_to_bool(ctx); conf->box_drawings_uses_font_glyphs = value_to_bool(ctx);
else { else {
LOG_AND_NOTIFY_ERR("%s:%u: [main].%s is not a valid option", LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
path, lineno, key);
return false; return false;
} }
@ -1067,8 +1059,6 @@ parse_section_bell(struct context *ctx)
{ {
struct config *conf = ctx->conf; struct config *conf = ctx->conf;
const char *key = ctx->key; const char *key = ctx->key;
const char *path = ctx->path;
unsigned lineno = ctx->lineno;
if (strcmp(key, "urgent") == 0) if (strcmp(key, "urgent") == 0)
conf->bell.urgent = value_to_bool(ctx); conf->bell.urgent = value_to_bool(ctx);
@ -1081,8 +1071,7 @@ parse_section_bell(struct context *ctx)
else if (strcmp(key, "command-focused") == 0) else if (strcmp(key, "command-focused") == 0)
conf->bell.command_focused = value_to_bool(ctx); conf->bell.command_focused = value_to_bool(ctx);
else { else {
LOG_AND_NOTIFY_ERR("%s:%u: [bell].%s is not a valid option", LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
path, lineno, key);
return false; return false;
} }
@ -1095,15 +1084,11 @@ parse_section_scrollback(struct context *ctx)
struct config *conf = ctx->conf; struct config *conf = ctx->conf;
const char *key = ctx->key; const char *key = ctx->key;
const char *value = ctx->value; const char *value = ctx->value;
const char *path = ctx->path;
unsigned lineno = ctx->lineno;
if (strcmp(key, "lines") == 0) { if (strcmp(key, "lines") == 0) {
unsigned long lines; unsigned long lines;
if (!value_to_ulong(ctx, 10, &lines)) { if (!value_to_ulong(ctx, 10, &lines)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%d: [scrollback].lines: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
conf->scrollback.lines = lines; conf->scrollback.lines = lines;
@ -1117,10 +1102,7 @@ parse_section_scrollback(struct context *ctx)
else if (strcmp(value, "relative") == 0) else if (strcmp(value, "relative") == 0)
conf->scrollback.indicator.position = SCROLLBACK_INDICATOR_POSITION_RELATIVE; conf->scrollback.indicator.position = SCROLLBACK_INDICATOR_POSITION_RELATIVE;
else { else {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'none', 'fixed' or 'relative'");
"%s:%d: [scrollback].indicator-position: %s: not one of "
"'none', 'fixed' or 'relative'",
path, lineno, value);
return false; return false;
} }
} }
@ -1138,9 +1120,7 @@ parse_section_scrollback(struct context *ctx)
size_t len = mbstowcs(NULL, value, 0); size_t len = mbstowcs(NULL, value, 0);
if (len == (size_t)-1) { if (len == (size_t)-1) {
LOG_AND_NOTIFY_ERRNO( LOG_CONTEXTUAL_ERRNO("invalid free form text");
"%s:%d: [scrollback].indicator-format: %s: "
"invalid free form text", path, lineno, value);
return false; return false;
} }
@ -1152,9 +1132,7 @@ parse_section_scrollback(struct context *ctx)
else if (strcmp(key, "multiplier") == 0) { else if (strcmp(key, "multiplier") == 0) {
double multiplier; double multiplier;
if (!value_to_double(ctx, &multiplier)) { if (!value_to_double(ctx, &multiplier)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid decimal value");
"%s:%d: [scrollback].multiplier: %s: invalid decimal value",
path, lineno, value);
return false; return false;
} }
@ -1162,8 +1140,7 @@ parse_section_scrollback(struct context *ctx)
} }
else { else {
LOG_AND_NOTIFY_ERR("%s:%u: [scrollback].%s is not a valid option", LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
path, lineno, key);
return false; return false;
} }
@ -1176,8 +1153,6 @@ parse_section_url(struct context *ctx)
struct config *conf = ctx->conf; struct config *conf = ctx->conf;
const char *key = ctx->key; const char *key = ctx->key;
const char *value = ctx->value; const char *value = ctx->value;
const char *path = ctx->path;
unsigned lineno = ctx->lineno;
if (strcmp(key, "launch") == 0) { if (strcmp(key, "launch") == 0) {
if (!value_to_spawn_template(ctx, &conf->url.launch)) if (!value_to_spawn_template(ctx, &conf->url.launch))
@ -1199,9 +1174,7 @@ parse_section_url(struct context *ctx)
else if (strcmp(value, "always") == 0) else if (strcmp(value, "always") == 0)
conf->url.osc8_underline = OSC8_UNDERLINE_ALWAYS; conf->url.osc8_underline = OSC8_UNDERLINE_ALWAYS;
else { else {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'url-mode', or 'always'");
"%s:%u: [url].osc8-underline: %s: not one of "
"'url-mode', or 'always'", path, lineno, value);
return false; return false;
} }
} }
@ -1233,9 +1206,8 @@ parse_section_url(struct context *ctx)
size_t chars = mbstowcs(NULL, prot, 0); size_t chars = mbstowcs(NULL, prot, 0);
if (chars == (size_t)-1) { if (chars == (size_t)-1) {
LOG_AND_NOTIFY_ERRNO( ctx->value = prot;
"%s:%u: [url].protocols: %s: invalid protocol", LOG_CONTEXTUAL_ERRNO("invalid protocol");
path, lineno, prot);
return false; return false;
} }
@ -1273,8 +1245,7 @@ parse_section_url(struct context *ctx)
} }
else { else {
LOG_AND_NOTIFY_ERR("%s:%d: [url].%s is not a valid option", LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
path, lineno, key);
return false; return false;
} }
@ -1286,9 +1257,6 @@ parse_section_colors(struct context *ctx)
{ {
struct config *conf = ctx->conf; struct config *conf = ctx->conf;
const char *key = ctx->key; const char *key = ctx->key;
const char *value = ctx->value;
const char *path = ctx->path;
unsigned lineno = ctx->lineno;
size_t key_len = strlen(key); size_t key_len = strlen(key);
uint8_t last_digit = (unsigned char)key[key_len - 1] - '0'; uint8_t last_digit = (unsigned char)key[key_len - 1] - '0';
@ -1297,14 +1265,12 @@ parse_section_colors(struct context *ctx)
if (isdigit(key[0])) { if (isdigit(key[0])) {
unsigned long index; unsigned long index;
if (!str_to_ulong(key, 0, &index)) { if (!str_to_ulong(key, 0, &index)) {
LOG_AND_NOTIFY_ERR("%s:%d: [colors].%s: %s: invalid integer value", LOG_CONTEXTUAL_ERR("invalid integer value");
path, lineno, key, value);
return false; return false;
} }
if (index >= ALEN(conf->colors.table)) { if (index >= ALEN(conf->colors.table)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("color index outside range 0-%zu",
"%s:%d: [colors].%s: %s: color index outside range 0-%zu", ALEN(conf->colors.table));
path, lineno, key, value, ALEN(conf->colors.table));
return false; return false;
} }
color = &conf->colors.table[index]; color = &conf->colors.table[index];
@ -1360,10 +1326,7 @@ parse_section_colors(struct context *ctx)
else if (strcmp(key, "alpha") == 0) { else if (strcmp(key, "alpha") == 0) {
double alpha; double alpha;
if (!value_to_double(ctx, &alpha) || alpha < 0. || alpha > 1.) { if (!value_to_double(ctx, &alpha) || alpha < 0. || alpha > 1.) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid decimal value, or not in range 0.0-1.0");
"%s:%d: [colors].alpha: %s: "
"invalid decimal value, or not in range 0.0-1.0",
path, lineno, value);
return false; return false;
} }
@ -1372,8 +1335,7 @@ parse_section_colors(struct context *ctx)
} }
else { else {
LOG_AND_NOTIFY_ERR("%s:%d: [colors].%s is not valid option", LOG_CONTEXTUAL_ERR("not valid option");
path, lineno, key);
return false; return false;
} }
@ -1391,8 +1353,6 @@ parse_section_cursor(struct context *ctx)
struct config *conf = ctx->conf; struct config *conf = ctx->conf;
const char *key = ctx->key; const char *key = ctx->key;
const char *value = ctx->value; const char *value = ctx->value;
const char *path = ctx->path;
unsigned lineno = ctx->lineno;
if (strcmp(key, "style") == 0) { if (strcmp(key, "style") == 0) {
if (strcmp(value, "block") == 0) if (strcmp(value, "block") == 0)
@ -1403,9 +1363,7 @@ parse_section_cursor(struct context *ctx)
conf->cursor.style = CURSOR_UNDERLINE; conf->cursor.style = CURSOR_UNDERLINE;
else { else {
LOG_AND_NOTIFY_ERR("%s:%d: [cursor].style: %s: not one of " LOG_CONTEXTUAL_ERR("not one of 'block', 'beam' or 'underline'");
"'block', 'beam' or 'underline'",
path, lineno, value);
return false; return false;
} }
} }
@ -1438,8 +1396,7 @@ parse_section_cursor(struct context *ctx)
} }
else { else {
LOG_AND_NOTIFY_ERR("%s:%d: [cursor].%s is not a valid option", LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
path, lineno, key);
return false; return false;
} }
@ -1451,8 +1408,6 @@ parse_section_mouse(struct context *ctx)
{ {
struct config *conf = ctx->conf; struct config *conf = ctx->conf;
const char *key = ctx->key; const char *key = ctx->key;
const char *path = ctx->path;
unsigned lineno = ctx->lineno;
if (strcmp(key, "hide-when-typing") == 0) if (strcmp(key, "hide-when-typing") == 0)
conf->mouse.hide_when_typing = value_to_bool(ctx); conf->mouse.hide_when_typing = value_to_bool(ctx);
@ -1461,8 +1416,7 @@ parse_section_mouse(struct context *ctx)
conf->mouse.alternate_scroll_mode = value_to_bool(ctx); conf->mouse.alternate_scroll_mode = value_to_bool(ctx);
else { else {
LOG_AND_NOTIFY_ERR("%s:%d: [mouse].%s is not a valid option", LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
path, lineno, key);
return false; return false;
} }
@ -1475,8 +1429,6 @@ parse_section_csd(struct context *ctx)
struct config *conf = ctx->conf; struct config *conf = ctx->conf;
const char *key = ctx->key; const char *key = ctx->key;
const char *value = ctx->value; const char *value = ctx->value;
const char *path = ctx->path;
unsigned lineno = ctx->lineno;
if (strcmp(key, "preferred") == 0) { if (strcmp(key, "preferred") == 0) {
if (strcmp(value, "server") == 0) if (strcmp(value, "server") == 0)
@ -1486,9 +1438,7 @@ parse_section_csd(struct context *ctx)
else if (strcmp(value, "none") == 0) else if (strcmp(value, "none") == 0)
conf->csd.preferred = CONF_CSD_PREFER_NONE; conf->csd.preferred = CONF_CSD_PREFER_NONE;
else { else {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'server', 'client' or 'none'");
"%s:%d: csd.preferred: %s: not one of "
"'server', 'client' or 'none'", path, lineno, value);
return false; return false;
} }
} }
@ -1514,9 +1464,7 @@ parse_section_csd(struct context *ctx)
else if (strcmp(key, "size") == 0) { else if (strcmp(key, "size") == 0) {
unsigned long pixels; unsigned long pixels;
if (!value_to_ulong(ctx, 10, &pixels)) { if (!value_to_ulong(ctx, 10, &pixels)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%d: [csd].size: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
@ -1526,9 +1474,7 @@ parse_section_csd(struct context *ctx)
else if (strcmp(key, "button-width") == 0) { else if (strcmp(key, "button-width") == 0) {
unsigned long pixels; unsigned long pixels;
if (!value_to_ulong(ctx, 10, &pixels)) { if (!value_to_ulong(ctx, 10, &pixels)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%d: [csd].button-width: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
@ -1583,9 +1529,7 @@ parse_section_csd(struct context *ctx)
else if (strcmp(key, "border-width") == 0) { else if (strcmp(key, "border-width") == 0) {
unsigned long width; unsigned long width;
if (!value_to_ulong(ctx, 10, &width)) { if (!value_to_ulong(ctx, 10, &width)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%u: [csd].border-width: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
@ -1593,8 +1537,7 @@ parse_section_csd(struct context *ctx)
} }
else { else {
LOG_AND_NOTIFY_ERR("%s:%u: [csd].%s is not a valid action", LOG_CONTEXTUAL_ERR("not a valid action: %s", key);
path, lineno, key);
return false; return false;
} }
@ -1651,8 +1594,7 @@ parse_modifiers(struct context *ctx, const char *text, size_t len,
else if (strcmp(key, XKB_MOD_NAME_LOGO) == 0) else if (strcmp(key, XKB_MOD_NAME_LOGO) == 0)
modifiers->meta = true; modifiers->meta = true;
else { else {
LOG_AND_NOTIFY_ERR("%s:%d: %s: not a valid modifier name", LOG_CONTEXTUAL_ERR("not a valid modifier name: %s", key);
ctx->path, ctx->lineno, ctx->key);
goto out; goto out;
} }
} }
@ -1690,27 +1632,10 @@ value_to_key_combos(struct context *ctx, struct key_combo_list *key_combos)
key++; /* Skip past the '+' */ key++; /* Skip past the '+' */
} }
#if 0
if (modifiers.shift && strlen(key) == 1 && (*key >= 'A' && *key <= 'Z')) {
LOG_WARN(
"%s:%d: [%s].%s: %s: "
"upper case keys not supported with explicit 'Shift' modifier",
path, lineno, section, option, combo);
user_notification_add(
&conf->notifications, USER_NOTIFICATION_DEPRECATED,
"%s:%d: [%s].%s: \033[1m%s\033[m: "
"shifted keys not supported with explicit \033[1mShift\033[m "
"modifier",
path, lineno, section, option, combo);
*key = *key - 'A' + 'a';
}
#endif
/* Translate key name to symbol */ /* Translate key name to symbol */
xkb_keysym_t sym = xkb_keysym_from_name(key, 0); xkb_keysym_t sym = xkb_keysym_from_name(key, 0);
if (sym == XKB_KEY_NoSymbol) { if (sym == XKB_KEY_NoSymbol) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not a valid XKB key name: %s", key);
"%s:%d: [%s].%s: %s: is not a valid XKB key name",
ctx->path, ctx->lineno, ctx->section, ctx->key, key);
goto err; goto err;
} }
@ -1766,8 +1691,8 @@ has_key_binding_collisions(struct context *ctx,
if (shift && alt && ctrl && meta && sym) { if (shift && alt && ctrl && meta && sym) {
bool has_pipe = combo1->pipe.argv.args != NULL; bool has_pipe = combo1->pipe.argv.args != NULL;
LOG_AND_NOTIFY_ERR("%s:%d: %s already mapped to '%s%s%s%s'", LOG_CONTEXTUAL_ERR("%s already mapped to '%s%s%s%s'",
ctx->path, ctx->lineno, combo2->text, combo2->text,
action_map[combo1->action], action_map[combo1->action],
has_pipe ? " [" : "", has_pipe ? " [" : "",
has_pipe ? combo1->pipe.argv.args[0] : "", has_pipe ? combo1->pipe.argv.args[0] : "",
@ -1834,7 +1759,7 @@ pipe_argv_from_value(struct context *ctx, char ***argv)
const char *pipe_cmd_end = strrchr(ctx->value, ']'); const char *pipe_cmd_end = strrchr(ctx->value, ']');
if (pipe_cmd_end == NULL) { if (pipe_cmd_end == NULL) {
LOG_AND_NOTIFY_ERR("%s:%d: unclosed '['", ctx->path, ctx->lineno); LOG_CONTEXTUAL_ERR("unclosed '['");
return -1; return -1;
} }
@ -1842,7 +1767,7 @@ pipe_argv_from_value(struct context *ctx, char ***argv)
char *cmd = xstrndup(&ctx->value[1], pipe_len); char *cmd = xstrndup(&ctx->value[1], pipe_len);
if (!tokenize_cmdline(cmd, argv)) { if (!tokenize_cmdline(cmd, argv)) {
LOG_AND_NOTIFY_ERR("%s:%d: syntax error in command line", ctx->path, ctx->lineno); LOG_CONTEXTUAL_ERR("syntax error in command line");
free(cmd); free(cmd);
return -1; return -1;
} }
@ -1965,8 +1890,7 @@ parse_key_binding_section(struct context *ctx,
return true; return true;
} }
LOG_AND_NOTIFY_ERR("%s:%u: [%s].%s is not a valid action", LOG_CONTEXTUAL_ERR("not a valid action: %s", ctx->key);
ctx->path, ctx->lineno, ctx->section, ctx->key);
free(pipe_argv); free(pipe_argv);
return false; return false;
} }
@ -2150,9 +2074,7 @@ value_to_mouse_combos(struct context *ctx, struct key_combo_list *key_combos)
if (!parse_modifiers(ctx, combo, key - combo, &modifiers)) if (!parse_modifiers(ctx, combo, key - combo, &modifiers))
goto err; goto err;
if (modifiers.shift) { if (modifiers.shift) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("Shift cannot be used in mouse bindings");
"%s:%d: [%s].%s: Shift cannot be used in mouse bindings",
ctx->path, ctx->lineno, ctx->section, ctx->key);
goto err; goto err;
} }
key++; /* Skip past the '+' */ key++; /* Skip past the '+' */
@ -2170,13 +2092,9 @@ value_to_mouse_combos(struct context *ctx, struct key_combo_list *key_combos)
unsigned long value = strtoul(_count, &end, 10); unsigned long value = strtoul(_count, &end, 10);
if (_count[0] == '\0' || *end != '\0' || errno != 0) { if (_count[0] == '\0' || *end != '\0' || errno != 0) {
if (errno != 0) if (errno != 0)
LOG_AND_NOTIFY_ERRNO( LOG_CONTEXTUAL_ERRNO("invalid click count: %s", _count);
"%s:%d: [%s].%s: %s: invalid click count",
ctx->path, ctx->lineno, ctx->section, ctx->key, _count);
else else
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid click count: %s", _count);
"%s:%d: [%s].%s: %s: invalid click count",
ctx->path, ctx->lineno, ctx->section, ctx->key, _count);
goto err; goto err;
} }
count = value; count = value;
@ -2206,8 +2124,7 @@ value_to_mouse_combos(struct context *ctx, struct key_combo_list *key_combos)
} }
if (button == 0) { if (button == 0) {
LOG_AND_NOTIFY_ERR("%s:%d: [%s].%s: %s: invalid mouse button name", LOG_CONTEXTUAL_ERR("invalid mouse button name: %s", key);
ctx->path, ctx->lineno, ctx->section, ctx->key, key);
goto err; goto err;
} }
@ -2265,8 +2182,8 @@ has_mouse_binding_collisions(struct context *ctx,
if (shift && alt && ctrl && meta && button && count) { if (shift && alt && ctrl && meta && button && count) {
bool has_pipe = combo1->pipe.argv.args != NULL; bool has_pipe = combo1->pipe.argv.args != NULL;
LOG_AND_NOTIFY_ERR("%s:%d: %s already mapped to '%s%s%s%s'", LOG_CONTEXTUAL_ERR("%s already mapped to '%s%s%s%s'",
ctx->path, ctx->lineno, combo2->text, combo2->text,
binding_action_map[combo1->action], binding_action_map[combo1->action],
has_pipe ? " [" : "", has_pipe ? " [" : "",
has_pipe ? combo1->pipe.argv.args[0] : "", has_pipe ? combo1->pipe.argv.args[0] : "",
@ -2286,8 +2203,6 @@ parse_section_mouse_bindings(struct context *ctx)
struct config *conf = ctx->conf; struct config *conf = ctx->conf;
const char *key = ctx->key; const char *key = ctx->key;
const char *value = ctx->value; const char *value = ctx->value;
const char *path = ctx->path;
unsigned lineno = ctx->lineno;
char **pipe_argv; char **pipe_argv;
@ -2378,8 +2293,7 @@ parse_section_mouse_bindings(struct context *ctx)
return true; return true;
} }
LOG_AND_NOTIFY_ERR("%s:%u: [mouse-bindings].%s is not a valid option", LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
path, lineno, key);
free(pipe_argv); free(pipe_argv);
return false; return false;
} }
@ -2410,10 +2324,8 @@ parse_section_tweak(struct context *ctx)
} }
} }
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR(
"%s:%d: [tweak].scaling-filter: %s: not one of " "not one of 'none', 'nearest', 'bilinear', 'cubic' or 'lanczos3'");
"'none', 'nearest', 'bilinear', 'cubic' or 'lanczos3'",
path, lineno, value);
return false; return false;
} }
@ -2434,19 +2346,15 @@ parse_section_tweak(struct context *ctx)
#if !defined(FOOT_GRAPHEME_CLUSTERING) #if !defined(FOOT_GRAPHEME_CLUSTERING)
if (conf->tweak.grapheme_shaping) { if (conf->tweak.grapheme_shaping) {
LOG_AND_NOTIFY_WARN( LOG_CONTEXTUAL_WARN(
"%s:%d: [tweak].grapheme-shaping: " "foot was not compiled with support for grapheme shaping");
"enabled, but foot was not compiled with support for it",
path, lineno);
conf->tweak.grapheme_shaping = false; conf->tweak.grapheme_shaping = false;
} }
#endif #endif
if (conf->tweak.grapheme_shaping && !conf->can_shape_grapheme) { if (conf->tweak.grapheme_shaping && !conf->can_shape_grapheme) {
LOG_WARN( LOG_WARN(
"%s:%d [tweak].grapheme-shaping: " "fcft was not compiled with support for grapheme shaping");
"enabled, but fcft was not compiled with support for it",
path, lineno);
/* Keep it enabled though - this will cause us to do /* Keep it enabled though - this will cause us to do
* grapheme-clustering at least */ * grapheme-clustering at least */
@ -2462,9 +2370,7 @@ parse_section_tweak(struct context *ctx)
else if (strcmp(value, "wcswidth") == 0) else if (strcmp(value, "wcswidth") == 0)
conf->tweak.grapheme_width_method = GRAPHEME_WIDTH_WCSWIDTH; conf->tweak.grapheme_width_method = GRAPHEME_WIDTH_WCSWIDTH;
else { else {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'wcswidth' or 'double-width'");
"%s:%d: [tweak].grapheme-width-method: %s: not one of "
"'wcswidth' or 'double-width'", path, lineno, value);
return false; return false;
} }
@ -2485,9 +2391,7 @@ parse_section_tweak(struct context *ctx)
conf->tweak.render_timer_osd = true; conf->tweak.render_timer_osd = true;
conf->tweak.render_timer_log = true; conf->tweak.render_timer_log = true;
} else { } else {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("not one of 'none', 'osd', 'log' or 'both'");
"%s:%d: [tweak].render-timer: %s: not one of "
"none', 'osd', 'log' or 'both'", path, lineno, value);
return false; return false;
} }
} }
@ -2495,16 +2399,12 @@ parse_section_tweak(struct context *ctx)
else if (strcmp(key, "delayed-render-lower") == 0) { else if (strcmp(key, "delayed-render-lower") == 0) {
unsigned long ns; unsigned long ns;
if (!value_to_ulong(ctx, 10, &ns)) { if (!value_to_ulong(ctx, 10, &ns)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%d: [tweak].delayed-render-lower: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
if (ns > 16666666) { if (ns > 16666666) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("timeout must not exceed 16ms");
"%s:%d: [tweak].delayed-render-lower: %s: "
"timeout must not exceed 16ms", path, lineno, value);
return false; return false;
} }
@ -2515,16 +2415,12 @@ parse_section_tweak(struct context *ctx)
else if (strcmp(key, "delayed-render-upper") == 0) { else if (strcmp(key, "delayed-render-upper") == 0) {
unsigned long ns; unsigned long ns;
if (!value_to_ulong(ctx, 10, &ns)) { if (!value_to_ulong(ctx, 10, &ns)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%d: [tweak].delayed-render-upper: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
if (ns > 16666666) { if (ns > 16666666) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("timeout must not exceed 16ms");
"%s:%d: [tweak].delayed-render-upper: %s: "
"timeout must not exceed 16ms", path, lineno, value);
return false; return false;
} }
@ -2535,9 +2431,7 @@ parse_section_tweak(struct context *ctx)
else if (strcmp(key, "max-shm-pool-size-mb") == 0) { else if (strcmp(key, "max-shm-pool-size-mb") == 0) {
unsigned long mb; unsigned long mb;
if (!value_to_ulong(ctx, 10, &mb)) { if (!value_to_ulong(ctx, 10, &mb)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid integer value");
"%s:%d: [tweak].max-shm-pool-size-mb: %s: invalid integer value",
path, lineno, value);
return false; return false;
} }
@ -2549,9 +2443,7 @@ parse_section_tweak(struct context *ctx)
else if (strcmp(key, "box-drawing-base-thickness") == 0) { else if (strcmp(key, "box-drawing-base-thickness") == 0) {
double base_thickness; double base_thickness;
if (!value_to_double(ctx, &base_thickness)) { if (!value_to_double(ctx, &base_thickness)) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid decimal value");
"%s:%d: [tweak].box-drawing-base-thickness: %s: "
"invalid decimal value", path, lineno, value);
return false; return false;
} }
@ -2572,8 +2464,7 @@ parse_section_tweak(struct context *ctx)
conf->tweak.font_monospace_warn = value_to_bool(ctx); conf->tweak.font_monospace_warn = value_to_bool(ctx);
else { else {
LOG_AND_NOTIFY_ERR("%s:%u: [tweak].%s is not a valid option", LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
path, lineno, key);
return false; return false;
} }
@ -2583,7 +2474,6 @@ parse_section_tweak(struct context *ctx)
static bool static bool
parse_key_value(char *kv, const char **section, const char **key, const char **value) parse_key_value(char *kv, const char **section, const char **key, const char **value)
{ {
/*strip leading whitespace*/ /*strip leading whitespace*/
while (*kv && isspace(*kv)) while (*kv && isspace(*kv))
++kv; ++kv;
@ -2762,7 +2652,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path, bool errors_ar
if (key_value[0] == '[') { if (key_value[0] == '[') {
char *end = strchr(key_value, ']'); char *end = strchr(key_value, ']');
if (end == NULL) { if (end == NULL) {
LOG_AND_NOTIFY_ERR("%s:%d: syntax error: %s", path, context.lineno, key_value); LOG_CONTEXTUAL_ERR("syntax error: no closing ']'");
error_or_continue(); error_or_continue();
} }
@ -2770,7 +2660,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path, bool errors_ar
section = str_to_section(&key_value[1]); section = str_to_section(&key_value[1]);
if (section == SECTION_COUNT) { if (section == SECTION_COUNT) {
LOG_AND_NOTIFY_ERR("%s:%d: invalid section name: %s", path, context.lineno, &key_value[1]); LOG_CONTEXTUAL_ERR("invalid section name: %s", &key_value[1]);
error_or_continue(); error_or_continue();
} }
@ -2786,7 +2676,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path, bool errors_ar
} }
if (!parse_key_value(key_value, NULL, &context.key, &context.value)) { if (!parse_key_value(key_value, NULL, &context.key, &context.value)) {
LOG_AND_NOTIFY_ERR("%s:%d: syntax error: %s", path, context.lineno, key_value); LOG_CONTEXTUAL_ERR("syntax error: key/value pair has no value");
if (errors_are_fatal) if (errors_are_fatal)
goto err; goto err;
break; break;
@ -3117,21 +3007,6 @@ config_load(struct config *conf, const char *conf_path,
add_default_url_bindings(conf); add_default_url_bindings(conf);
add_default_mouse_bindings(conf); add_default_mouse_bindings(conf);
/*
* TODO: replace LOG_AND_NOTIFY_*() with custom loggers that
* doesnt take a context
*/
struct context context = {
.conf = conf,
.section = "",
.key = "",
.value = "",
.path = conf_path,
.lineno = 0,
.errors_are_fatal = errors_are_fatal,
};
struct context *ctx = &context;
struct config_file conf_file = {.path = NULL, .fd = -1}; struct config_file conf_file = {.path = NULL, .fd = -1};
if (conf_path != NULL) { if (conf_path != NULL) {
int fd = open(conf_path, O_RDONLY); int fd = open(conf_path, O_RDONLY);
@ -3220,7 +3095,7 @@ config_override_apply(struct config *conf, config_override_t *overrides, bool er
if (!parse_key_value( if (!parse_key_value(
it->item, &context.section, &context.key, &context.value)) it->item, &context.section, &context.key, &context.value))
{ {
LOG_AND_NOTIFY_ERR("syntax error: %s", it->item); LOG_CONTEXTUAL_ERR("syntax error: key/value pair has no value");
if (errors_are_fatal) if (errors_are_fatal)
return false; return false;
continue; continue;
@ -3228,8 +3103,7 @@ config_override_apply(struct config *conf, config_override_t *overrides, bool er
enum section section = str_to_section(context.section); enum section section = str_to_section(context.section);
if (section == SECTION_COUNT) { if (section == SECTION_COUNT) {
LOG_AND_NOTIFY_ERR( LOG_CONTEXTUAL_ERR("invalid section name: %s", context.section);
"override: invalid section name: %s", context.section);
if (errors_are_fatal) if (errors_are_fatal)
return false; return false;
continue; continue;

3
log.h
View file

@ -11,7 +11,8 @@ enum log_class {
LOG_CLASS_ERROR, LOG_CLASS_ERROR,
LOG_CLASS_WARNING, LOG_CLASS_WARNING,
LOG_CLASS_INFO, LOG_CLASS_INFO,
LOG_CLASS_DEBUG LOG_CLASS_DEBUG,
LOG_CLASS_COUNT,
}; };
void log_init(enum log_colorize colorize, bool do_syslog, void log_init(enum log_colorize colorize, bool do_syslog,