terminal-util: Move various functions to ansi-color.c
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "log.h"
|
||||
#include "process-util.h"
|
||||
#include "string-table.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
|
||||
static volatile int cached_color_mode = _COLOR_MODE_INVALID;
|
||||
static volatile int cached_underline_enabled = -1;
|
||||
|
||||
bool underline_enabled(void) {
|
||||
|
||||
if (cached_underline_enabled < 0) {
|
||||
|
||||
/* The Linux console doesn't support underlining, turn it off, but only there. */
|
||||
|
||||
if (colors_enabled())
|
||||
cached_underline_enabled = !streq_ptr(getenv("TERM"), "linux");
|
||||
else
|
||||
cached_underline_enabled = false;
|
||||
}
|
||||
|
||||
return cached_underline_enabled;
|
||||
}
|
||||
|
||||
void reset_ansi_feature_caches(void) {
|
||||
cached_color_mode = _COLOR_MODE_INVALID;
|
||||
cached_underline_enabled = -1;
|
||||
}
|
||||
|
||||
ColorMode parse_systemd_colors(void) {
|
||||
const char *e;
|
||||
|
||||
e = getenv("SYSTEMD_COLORS");
|
||||
if (!e)
|
||||
return _COLOR_MODE_INVALID;
|
||||
|
||||
ColorMode m = color_mode_from_string(e);
|
||||
if (m < 0)
|
||||
return log_debug_errno(m, "Failed to parse $SYSTEMD_COLORS value '%s', ignoring: %m", e);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
static ColorMode get_color_mode_impl(void) {
|
||||
/* 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_24BIT for
|
||||
* unrestricted color output. */
|
||||
|
||||
/* First, we check $SYSTEMD_COLORS, which is the explicit way to change the mode. */
|
||||
ColorMode m = parse_systemd_colors();
|
||||
if (m >= 0)
|
||||
return m;
|
||||
|
||||
/* Next, check for the presence of $NO_COLOR; value is ignored. */
|
||||
if (getenv("NO_COLOR"))
|
||||
return COLOR_OFF;
|
||||
|
||||
/* If the above 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. */
|
||||
if (getpid_cached() == 1 ? getenv_terminal_is_dumb() : terminal_is_dumb())
|
||||
return COLOR_OFF;
|
||||
|
||||
/* We failed to figure out any reason to *disable* colors. Let's see how many colors we shall use. */
|
||||
if (STRPTR_IN_SET(getenv("COLORTERM"),
|
||||
"truecolor",
|
||||
"24bit"))
|
||||
return COLOR_24BIT;
|
||||
|
||||
/* Note that the Linux console can only display 16 colors. We still enable 256 color mode
|
||||
* even for PID1 output though (which typically goes to the Linux console), since the Linux
|
||||
* console is able to parse the 256 color sequences and automatically map them to the closest
|
||||
* color in the 16 color palette (since kernel 3.16). Doing 256 colors is nice for people who
|
||||
* invoke systemd in a container or via a serial link or such, and use a true 256 color
|
||||
* terminal to do so. */
|
||||
return COLOR_256;
|
||||
}
|
||||
|
||||
ColorMode get_color_mode(void) {
|
||||
if (cached_color_mode < 0)
|
||||
cached_color_mode = get_color_mode_impl();
|
||||
|
||||
return cached_color_mode;
|
||||
}
|
||||
|
||||
|
||||
static const char* const color_mode_table[_COLOR_MODE_MAX] = {
|
||||
[COLOR_OFF] = "off",
|
||||
[COLOR_16] = "16",
|
||||
[COLOR_256] = "256",
|
||||
[COLOR_24BIT] = "24bit",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(color_mode, ColorMode, COLOR_24BIT);
|
||||
+28
-1
@@ -1,7 +1,34 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "terminal-util.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
/* Limits the use of ANSI colors to a subset. */
|
||||
typedef enum ColorMode {
|
||||
COLOR_OFF, /* No colors, monochrome output. */
|
||||
COLOR_16, /* Only the base 16 colors. */
|
||||
COLOR_256, /* Only 256 colors. */
|
||||
COLOR_24BIT, /* For truecolor or 24bit color support, no restriction. */
|
||||
_COLOR_MODE_MAX,
|
||||
_COLOR_MODE_INVALID = -EINVAL,
|
||||
} ColorMode;
|
||||
|
||||
const char* color_mode_to_string(ColorMode m) _const_;
|
||||
ColorMode color_mode_from_string(const char *s) _pure_;
|
||||
|
||||
ColorMode get_color_mode(void);
|
||||
static inline bool colors_enabled(void) {
|
||||
/* Returns true if colors are considered supported on our stdout. */
|
||||
return get_color_mode() != COLOR_OFF;
|
||||
}
|
||||
|
||||
ColorMode parse_systemd_colors(void);
|
||||
|
||||
bool underline_enabled(void);
|
||||
|
||||
void reset_ansi_feature_caches(void);
|
||||
|
||||
/* Regular colors */
|
||||
#define ANSI_BLACK "\x1B[0;30m" /* Some type of grey usually. */
|
||||
|
||||
@@ -4,6 +4,7 @@ basic_sources = files(
|
||||
'MurmurHash2.c',
|
||||
'af-list.c',
|
||||
'alloc-util.c',
|
||||
'ansi-color.c',
|
||||
'architecture.c',
|
||||
'argv-util.c',
|
||||
'arphrd-util.c',
|
||||
|
||||
@@ -60,8 +60,6 @@ static volatile unsigned cached_lines = 0;
|
||||
|
||||
static volatile int cached_on_tty = -1;
|
||||
static volatile int cached_on_dev_null = -1;
|
||||
static volatile int cached_color_mode = _COLOR_MODE_INVALID;
|
||||
static volatile int cached_underline_enabled = -1;
|
||||
|
||||
bool isatty_safe(int fd) {
|
||||
assert(fd >= 0);
|
||||
@@ -1433,10 +1431,10 @@ void reset_terminal_feature_caches(void) {
|
||||
cached_columns = 0;
|
||||
cached_lines = 0;
|
||||
|
||||
cached_color_mode = _COLOR_MODE_INVALID;
|
||||
cached_underline_enabled = -1;
|
||||
cached_on_tty = -1;
|
||||
cached_on_dev_null = -1;
|
||||
|
||||
reset_ansi_feature_caches();
|
||||
}
|
||||
|
||||
bool on_tty(void) {
|
||||
@@ -1753,72 +1751,6 @@ bool terminal_is_dumb(void) {
|
||||
return getenv_terminal_is_dumb();
|
||||
}
|
||||
|
||||
static const char* const color_mode_table[_COLOR_MODE_MAX] = {
|
||||
[COLOR_OFF] = "off",
|
||||
[COLOR_16] = "16",
|
||||
[COLOR_256] = "256",
|
||||
[COLOR_24BIT] = "24bit",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(color_mode, ColorMode, COLOR_24BIT);
|
||||
|
||||
static ColorMode parse_systemd_colors(void) {
|
||||
const char *e;
|
||||
|
||||
e = getenv("SYSTEMD_COLORS");
|
||||
if (!e)
|
||||
return _COLOR_MODE_INVALID;
|
||||
|
||||
ColorMode m = color_mode_from_string(e);
|
||||
if (m < 0)
|
||||
return log_debug_errno(m, "Failed to parse $SYSTEMD_COLORS value '%s', ignoring: %m", e);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
static ColorMode get_color_mode_impl(void) {
|
||||
/* 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_24BIT for
|
||||
* unrestricted color output. */
|
||||
|
||||
/* First, we check $SYSTEMD_COLORS, which is the explicit way to change the mode. */
|
||||
ColorMode m = parse_systemd_colors();
|
||||
if (m >= 0)
|
||||
return m;
|
||||
|
||||
/* Next, check for the presence of $NO_COLOR; value is ignored. */
|
||||
if (getenv("NO_COLOR"))
|
||||
return COLOR_OFF;
|
||||
|
||||
/* If the above 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. */
|
||||
if (getpid_cached() == 1 ? getenv_terminal_is_dumb() : terminal_is_dumb())
|
||||
return COLOR_OFF;
|
||||
|
||||
/* We failed to figure out any reason to *disable* colors. Let's see how many colors we shall use. */
|
||||
if (STRPTR_IN_SET(getenv("COLORTERM"),
|
||||
"truecolor",
|
||||
"24bit"))
|
||||
return COLOR_24BIT;
|
||||
|
||||
/* Note that the Linux console can only display 16 colors. We still enable 256 color mode
|
||||
* even for PID1 output though (which typically goes to the Linux console), since the Linux
|
||||
* console is able to parse the 256 color sequences and automatically map them to the closest
|
||||
* color in the 16 color palette (since kernel 3.16). Doing 256 colors is nice for people who
|
||||
* invoke systemd in a container or via a serial link or such, and use a true 256 color
|
||||
* terminal to do so. */
|
||||
return COLOR_256;
|
||||
}
|
||||
|
||||
ColorMode get_color_mode(void) {
|
||||
if (cached_color_mode < 0)
|
||||
cached_color_mode = get_color_mode_impl();
|
||||
|
||||
return cached_color_mode;
|
||||
}
|
||||
|
||||
bool dev_console_colors_enabled(void) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
ColorMode m;
|
||||
@@ -1843,21 +1775,6 @@ bool dev_console_colors_enabled(void) {
|
||||
return !streq_ptr(s, "dumb");
|
||||
}
|
||||
|
||||
bool underline_enabled(void) {
|
||||
|
||||
if (cached_underline_enabled < 0) {
|
||||
|
||||
/* The Linux console doesn't support underlining, turn it off, but only there. */
|
||||
|
||||
if (colors_enabled())
|
||||
cached_underline_enabled = !streq_ptr(getenv("TERM"), "linux");
|
||||
else
|
||||
cached_underline_enabled = false;
|
||||
}
|
||||
|
||||
return cached_underline_enabled;
|
||||
}
|
||||
|
||||
int vt_restore(int fd) {
|
||||
|
||||
static const struct vt_mode mode = {
|
||||
|
||||
@@ -129,26 +129,6 @@ bool on_tty(void);
|
||||
bool getenv_terminal_is_dumb(void);
|
||||
bool terminal_is_dumb(void);
|
||||
|
||||
/* Limits the use of ANSI colors to a subset. */
|
||||
typedef enum ColorMode {
|
||||
COLOR_OFF, /* No colors, monochrome output. */
|
||||
COLOR_16, /* Only the base 16 colors. */
|
||||
COLOR_256, /* Only 256 colors. */
|
||||
COLOR_24BIT, /* For truecolor or 24bit color support, no restriction. */
|
||||
_COLOR_MODE_MAX,
|
||||
_COLOR_MODE_INVALID = -EINVAL,
|
||||
} ColorMode;
|
||||
|
||||
const char* color_mode_to_string(ColorMode m) _const_;
|
||||
ColorMode color_mode_from_string(const char *s) _pure_;
|
||||
|
||||
ColorMode get_color_mode(void);
|
||||
static inline bool colors_enabled(void) {
|
||||
/* Returns true if colors are considered supported on our stdout. */
|
||||
return get_color_mode() != COLOR_OFF;
|
||||
}
|
||||
|
||||
bool underline_enabled(void);
|
||||
bool dev_console_colors_enabled(void);
|
||||
|
||||
int get_ctty_devnr(pid_t pid, dev_t *ret);
|
||||
|
||||
Reference in New Issue
Block a user