diff --git a/client.c b/client.c index a1b86d30..bf9264ee 100644 --- a/client.c +++ b/client.c @@ -17,6 +17,7 @@ #include "client-protocol.h" #include "debug.h" #include "foot-features.h" +#include "macros.h" #include "util.h" #include "version.h" #include "xmalloc.h" @@ -156,38 +157,16 @@ main(int argc, char *const *argv) break; case 'd': { - static const char *log_level_map[] = { -#if defined(_DEBUG) - [LOG_CLASS_DEBUG] = "debug", -#endif - [LOG_CLASS_INFO] = "info", - [LOG_CLASS_WARNING] = "warning", - [LOG_CLASS_ERROR] = "error", - }; - - bool valid_log_level = false; - for (size_t i = 0; i < ALEN(log_level_map); i++) { - if (strcmp(optarg, log_level_map[i]) == 0) { - log_level = i; - valid_log_level = true; - break; - } - } - - if (!valid_log_level) { + int lvl = log_level_from_string(optarg); + if (unlikely(lvl < 0)) { fprintf( - stderr, "-d,--log-level: %s: argument must be one of ", - optarg); - - for (size_t i = 0; i < ALEN(log_level_map); i++) { - fprintf(stderr, "'%s'%s", - log_level_map[i], - i < ALEN(log_level_map) - 1 ? " , " : ""); - } - fprintf(stderr, "\n"); - + stderr, + "-d,--log-level: %s: argument must be one of %s\n", + optarg, + log_level_string_hint()); return EXIT_FAILURE; } + log_level = lvl; break; } diff --git a/log.c b/log.c index 10ba5346..1c33c723 100644 --- a/log.c +++ b/log.c @@ -10,11 +10,22 @@ #include #include "debug.h" +#include "util.h" +#include "xsnprintf.h" static bool colorize = false; static bool do_syslog = true; static enum log_class log_level = LOG_CLASS_INFO; +static const char log_level_map[][8] = { + [LOG_CLASS_ERROR] = "error", + [LOG_CLASS_WARNING] = "warning", + [LOG_CLASS_INFO] = "info", +#if defined(_DEBUG) + [LOG_CLASS_DEBUG] = "debug", +#endif +}; + void log_init(enum log_colorize _colorize, bool _do_syslog, enum log_facility syslog_facility, enum log_class _log_level) @@ -149,3 +160,32 @@ void log_errno_provided(enum log_class log_class, const char *module, va_end(ap1); va_end(ap2); } + +int +log_level_from_string(const char *str) +{ + if (unlikely(str[0] == '\0')) + return -1; + + for (int i = 0, n = ALEN(log_level_map); i < n; i++) + if (strcmp(str, log_level_map[i]) == 0) + return i; + + return -1; +} + +const char * +log_level_string_hint(void) +{ + static char buf[64]; + if (buf[0] != '\0') + return buf; + + for (size_t i = 0, pos = 0, n = ALEN(log_level_map); i < n; i++) { + const char *entry = log_level_map[i]; + const char *delim = (i + 1 < n) ? ", " : ""; + pos += xsnprintf(buf + pos, sizeof(buf) - pos, "'%s'%s", entry, delim); + } + + return buf; +} diff --git a/log.h b/log.h index 5baddfcd..f0c28d7b 100644 --- a/log.h +++ b/log.h @@ -23,6 +23,9 @@ void log_errno_provided( const char *file, int lineno, int _errno, const char *fmt, ...) PRINTF(6); +int log_level_from_string(const char *str); +const char *log_level_string_hint(void); + #define LOG_ERR(...) \ log_msg(LOG_CLASS_ERROR, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) #define LOG_ERRNO(...) \ diff --git a/main.c b/main.c index 4ea6e1fb..0fbf4e8b 100644 --- a/main.c +++ b/main.c @@ -23,6 +23,7 @@ #include "config.h" #include "foot-features.h" #include "fdm.h" +#include "macros.h" #include "reaper.h" #include "render.h" #include "server.h" @@ -310,38 +311,16 @@ main(int argc, char *const *argv) break; case 'd': { - static const char *log_level_map[] = { -#if defined(_DEBUG) - [LOG_CLASS_DEBUG] = "debug", -#endif - [LOG_CLASS_INFO] = "info", - [LOG_CLASS_WARNING] = "warning", - [LOG_CLASS_ERROR] = "error", - }; - - bool valid_log_level = false; - for (size_t i = 0; i < ALEN(log_level_map); i++) { - if (strcmp(optarg, log_level_map[i]) == 0) { - log_level = i; - valid_log_level = true; - break; - } - } - - if (!valid_log_level) { + int lvl = log_level_from_string(optarg); + if (unlikely(lvl < 0)) { fprintf( - stderr, "-d,--log-level: %s: argument must be one of ", - optarg); - - for (size_t i = 0; i < ALEN(log_level_map); i++) { - fprintf(stderr, "'%s'%s", - log_level_map[i], - i < ALEN(log_level_map) - 1 ? " , " : ""); - } - fprintf(stderr, "\n"); - + stderr, + "-d,--log-level: %s: argument must be one of %s\n", + optarg, + log_level_string_hint()); return EXIT_FAILURE; } + log_level = lvl; break; } diff --git a/meson.build b/meson.build index f2e6da2b..85875e7a 100644 --- a/meson.build +++ b/meson.build @@ -196,7 +196,9 @@ executable( 'foot-features.h', 'log.c', 'log.h', 'macros.h', + 'util.h', 'xmalloc.c', 'xmalloc.h', + 'xsnprintf.c', 'xsnprintf.h', version, install: true)