send logs to stderr

This commit is contained in:
Devaev Maxim
2021-01-05 09:56:01 +03:00
parent 85e63f49a0
commit 7d587052ad
3 changed files with 151 additions and 148 deletions

View File

@@ -54,7 +54,7 @@ extern pthread_mutex_t log_mutex;
#define LOGGING_INIT { \ #define LOGGING_INIT { \
log_level = LOG_LEVEL_INFO; \ log_level = LOG_LEVEL_INFO; \
log_colored = isatty(1); \ log_colored = isatty(2); \
A_MUTEX_INIT(&log_mutex); \ A_MUTEX_INIT(&log_mutex); \
} }
@@ -76,10 +76,10 @@ extern pthread_mutex_t log_mutex;
#define SEP_INFO(_ch) { \ #define SEP_INFO(_ch) { \
LOGGING_LOCK; \ LOGGING_LOCK; \
for (int _i = 0; _i < 80; ++_i) { \ for (int _i = 0; _i < 80; ++_i) { \
putchar(_ch); \ fputc(_ch, stderr); \
} \ } \
putchar('\n'); \ fputc('\n', stderr); \
fflush(stdout); \ fflush(stderr); \
LOGGING_UNLOCK; \ LOGGING_UNLOCK; \
} }
@@ -94,14 +94,15 @@ extern pthread_mutex_t log_mutex;
char _tname_buf[MAX_THREAD_NAME] = {0}; \ char _tname_buf[MAX_THREAD_NAME] = {0}; \
thread_get_name(_tname_buf); \ thread_get_name(_tname_buf); \
if (log_colored) { \ if (log_colored) { \
printf(COLOR_GRAY "-- " _label_color _label COLOR_GRAY " [%.03Lf %9s]" " -- " COLOR_RESET _msg_color _msg COLOR_RESET, \ fprintf(stderr, COLOR_GRAY "-- " _label_color _label COLOR_GRAY \
" [%.03Lf %9s]" " -- " COLOR_RESET _msg_color _msg COLOR_RESET, \
get_now_monotonic(), _tname_buf, ##__VA_ARGS__); \ get_now_monotonic(), _tname_buf, ##__VA_ARGS__); \
} else { \ } else { \
printf("-- " _label " [%.03Lf %9s] -- " _msg, \ fprintf(stderr, "-- " _label " [%.03Lf %9s] -- " _msg, \
get_now_monotonic(), _tname_buf, ##__VA_ARGS__); \ get_now_monotonic(), _tname_buf, ##__VA_ARGS__); \
} \ } \
putchar('\n'); \ fputc('\n', stderr); \
fflush(stdout); \ fflush(stderr); \
} }
#define LOG_PRINTF(_label_color, _label, _msg_color, _msg, ...) { \ #define LOG_PRINTF(_label_color, _label, _msg_color, _msg, ...) { \

View File

@@ -211,7 +211,7 @@ static int _parse_glitched_resolutions(const char *str, encoder_s *enc);
#endif #endif
static void _features(void); static void _features(void);
static void _help(device_s *dev, encoder_s *enc, stream_s *stream, server_s *server); static void _help(FILE *fp, device_s *dev, encoder_s *enc, stream_s *stream, server_s *server);
options_s *options_init(unsigned argc, char *argv[]) { options_s *options_init(unsigned argc, char *argv[]) {
@@ -444,12 +444,12 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s
case _O_FORCE_LOG_COLORS: OPT_SET(log_colored, true); case _O_FORCE_LOG_COLORS: OPT_SET(log_colored, true);
case _O_NO_LOG_COLORS: OPT_SET(log_colored, false); case _O_NO_LOG_COLORS: OPT_SET(log_colored, false);
case _O_HELP: _help(dev, enc, stream, server); return 1; case _O_HELP: _help(stdout, dev, enc, stream, server); return 1;
case _O_VERSION: puts(VERSION); return 1; case _O_VERSION: puts(VERSION); return 1;
case _O_FEATURES: _features(); return 1; case _O_FEATURES: _features(); return 1;
case 0: break; case 0: break;
default: _help(dev, enc, stream, server); return -1; default: _help(stderr, dev, enc, stream, server); return -1;
} }
} }
@@ -586,144 +586,146 @@ static void _features(void) {
# endif # endif
} }
static void _help(device_s *dev, encoder_s *enc, stream_s *stream, server_s *server) { static void _help(FILE *fp, device_s *dev, encoder_s *enc, stream_s *stream, server_s *server) {
printf("\nuStreamer - Lightweight and fast MJPG-HTTP streamer\n"); # define SAY(_msg, ...) fprintf(fp, _msg "\n", ##__VA_ARGS__)
printf("═══════════════════════════════════════════════════\n\n"); SAY("\nuStreamer - Lightweight and fast MJPG-HTTP streamer");
printf("Version: %s; license: GPLv3\n", VERSION); SAY("═══════════════════════════════════════════════════\n");
printf("Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com>\n\n"); SAY("Version: %s; license: GPLv3", VERSION);
printf("Capturing options:\n"); SAY("Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com>\n");
printf("══════════════════\n"); SAY("Capturing options:");
printf(" -d|--device </dev/path> ───────────── Path to V4L2 device. Default: %s.\n\n", dev->path); SAY("══════════════════");
printf(" -i|--input <N> ────────────────────── Input channel. Default: %u.\n\n", dev->input); SAY(" -d|--device </dev/path> ───────────── Path to V4L2 device. Default: %s.\n", dev->path);
printf(" -r|--resolution <WxH> ─────────────── Initial image resolution. Default: %ux%u.\n\n", dev->width, dev->height); SAY(" -i|--input <N> ────────────────────── Input channel. Default: %u.\n", dev->input);
printf(" -m|--format <fmt> ─────────────────── Image format.\n"); SAY(" -r|--resolution <WxH> ─────────────── Initial image resolution. Default: %ux%u.\n", dev->width, dev->height);
printf(" Available: %s; default: YUYV.\n\n", FORMATS_STR); SAY(" -m|--format <fmt> ─────────────────── Image format.");
printf(" -a|--tv-standard <std> ────────────── Force TV standard.\n"); SAY(" Available: %s; default: YUYV.\n", FORMATS_STR);
printf(" Available: %s; default: disabled.\n\n", STANDARDS_STR); SAY(" -a|--tv-standard <std> ────────────── Force TV standard.");
printf(" -I|--io-method <method> ───────────── Set V4L2 IO method (see kernel documentation).\n"); SAY(" Available: %s; default: disabled.\n", STANDARDS_STR);
printf(" Changing of this parameter may increase the performance. Or not.\n"); SAY(" -I|--io-method <method> ───────────── Set V4L2 IO method (see kernel documentation).");
printf(" Available: %s; default: MMAP.\n\n", IO_METHODS_STR); SAY(" Changing of this parameter may increase the performance. Or not.");
printf(" -f|--desired-fps <N> ──────────────── Desired FPS. Default: maximum possible.\n\n"); SAY(" Available: %s; default: MMAP.\n", IO_METHODS_STR);
printf(" -z|--min-frame-size <N> ───────────── Drop frames smaller then this limit. Useful if the device\n"); SAY(" -f|--desired-fps <N> ──────────────── Desired FPS. Default: maximum possible.\n");
printf(" produces small-sized garbage frames. Default: %zu bytes.\n\n", dev->min_frame_size); SAY(" -z|--min-frame-size <N> ───────────── Drop frames smaller then this limit. Useful if the device");
printf(" -n|--persistent ───────────────────── Don't re-initialize device on timeout. Default: disabled.\n\n"); SAY(" produces small-sized garbage frames. Default: %zu bytes.\n", dev->min_frame_size);
printf(" -t|--dv-timings ───────────────────── Enable DV timings querying and events processing\n"); SAY(" -n|--persistent ───────────────────── Don't re-initialize device on timeout. Default: disabled.\n");
printf(" to automatic resolution change. Default: disabled.\n\n"); SAY(" -t|--dv-timings ───────────────────── Enable DV timings querying and events processing");
printf(" -b|--buffers <N> ──────────────────── The number of buffers to receive data from the device.\n"); SAY(" to automatic resolution change. Default: disabled.\n");
printf(" Each buffer may processed using an independent thread.\n"); SAY(" -b|--buffers <N> ──────────────────── The number of buffers to receive data from the device.");
printf(" Default: %u (the number of CPU cores (but not more than 4) + 1).\n\n", dev->n_buffers); SAY(" Each buffer may processed using an independent thread.");
printf(" -w|--workers <N> ──────────────────── The number of worker threads but not more than buffers.\n"); SAY(" Default: %u (the number of CPU cores (but not more than 4) + 1).\n", dev->n_buffers);
printf(" Default: %u (the number of CPU cores (but not more than 4)).\n\n", enc->n_workers); SAY(" -w|--workers <N> ──────────────────── The number of worker threads but not more than buffers.");
printf(" -q|--quality <N> ──────────────────── Set quality of JPEG encoding from 1 to 100 (best). Default: %u.\n", dev->jpeg_quality); SAY(" Default: %u (the number of CPU cores (but not more than 4)).\n", enc->n_workers);
printf(" Note: If HW encoding is used (JPEG source format selected),\n"); SAY(" -q|--quality <N> ──────────────────── Set quality of JPEG encoding from 1 to 100 (best). Default: %u.", dev->jpeg_quality);
printf(" this parameter attempts to configure the camera\n"); SAY(" Note: If HW encoding is used (JPEG source format selected),");
printf(" or capture device hardware's internal encoder.\n"); SAY(" this parameter attempts to configure the camera");
printf(" It does not re-encode MJPG to MJPG to change the quality level\n"); SAY(" or capture device hardware's internal encoder.");
printf(" for sources that already output MJPG.\n\n"); SAY(" It does not re-encode MJPG to MJPG to change the quality level");
printf(" -c|--encoder <type> ───────────────── Use specified encoder. It may affect the number of workers.\n"); SAY(" for sources that already output MJPG.\n");
printf(" Available:\n"); SAY(" -c|--encoder <type> ───────────────── Use specified encoder. It may affect the number of workers.");
printf(" * CPU ── Software MJPG encoding (default);\n"); SAY(" Available:");
SAY(" * CPU ── Software MJPG encoding (default);");
# ifdef WITH_OMX # ifdef WITH_OMX
printf(" * OMX ── GPU hardware accelerated MJPG encoding with OpenMax;\n"); SAY(" * OMX ── GPU hardware accelerated MJPG encoding with OpenMax;");
# endif # endif
printf(" * HW ─── Use pre-encoded MJPG frames directly from camera hardware.\n"); SAY(" * HW ─── Use pre-encoded MJPG frames directly from camera hardware.");
printf(" * NOOP ─ Don't compress MJPG stream (do nothing).\n\n"); SAY(" * NOOP ─ Don't compress MJPG stream (do nothing).\n");
# ifdef WITH_OMX # ifdef WITH_OMX
printf(" -g|--glitched-resolutions <WxH,...> ─ Comma-separated list of resolutions that require forced\n"); SAY(" -g|--glitched-resolutions <WxH,...> ─ Comma-separated list of resolutions that require forced");
printf(" encoding on CPU instead of OMX. Default: disabled.\n\n"); SAY(" encoding on CPU instead of OMX. Default: disabled.\n");
# endif # endif
printf(" -k|--blank <path> ─────────────────── Path to JPEG file that will be shown when the device is disconnected\n"); SAY(" -k|--blank <path> ─────────────────── Path to JPEG file that will be shown when the device is disconnected");
printf(" during the streaming. Default: black screen 640x480 with 'NO SIGNAL'.\n\n"); SAY(" during the streaming. Default: black screen 640x480 with 'NO SIGNAL'.\n");
printf(" -K|--last-as-blank <sec> ──────────── Show the last frame received from the camera after it was disconnected,\n"); SAY(" -K|--last-as-blank <sec> ──────────── Show the last frame received from the camera after it was disconnected,");
printf(" but no more than specified time (or endlessly if 0 is specified).\n"); SAY(" but no more than specified time (or endlessly if 0 is specified).");
printf(" If the device has not yet been online, display 'NO SIGNAL' or the image\n"); SAY(" If the device has not yet been online, display 'NO SIGNAL' or the image");
printf(" specified by option --blank. Default: disabled.\n\n"); SAY(" specified by option --blank. Default: disabled.\n");
printf(" --device-timeout <sec> ────────────── Timeout for device querying. Default: %u.\n\n", dev->timeout); SAY(" --device-timeout <sec> ────────────── Timeout for device querying. Default: %u.\n", dev->timeout);
printf(" --device-error-delay <sec> ────────── Delay before trying to connect to the device again\n"); SAY(" --device-error-delay <sec> ────────── Delay before trying to connect to the device again");
printf(" after an error (timeout for example). Default: %u.\n\n", stream->error_delay); SAY(" after an error (timeout for example). Default: %u.\n", stream->error_delay);
printf("Image control options:\n"); SAY("Image control options:");
printf("══════════════════════\n"); SAY("══════════════════════");
printf(" --image-default ────────────────────── Reset all image settings below to default. Default: no change.\n\n"); SAY(" --image-default ────────────────────── Reset all image settings below to default. Default: no change.\n");
printf(" --brightness <N|auto|default> ──────── Set brightness. Default: no change.\n\n"); SAY(" --brightness <N|auto|default> ──────── Set brightness. Default: no change.\n");
printf(" --contrast <N|default> ─────────────── Set contrast. Default: no change.\n\n"); SAY(" --contrast <N|default> ─────────────── Set contrast. Default: no change.\n");
printf(" --saturation <N|default> ───────────── Set saturation. Default: no change.\n\n"); SAY(" --saturation <N|default> ───────────── Set saturation. Default: no change.\n");
printf(" --hue <N|auto|default> ─────────────── Set hue. Default: no change.\n\n"); SAY(" --hue <N|auto|default> ─────────────── Set hue. Default: no change.\n");
printf(" --gamma <N|default> ─────────────────── Set gamma. Default: no change.\n\n"); SAY(" --gamma <N|default> ─────────────────── Set gamma. Default: no change.\n");
printf(" --sharpness <N|default> ────────────── Set sharpness. Default: no change.\n\n"); SAY(" --sharpness <N|default> ────────────── Set sharpness. Default: no change.\n");
printf(" --backlight-compensation <N|default> ─ Set backlight compensation. Default: no change.\n\n"); SAY(" --backlight-compensation <N|default> ─ Set backlight compensation. Default: no change.\n");
printf(" --white-balance <N|auto|default> ───── Set white balance. Default: no change.\n\n"); SAY(" --white-balance <N|auto|default> ───── Set white balance. Default: no change.\n");
printf(" --gain <N|auto|default> ────────────── Set gain. Default: no change.\n\n"); SAY(" --gain <N|auto|default> ────────────── Set gain. Default: no change.\n");
printf(" --color-effect <N|default> ─────────── Set color effect. Default: no change.\n\n"); SAY(" --color-effect <N|default> ─────────── Set color effect. Default: no change.\n");
printf(" --flip-vertical <1|0|default> ──────── Set vertical flip. Default: no change.\n\n"); SAY(" --flip-vertical <1|0|default> ──────── Set vertical flip. Default: no change.\n");
printf(" --flip-horizontal <1|0|default> ────── Set horizontal flip. Default: no change.\n\n"); SAY(" --flip-horizontal <1|0|default> ────── Set horizontal flip. Default: no change.\n");
printf(" Hint: use v4l2-ctl --list-ctrls-menus to query available controls of the device.\n\n"); SAY(" Hint: use v4l2-ctl --list-ctrls-menus to query available controls of the device.\n");
printf("HTTP server options:\n"); SAY("HTTP server options:");
printf("════════════════════\n"); SAY("════════════════════");
printf(" -s|--host <address> ──────── Listen on Hostname or IP. Default: %s.\n\n", server->host); SAY(" -s|--host <address> ──────── Listen on Hostname or IP. Default: %s.\n", server->host);
printf(" -p|--port <N> ────────────── Bind to this TCP port. Default: %u.\n\n", server->port); SAY(" -p|--port <N> ────────────── Bind to this TCP port. Default: %u.\n", server->port);
printf(" -U|--unix <path> ─────────── Bind to UNIX domain socket. Default: disabled.\n\n"); SAY(" -U|--unix <path> ─────────── Bind to UNIX domain socket. Default: disabled.\n");
printf(" -D|--unix-rm ─────────────── Try to remove old UNIX socket file before binding. Default: disabled.\n\n"); SAY(" -D|--unix-rm ─────────────── Try to remove old UNIX socket file before binding. Default: disabled.\n");
printf(" -M|--unix-mode <mode> ────── Set UNIX socket file permissions (like 777). Default: disabled.\n\n"); SAY(" -M|--unix-mode <mode> ────── Set UNIX socket file permissions (like 777). Default: disabled.\n");
printf(" --user <name> ────────────── HTTP basic auth user. Default: disabled.\n\n"); SAY(" --user <name> ────────────── HTTP basic auth user. Default: disabled.\n");
printf(" --passwd <str> ───────────── HTTP basic auth passwd. Default: empty.\n\n"); SAY(" --passwd <str> ───────────── HTTP basic auth passwd. Default: empty.\n");
printf(" --static <path> ───────────── Path to dir with static files instead of embedded root index page.\n"); SAY(" --static <path> ───────────── Path to dir with static files instead of embedded root index page.");
printf(" Symlinks are not supported for security reasons. Default: disabled.\n\n"); SAY(" Symlinks are not supported for security reasons. Default: disabled.\n");
printf(" -e|--drop-same-frames <N> ── Don't send identical frames to clients, but no more than specified number.\n"); SAY(" -e|--drop-same-frames <N> ── Don't send identical frames to clients, but no more than specified number.");
printf(" It can significantly reduce the outgoing traffic, but will increase\n"); SAY(" It can significantly reduce the outgoing traffic, but will increase");
printf(" the CPU loading. Don't use this option with analog signal sources\n"); SAY(" the CPU loading. Don't use this option with analog signal sources");
printf(" or webcams, it's useless. Default: disabled.\n\n"); SAY(" or webcams, it's useless. Default: disabled.\n");
printf(" -l|--slowdown ────────────── Slowdown capturing to 1 FPS or less when no stream clients are connected.\n"); SAY(" -l|--slowdown ────────────── Slowdown capturing to 1 FPS or less when no stream clients are connected.");
printf(" Useful to reduce CPU consumption. Default: disabled.\n\n"); SAY(" Useful to reduce CPU consumption. Default: disabled.\n");
printf(" -R|--fake-resolution <WxH> ─ Override image resolution for the /state. Default: disabled.\n\n"); SAY(" -R|--fake-resolution <WxH> ─ Override image resolution for the /state. Default: disabled.\n");
printf(" --tcp-nodelay ────────────── Set TCP_NODELAY flag to the client /stream socket. Ignored for --unix.\n"); SAY(" --tcp-nodelay ────────────── Set TCP_NODELAY flag to the client /stream socket. Ignored for --unix.");
printf(" Default: disabled.\n\n"); SAY(" Default: disabled.\n");
printf(" --allow-origin <str> ─────── Set Access-Control-Allow-Origin header. Default: disabled.\n\n"); SAY(" --allow-origin <str> ─────── Set Access-Control-Allow-Origin header. Default: disabled.\n");
printf(" --server-timeout <sec> ───── Timeout for client connections. Default: %u.\n\n", server->timeout); SAY(" --server-timeout <sec> ───── Timeout for client connections. Default: %u.\n", server->timeout);
#ifdef WITH_OMX # ifdef WITH_OMX
printf("H264 sink options:\n"); SAY("H264 sink options:");
printf("═════════════════\n"); SAY("═════════════════");
printf(" --h264-sink <name> ──────── Use the shared memory to sink H264 frames encoded by MMAL.\n"); SAY(" --h264-sink <name> ──────── Use the shared memory to sink H264 frames encoded by MMAL.");
printf(" Most likely you will never need it. Default: disabled.\n\n"); SAY(" Most likely you will never need it. Default: disabled.\n");
printf(" --h264-sink-mode <mode> ─── Set H264 sink permissions (like 777). Default: 660.\n\n"); SAY(" --h264-sink-mode <mode> ─── Set H264 sink permissions (like 777). Default: 660.\n");
printf(" --h264-sink-rm ──────────── Remove shared memory on stop. Default: disabled.\n\n"); SAY(" --h264-sink-rm ──────────── Remove shared memory on stop. Default: disabled.\n");
printf(" --h264-sink-timeout <sec> ─ Timeout for lock. Default: 1.\n\n"); SAY(" --h264-sink-timeout <sec> ─ Timeout for lock. Default: 1.\n");
#endif # endif
#ifdef WITH_GPIO # ifdef WITH_GPIO
printf("GPIO options:\n"); SAY("GPIO options:");
printf("═════════════\n"); SAY("═════════════");
printf(" --gpio-device </dev/path> ───── Path to GPIO character device. Default: %s.\n\n", gpio.path); SAY(" --gpio-device </dev/path> ───── Path to GPIO character device. Default: %s.\n", gpio.path);
printf(" --gpio-consumer-prefix <str> ── Consumer prefix for GPIO outputs. Default: %s.\n\n", gpio.consumer_prefix); SAY(" --gpio-consumer-prefix <str> ── Consumer prefix for GPIO outputs. Default: %s.\n", gpio.consumer_prefix);
printf(" --gpio-prog-running <pin> ───── Set 1 on GPIO pin while uStreamer is running. Default: disabled.\n\n"); SAY(" --gpio-prog-running <pin> ───── Set 1 on GPIO pin while uStreamer is running. Default: disabled.\n");
printf(" --gpio-stream-online <pin> ──── Set 1 while streaming. Default: disabled.\n\n"); SAY(" --gpio-stream-online <pin> ──── Set 1 while streaming. Default: disabled.\n");
printf(" --gpio-has-http-clients <pin> ─ Set 1 while stream has at least one client. Default: disabled.\n\n"); SAY(" --gpio-has-http-clients <pin> ─ Set 1 while stream has at least one client. Default: disabled.\n");
#endif # endif
#if (defined(HAS_PDEATHSIG) || defined(WITH_SETPROCTITLE)) # if (defined(HAS_PDEATHSIG) || defined(WITH_SETPROCTITLE))
printf("Process options:\n"); SAY("Process options:");
printf("════════════════\n"); SAY("════════════════");
#endif # endif
#ifdef HAS_PDEATHSIG # ifdef HAS_PDEATHSIG
printf(" --exit-on-parent-death ─────── Exit the program if the parent process is dead. Default: disabled.\n\n"); SAY(" --exit-on-parent-death ─────── Exit the program if the parent process is dead. Default: disabled.\n");
#endif # endif
#ifdef WITH_SETPROCTITLE # ifdef WITH_SETPROCTITLE
printf(" --process-name-prefix <str> ── Set process name prefix which will be displayed in the process list\n"); SAY(" --process-name-prefix <str> ── Set process name prefix which will be displayed in the process list");
printf(" like '<str>: ustreamer --blah-blah-blah'. Default: disabled.\n\n"); SAY(" like '<str>: ustreamer --blah-blah-blah'. Default: disabled.\n");
printf(" --notify-parent ────────────── Send SIGUSR2 to the parent process when the stream parameters are changed.\n"); SAY(" --notify-parent ────────────── Send SIGUSR2 to the parent process when the stream parameters are changed.");
printf(" Checking changes is performed for the online flag and image resolution.\n\n"); SAY(" Checking changes is performed for the online flag and image resolution.\n");
#endif # endif
printf("Logging options:\n"); SAY("Logging options:");
printf("════════════════\n"); SAY("════════════════");
printf(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).\n"); SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).");
printf(" Enabling debugging messages can slow down the program.\n"); SAY(" Enabling debugging messages can slow down the program.");
printf(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug).\n"); SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug).");
printf(" Default: %d.\n\n", log_level); SAY(" Default: %d.\n", log_level);
printf(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n\n"); SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n");
printf(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n\n"); SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n");
printf(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n\n"); SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n");
printf(" --force-log-colors ─ Force color logging. Default: colored if stdout is a TTY.\n\n"); SAY(" --force-log-colors ─ Force color logging. Default: colored if stderr is a TTY.\n");
printf(" --no-log-colors ──── Disable color logging. Default: ditto.\n\n"); SAY(" --no-log-colors ──── Disable color logging. Default: ditto.\n");
printf("Help options:\n"); SAY("Help options:");
printf("═════════════\n"); SAY("═════════════");
printf(" -h|--help ─────── Print this text and exit.\n\n"); SAY(" -h|--help ─────── Print this text and exit.\n");
printf(" -v|--version ──── Print version and exit.\n\n"); SAY(" -v|--version ──── Print version and exit.\n");
printf(" --features ────── Print list of supported features.\n\n"); SAY(" --features ────── Print list of supported features.\n");
# undef SAY
} }

View File

@@ -256,7 +256,7 @@ Enable verbose messages and lower (same as \-\-log\-level=2). Default: disabled.
Enable debug messages and lower (same as \-\-log\-level=3). Default: disabled. Enable debug messages and lower (same as \-\-log\-level=3). Default: disabled.
.TP .TP
.BR \-\-force\-log\-colors .BR \-\-force\-log\-colors
Force color logging. Default: colored if stdout is a TTY. Force color logging. Default: colored if stderr is a TTY.
.TP .TP
.BR \-\-no\-log\-colors .BR \-\-no\-log\-colors
Disable color logging. Default: ditto. Disable color logging. Default: ditto.