mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-12 09:17:44 +03:00
Merge pull request #17702 from rnhmjoj/master
Extend $SYSTEMD_COLORS to switch colors mode
This commit is contained in:
commit
e4dde4e87d
@ -94,10 +94,11 @@
|
||||
<varlistentry id='colors'>
|
||||
<term><varname>$SYSTEMD_COLORS</varname></term>
|
||||
|
||||
<listitem><para>The value must be a boolean. Controls whether colorized output should be
|
||||
generated. This can be specified to override the decision that <command>systemd</command> makes based
|
||||
on <varname>$TERM</varname> and what the console is connected to.</para>
|
||||
</listitem>
|
||||
<listitem><para>Takes a boolean argument. When true, <command>systemd</command> and related utilities
|
||||
will use colors in their output, otherwise the output will be monochrome. Additionally, the variable can
|
||||
take one of the following special values: <literal>16</literal>, <literal>256</literal> to restrict the use
|
||||
of colors to the base 16 or 256 ANSI colors, respectively. This can be specified to override the automatic
|
||||
decision based on <varname>$TERM</varname> and what the console is connected to.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<!-- This is not documented on purpose, because it is not clear if $NO_COLOR will become supported
|
||||
|
@ -404,7 +404,7 @@ static int write_to_console(
|
||||
if (show_location) {
|
||||
const char *lon = "", *loff = "";
|
||||
if (log_get_show_color()) {
|
||||
lon = ANSI_HIGHLIGHT_YELLOW4;
|
||||
lon = ansi_highlight_yellow4();
|
||||
loff = ANSI_NORMAL;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ static volatile unsigned cached_columns = 0;
|
||||
static volatile unsigned cached_lines = 0;
|
||||
|
||||
static volatile int cached_on_tty = -1;
|
||||
static volatile int cached_colors_enabled = -1;
|
||||
static volatile int cached_color_mode = _COLOR_INVALID;
|
||||
static volatile int cached_underline_enabled = -1;
|
||||
|
||||
int chvt(int vt) {
|
||||
@ -164,8 +164,7 @@ int ask_char(char *ret, const char *replies, const char *fmt, ...) {
|
||||
char c;
|
||||
bool need_nl = true;
|
||||
|
||||
if (colors_enabled())
|
||||
fputs(ANSI_HIGHLIGHT, stdout);
|
||||
fputs(ansi_highlight(), stdout);
|
||||
|
||||
putchar('\r');
|
||||
|
||||
@ -173,8 +172,7 @@ int ask_char(char *ret, const char *replies, const char *fmt, ...) {
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (colors_enabled())
|
||||
fputs(ANSI_NORMAL, stdout);
|
||||
fputs(ansi_normal(), stdout);
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
@ -213,15 +211,13 @@ int ask_string(char **ret, const char *text, ...) {
|
||||
assert(ret);
|
||||
assert(text);
|
||||
|
||||
if (colors_enabled())
|
||||
fputs(ANSI_HIGHLIGHT, stdout);
|
||||
fputs(ansi_highlight(), stdout);
|
||||
|
||||
va_start(ap, text);
|
||||
vprintf(text, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (colors_enabled())
|
||||
fputs(ANSI_NORMAL, stdout);
|
||||
fputs(ansi_normal(), stdout);
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
@ -867,7 +863,7 @@ void reset_terminal_feature_caches(void) {
|
||||
cached_columns = 0;
|
||||
cached_lines = 0;
|
||||
|
||||
cached_colors_enabled = -1;
|
||||
cached_color_mode = _COLOR_INVALID;
|
||||
cached_underline_enabled = -1;
|
||||
cached_on_tty = -1;
|
||||
}
|
||||
@ -1206,38 +1202,57 @@ bool terminal_is_dumb(void) {
|
||||
return getenv_terminal_is_dumb();
|
||||
}
|
||||
|
||||
bool colors_enabled(void) {
|
||||
static ColorMode parse_systemd_colors(void) {
|
||||
const char *e;
|
||||
int r;
|
||||
|
||||
/* Returns true if colors are considered supported on our stdout. For that we check $SYSTEMD_COLORS first
|
||||
* (which is the explicit way to turn colors on/off). If that didn't work we turn colors off unless we are on a
|
||||
* TTY. And if we are on a TTY we turn it off if $TERM is set to "dumb". There's one special tweak though: if
|
||||
* we are PID 1 then we do not check whether we are connected to a TTY, because we don't keep /dev/console open
|
||||
* continuously due to fear of SAK, and hence things are a bit weird. */
|
||||
e = getenv("SYSTEMD_COLORS");
|
||||
if (!e)
|
||||
return _COLOR_INVALID;
|
||||
if (streq(e, "16"))
|
||||
return COLOR_16;
|
||||
if (streq(e, "256"))
|
||||
return COLOR_256;
|
||||
r = parse_boolean(e);
|
||||
if (r >= 0)
|
||||
return r > 0 ? COLOR_ON : COLOR_OFF;
|
||||
return _COLOR_INVALID;
|
||||
}
|
||||
|
||||
if (cached_colors_enabled < 0) {
|
||||
int val;
|
||||
ColorMode get_color_mode(void) {
|
||||
|
||||
val = getenv_bool("SYSTEMD_COLORS");
|
||||
if (val >= 0)
|
||||
cached_colors_enabled = val;
|
||||
/* Returns the mode used to choose output colors. The possible modes are COLOR_OFF for no colors,
|
||||
* COLOR_16 for only the base 16 ANSI colors, COLOR_256 for more colors and COLOR_ON for unrestricted
|
||||
* color output. For that we check $SYSTEMD_COLORS first (which is the explicit way to
|
||||
* change the mode). If that didn't work we turn colors off unless we are on a TTY. And if we are on a TTY
|
||||
* we turn it off if $TERM is set to "dumb". There's one special tweak though: if we are PID 1 then we do not
|
||||
* check whether we are connected to a TTY, because we don't keep /dev/console open continuously due to fear
|
||||
* of SAK, and hence things are a bit weird. */
|
||||
ColorMode m;
|
||||
|
||||
if (cached_color_mode < 0) {
|
||||
m = parse_systemd_colors();
|
||||
if (m >= 0)
|
||||
cached_color_mode = m;
|
||||
else if (getenv("NO_COLOR"))
|
||||
/* We only check for the presence of the variable; value is ignored. */
|
||||
cached_colors_enabled = false;
|
||||
cached_color_mode = COLOR_OFF;
|
||||
|
||||
else if (getpid_cached() == 1)
|
||||
/* PID1 outputs to the console without holding it open all the time */
|
||||
cached_colors_enabled = !getenv_terminal_is_dumb();
|
||||
/* PID1 outputs to the console without holding it open all the time.
|
||||
* Also note the Linux console can only handle 16 colors.
|
||||
*/
|
||||
cached_color_mode = getenv_terminal_is_dumb() ? COLOR_OFF : COLOR_16;
|
||||
else
|
||||
cached_colors_enabled = !terminal_is_dumb();
|
||||
cached_color_mode = terminal_is_dumb() ? COLOR_OFF : COLOR_256;
|
||||
}
|
||||
|
||||
return cached_colors_enabled;
|
||||
return cached_color_mode;
|
||||
}
|
||||
|
||||
bool dev_console_colors_enabled(void) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int b;
|
||||
ColorMode m;
|
||||
|
||||
/* Returns true if we assume that color is supported on /dev/console.
|
||||
*
|
||||
@ -1246,9 +1261,9 @@ bool dev_console_colors_enabled(void) {
|
||||
* line. If we find $TERM set we assume color if it's not set to "dumb", similarly to how regular
|
||||
* colors_enabled() operates. */
|
||||
|
||||
b = getenv_bool("SYSTEMD_COLORS");
|
||||
if (b >= 0)
|
||||
return b;
|
||||
m = parse_systemd_colors();
|
||||
if (m >= 0)
|
||||
return m;
|
||||
|
||||
if (getenv("NO_COLOR"))
|
||||
return false;
|
||||
@ -1353,7 +1368,7 @@ void get_log_colors(int priority, const char **on, const char **off, const char
|
||||
|
||||
if (priority <= LOG_ERR) {
|
||||
if (on)
|
||||
*on = ANSI_HIGHLIGHT_RED;
|
||||
*on = ansi_highlight_red();
|
||||
if (off)
|
||||
*off = ANSI_NORMAL;
|
||||
if (highlight)
|
||||
@ -1361,7 +1376,7 @@ void get_log_colors(int priority, const char **on, const char **off, const char
|
||||
|
||||
} else if (priority <= LOG_WARNING) {
|
||||
if (on)
|
||||
*on = ANSI_HIGHLIGHT_YELLOW;
|
||||
*on = ansi_highlight_yellow();
|
||||
if (off)
|
||||
*off = ANSI_NORMAL;
|
||||
if (highlight)
|
||||
@ -1373,14 +1388,14 @@ void get_log_colors(int priority, const char **on, const char **off, const char
|
||||
if (off)
|
||||
*off = ANSI_NORMAL;
|
||||
if (highlight)
|
||||
*highlight = ANSI_HIGHLIGHT_RED;
|
||||
*highlight = ansi_highlight_red();
|
||||
|
||||
} else if (priority >= LOG_DEBUG) {
|
||||
if (on)
|
||||
*on = ANSI_GREY;
|
||||
*on = ansi_grey();
|
||||
if (off)
|
||||
*off = ANSI_NORMAL;
|
||||
if (highlight)
|
||||
*highlight = ANSI_HIGHLIGHT_RED;
|
||||
*highlight = ansi_highlight_red();
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,10 @@
|
||||
#define ANSI_HIGHLIGHT "\x1B[0;1;39m"
|
||||
#define ANSI_HIGHLIGHT_UNDERLINE "\x1B[0;1;4m"
|
||||
|
||||
/* Fallback colors: 256 -> 16 */
|
||||
#define ANSI_HIGHLIGHT_GREY_FALLBACK "\x1B[0;1;90m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW_FALLBACK "\x1B[0;1;33m"
|
||||
|
||||
/* Reset/clear ANSI styles */
|
||||
#define ANSI_NORMAL "\x1B[0m"
|
||||
|
||||
@ -93,6 +97,23 @@ typedef enum AcquireTerminalFlags {
|
||||
ACQUIRE_TERMINAL_PERMISSIVE = 1 << 2,
|
||||
} AcquireTerminalFlags;
|
||||
|
||||
/* Limits the use of ANSI colors to a subset. */
|
||||
typedef enum ColorMode {
|
||||
/* No colors, monochrome output. */
|
||||
COLOR_OFF = 0,
|
||||
|
||||
/* All colors, no restrictions. */
|
||||
COLOR_ON = 1,
|
||||
|
||||
/* Only the base 16 colors. */
|
||||
COLOR_16 = 16,
|
||||
|
||||
/* Only 256 colors. */
|
||||
COLOR_256 = 256,
|
||||
|
||||
_COLOR_INVALID = -1,
|
||||
} ColorMode;
|
||||
|
||||
int acquire_terminal(const char *name, AcquireTerminalFlags flags, usec_t timeout);
|
||||
int release_terminal(void);
|
||||
|
||||
@ -127,19 +148,44 @@ void reset_terminal_feature_caches(void);
|
||||
|
||||
bool on_tty(void);
|
||||
bool terminal_is_dumb(void);
|
||||
bool colors_enabled(void);
|
||||
ColorMode get_color_mode(void);
|
||||
bool underline_enabled(void);
|
||||
bool dev_console_colors_enabled(void);
|
||||
|
||||
static inline bool colors_enabled(void) {
|
||||
|
||||
/* Returns true if colors are considered supported on our stdout. */
|
||||
return get_color_mode() != COLOR_OFF;
|
||||
}
|
||||
|
||||
#define DEFINE_ANSI_FUNC(name, NAME) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
return colors_enabled() ? ANSI_##NAME : ""; \
|
||||
}
|
||||
|
||||
#define DEFINE_ANSI_FUNC_UNDERLINE(name, NAME, REPLACEMENT) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
return underline_enabled() ? ANSI_##NAME : \
|
||||
colors_enabled() ? ANSI_##REPLACEMENT : ""; \
|
||||
#define DEFINE_ANSI_FUNC_256(name, NAME, FALLBACK) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
switch (get_color_mode()) { \
|
||||
case COLOR_OFF: return ""; \
|
||||
case COLOR_16: return ANSI_##FALLBACK; \
|
||||
default : return ANSI_##NAME; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DEFINE_ANSI_FUNC_UNDERLINE(name, NAME) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
return underline_enabled() ? ANSI_##NAME ANSI_UNDERLINE : \
|
||||
colors_enabled() ? ANSI_##NAME : ""; \
|
||||
}
|
||||
|
||||
|
||||
#define DEFINE_ANSI_FUNC_UNDERLINE_256(name, NAME, FALLBACK) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
switch (get_color_mode()) { \
|
||||
case COLOR_OFF: return ""; \
|
||||
case COLOR_16: return underline_enabled() ? ANSI_##FALLBACK ANSI_UNDERLINE : ANSI_##FALLBACK; \
|
||||
default : return underline_enabled() ? ANSI_##NAME ANSI_UNDERLINE: ANSI_##NAME; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_ANSI_FUNC(normal, NORMAL);
|
||||
@ -152,7 +198,7 @@ DEFINE_ANSI_FUNC(blue, BLUE);
|
||||
DEFINE_ANSI_FUNC(magenta, MAGENTA);
|
||||
DEFINE_ANSI_FUNC(cyan, CYAN);
|
||||
DEFINE_ANSI_FUNC(white, WHITE);
|
||||
DEFINE_ANSI_FUNC(grey, GREY);
|
||||
DEFINE_ANSI_FUNC_256(grey, GREY, BRIGHT_BLACK);
|
||||
|
||||
DEFINE_ANSI_FUNC(bright_black, BRIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC(bright_red, BRIGHT_RED);
|
||||
@ -163,29 +209,30 @@ DEFINE_ANSI_FUNC(bright_magenta, BRIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(bright_cyan, BRIGHT_CYAN);
|
||||
DEFINE_ANSI_FUNC(bright_white, BRIGHT_WHITE);
|
||||
|
||||
DEFINE_ANSI_FUNC(highlight_black, HIGHLIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC(highlight_red, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC(highlight_green, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC(highlight_yellow, HIGHLIGHT_YELLOW);
|
||||
DEFINE_ANSI_FUNC(highlight_blue, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC(highlight_magenta, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(highlight_cyan, HIGHLIGHT_CYAN);
|
||||
DEFINE_ANSI_FUNC(highlight_grey, HIGHLIGHT_GREY);
|
||||
DEFINE_ANSI_FUNC(highlight_white, HIGHLIGHT_WHITE);
|
||||
DEFINE_ANSI_FUNC(highlight_black, HIGHLIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC(highlight_red, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC(highlight_green, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC_256(highlight_yellow, HIGHLIGHT_YELLOW, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC_256(highlight_yellow4, HIGHLIGHT_YELLOW4, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC(highlight_blue, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC(highlight_magenta, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(highlight_cyan, HIGHLIGHT_CYAN);
|
||||
DEFINE_ANSI_FUNC_256(highlight_grey, HIGHLIGHT_GREY, HIGHLIGHT_GREY_FALLBACK);
|
||||
DEFINE_ANSI_FUNC(highlight_white, HIGHLIGHT_WHITE);
|
||||
|
||||
static inline const char* _ansi_highlight_yellow(void) {
|
||||
return colors_enabled() ? _ANSI_HIGHLIGHT_YELLOW : "";
|
||||
}
|
||||
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(underline, UNDERLINE, NORMAL);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_underline, HIGHLIGHT_UNDERLINE, HIGHLIGHT);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(grey_underline, GREY_UNDERLINE, GREY);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_red_underline, HIGHLIGHT_RED_UNDERLINE, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_green_underline, HIGHLIGHT_GREEN_UNDERLINE, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_yellow_underline, HIGHLIGHT_YELLOW_UNDERLINE, HIGHLIGHT_YELLOW);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_blue_underline, HIGHLIGHT_BLUE_UNDERLINE, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_magenta_underline, HIGHLIGHT_MAGENTA_UNDERLINE, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_grey_underline, HIGHLIGHT_GREY_UNDERLINE, HIGHLIGHT_GREY);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(underline, NORMAL);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_underline, HIGHLIGHT);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(grey_underline, GREY, BRIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_red_underline, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_green_underline, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(highlight_yellow_underline, HIGHLIGHT_YELLOW, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_blue_underline, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_magenta_underline, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(highlight_grey_underline, HIGHLIGHT_GREY, HIGHLIGHT_GREY_FALLBACK);
|
||||
|
||||
int get_ctty_devnr(pid_t pid, dev_t *d);
|
||||
int get_ctty(pid_t, dev_t *_devnr, char **r);
|
||||
|
@ -41,7 +41,9 @@ static void draw_progress(uint64_t p, usec_t *last_usec) {
|
||||
|
||||
fputs("\r", stdout);
|
||||
if (colors_enabled())
|
||||
fputs("\x1B[?25l" ANSI_HIGHLIGHT_GREEN, stdout);
|
||||
fputs("\x1B[?25l", stdout);
|
||||
|
||||
fputs(ansi_highlight_green(), stdout);
|
||||
|
||||
for (i = 0; i < j; i++)
|
||||
fputs("\xe2\x96\x88", stdout);
|
||||
|
@ -481,7 +481,7 @@ int ask_password_tty(
|
||||
|
||||
if (!(flags & ASK_PASSWORD_SILENT) && !(flags & ASK_PASSWORD_ECHO)) {
|
||||
if (use_color)
|
||||
(void) loop_write(ttyfd, ANSI_GREY, STRLEN(ANSI_GREY), false);
|
||||
(void) loop_write(ttyfd, ansi_grey(), strlen(ansi_grey()), false);
|
||||
(void) loop_write(ttyfd, PRESS_TAB, strlen(PRESS_TAB), false);
|
||||
press_tab_visible = true;
|
||||
}
|
||||
|
@ -1495,7 +1495,7 @@ static void json_format_string(FILE *f, const char *q, JsonFormatFlags flags) {
|
||||
fputc('"', f);
|
||||
|
||||
if (flags & JSON_FORMAT_COLOR)
|
||||
fputs(ANSI_GREEN, f);
|
||||
fputs(ansi_green(), f);
|
||||
|
||||
for (; *q; q++)
|
||||
switch (*q) {
|
||||
@ -1557,7 +1557,7 @@ static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const cha
|
||||
return -errno;
|
||||
|
||||
if (flags & JSON_FORMAT_COLOR)
|
||||
fputs(ANSI_HIGHLIGHT_BLUE, f);
|
||||
fputs(ansi_highlight_blue(), f);
|
||||
|
||||
fprintf(f, "%.*Le", DECIMAL_DIG, json_variant_real(v));
|
||||
|
||||
@ -1570,7 +1570,7 @@ static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const cha
|
||||
|
||||
case JSON_VARIANT_INTEGER:
|
||||
if (flags & JSON_FORMAT_COLOR)
|
||||
fputs(ANSI_HIGHLIGHT_BLUE, f);
|
||||
fputs(ansi_highlight_blue(), f);
|
||||
|
||||
fprintf(f, "%" PRIdMAX, json_variant_integer(v));
|
||||
|
||||
@ -1580,7 +1580,7 @@ static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const cha
|
||||
|
||||
case JSON_VARIANT_UNSIGNED:
|
||||
if (flags & JSON_FORMAT_COLOR)
|
||||
fputs(ANSI_HIGHLIGHT_BLUE, f);
|
||||
fputs(ansi_highlight_blue(), f);
|
||||
|
||||
fprintf(f, "%" PRIuMAX, json_variant_unsigned(v));
|
||||
|
||||
|
@ -67,7 +67,7 @@ static int print_catalog(FILE *f, sd_journal *j) {
|
||||
prefix = "--";
|
||||
|
||||
if (colors_enabled())
|
||||
newline = strjoina(ANSI_NORMAL "\n" ANSI_GREY, prefix, ANSI_NORMAL " " ANSI_GREEN);
|
||||
newline = strjoina(ANSI_NORMAL "\n", ansi_grey(), prefix, ANSI_NORMAL " ", ansi_green());
|
||||
else
|
||||
newline = strjoina("\n", prefix, " ");
|
||||
|
||||
@ -76,7 +76,7 @@ static int print_catalog(FILE *f, sd_journal *j) {
|
||||
return log_oom();
|
||||
|
||||
if (colors_enabled())
|
||||
fprintf(f, ANSI_GREY "%s" ANSI_NORMAL " " ANSI_GREEN, prefix);
|
||||
fprintf(f, "%s%s %s%s", ansi_grey(), prefix, ANSI_NORMAL, ansi_green());
|
||||
else
|
||||
fprintf(f, "%s ", prefix);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user