1
0
mirror of https://github.com/systemd/systemd synced 2026-03-16 10:04:47 +01:00

Compare commits

..

No commits in common. "b61aeeb315c2c9216acb2d960cd944b6ab8ef398" and "e9a1271a0c99f0fa5a16786c85b44b2a06150ae0" have entirely different histories.

10 changed files with 38 additions and 322 deletions

View File

@ -80,8 +80,6 @@ node /org/freedesktop/hostname1 {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s OperatingSystemPrettyName = '...'; readonly s OperatingSystemPrettyName = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s OperatingSystemFancyName = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s OperatingSystemCPEName = '...'; readonly s OperatingSystemCPEName = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t OperatingSystemSupportEnd = ...; readonly t OperatingSystemSupportEnd = ...;
@ -172,8 +170,6 @@ node /org/freedesktop/hostname1 {
<variablelist class="dbus-property" generated="True" extra-ref="OperatingSystemPrettyName"/> <variablelist class="dbus-property" generated="True" extra-ref="OperatingSystemPrettyName"/>
<variablelist class="dbus-property" generated="True" extra-ref="OperatingSystemFancyName"/>
<variablelist class="dbus-property" generated="True" extra-ref="OperatingSystemCPEName"/> <variablelist class="dbus-property" generated="True" extra-ref="OperatingSystemCPEName"/>
<variablelist class="dbus-property" generated="True" extra-ref="OperatingSystemSupportEnd"/> <variablelist class="dbus-property" generated="True" extra-ref="OperatingSystemSupportEnd"/>
@ -289,11 +285,9 @@ node /org/freedesktop/hostname1 {
<para><varname>KernelName</varname>, <varname>KernelRelease</varname>, and <para><varname>KernelName</varname>, <varname>KernelRelease</varname>, and
<varname>KernelVersion</varname> expose the kernel name (e.g. <literal>Linux</literal>), release <varname>KernelVersion</varname> expose the kernel name (e.g. <literal>Linux</literal>), release
(e.g. <literal>5.0.0-11</literal>), and version (i.e. the build number, e.g. <literal>#11</literal>) as (e.g. <literal>5.0.0-11</literal>), and version (i.e. the build number, e.g. <literal>#11</literal>) as
reported by <citerefentry project="man-pages"><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para> reported by <citerefentry project="man-pages"><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
<varname>OperatingSystemPrettyName</varname>, <varname>OperatingSystemCPEName</varname>, and
<para><varname>OperatingSystemPrettyName</varname>, <varname>OperatingSystemFancyName</varname>, <varname>HomeURL</varname> expose the <varname>PRETTY_NAME=</varname>, <varname>CPE_NAME=</varname> and
<varname>OperatingSystemCPEName</varname>, and <varname>HomeURL</varname> expose the
<varname>PRETTY_NAME=</varname>, <varname>FANCY_NAME=</varname>, <varname>CPE_NAME=</varname> and
<varname>HOME_URL=</varname> fields from <varname>HOME_URL=</varname> fields from
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
purpose of those properties is to allow remote clients to access this information over D-Bus. Local purpose of those properties is to allow remote clients to access this information over D-Bus. Local
@ -493,7 +487,6 @@ node /org/freedesktop/hostname1 {
<para><varname>ChassisAssetTag</varname>, <varname>OperatingSystemImageID</varname>, <para><varname>ChassisAssetTag</varname>, <varname>OperatingSystemImageID</varname>,
<varname>OperatingSystemImageVersion</varname>, <varname>HardwareSKU</varname>, and <varname>OperatingSystemImageVersion</varname>, <varname>HardwareSKU</varname>, and
<varname>HardwareVersion</varname> were added in version 258.</para> <varname>HardwareVersion</varname> were added in version 258.</para>
<para><varname>OperatingSystemFancyName</varname> was added in version 260.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>

View File

@ -191,34 +191,9 @@
<listitem><para>A pretty operating system name in a format suitable for presentation to the <listitem><para>A pretty operating system name in a format suitable for presentation to the
user. May or may not contain a release code name or OS version of some kind, as suitable. If not user. May or may not contain a release code name or OS version of some kind, as suitable. If not
set, a default of <literal>PRETTY_NAME="Linux"</literal> may be used.</para> set, a default of <literal>PRETTY_NAME="Linux"</literal> may be used</para>
<para>Example: <literal>PRETTY_NAME="Fedora 17 (Beefy Miracle)"</literal></para></listitem> <para>Example: <literal>PRETTY_NAME="Fedora 17 (Beefy Miracle)"</literal>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>FANCY_NAME=</varname></term>
<listitem><para>Similar to <varname>PRETTY_NAME=</varname>, but may contain ANSI sequences and
fancy UTF-8 characters such as emojis. If defined this shall preferably used when displaying the OS
name on modern terminal emulators. If the terminal emulator does not support emojis,
<varname>PRETTY_NAME=</varname> shall be shown instead, possibly with
<varname>ANSI_COLOR=</varname> coloring. Use <literal>\033</literal> to encode the ESC
character and <literal>\\</literal> to encode the backslash character.</para>
<!-- NB: the code actually does a full blown C style unescaping, but we are not going to mention
this here: people may add ANSI sequences, but maybe not the full expressivity of ASCII control
characters. -->
<para>Unlike <varname>PRETTY_NAME=</varname> this field must not contain information that is
present in other fields, in particular the version (already specified in
<varname>VERSION=</varname>) or the codename (already specified in
<varname>VERSION_CODENAME=</varname>).</para>
<para>Example:
<literal>FANCY_NAME="🍅 \033[31mTomato\033[0;1mOS\033[0m"</literal></para>
<xi:include href="version-info.xml" xpointer="v260"/></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -2911,7 +2911,7 @@ endif
alias_target('gensources', generated_sources) alias_target('gensources', generated_sources)
clang_tidy = find_program('clang-tidy', required : false) clang_tidy = find_program('clang-tidy', required : false)
if meson.version().version_compare('>=1.4.0') if meson.version().version_compare('>=1.10.0')
uniq = {} uniq = {}
foreach source : sources foreach source : sources
@ -2921,11 +2921,7 @@ if meson.version().version_compare('>=1.4.0')
uniq += {source.full_path(): source} uniq += {source.full_path(): source}
endforeach endforeach
# TODO: Use uniq.values() when we can rely on meson 1.10.0. sources = uniq.values()
sources = []
foreach path, file : uniq
sources += [file]
endforeach
foreach source : sources foreach source : sources
if systemd_headers.contains(source) if systemd_headers.contains(source)

View File

@ -102,7 +102,6 @@
#include "umask-util.h" #include "umask-util.h"
#include "unit-name.h" #include "unit-name.h"
#include "user-util.h" #include "user-util.h"
#include "utf8.h"
#include "version.h" #include "version.h"
#include "virt.h" #include "virt.h"
#include "watchdog.h" #include "watchdog.h"
@ -1390,16 +1389,14 @@ static int enforce_syscall_archs(Set *archs) {
} }
static int os_release_status(void) { static int os_release_status(void) {
_cleanup_free_ char *pretty_name = NULL, *fancy_name = NULL, _cleanup_free_ char *pretty_name = NULL, *name = NULL, *version = NULL,
*name = NULL, *version = NULL, *ansi_color = NULL, *support_end = NULL, *codename = NULL; *ansi_color = NULL, *support_end = NULL;
int r; int r;
r = parse_os_release(NULL, r = parse_os_release(NULL,
"PRETTY_NAME", &pretty_name, "PRETTY_NAME", &pretty_name,
"FANCY_NAME", &fancy_name,
"NAME", &name, "NAME", &name,
"VERSION", &version, "VERSION", &version,
"VERSION_CODENAME", &codename,
"ANSI_COLOR", &ansi_color, "ANSI_COLOR", &ansi_color,
"SUPPORT_END", &support_end); "SUPPORT_END", &support_end);
if (r < 0) if (r < 0)
@ -1407,59 +1404,22 @@ static int os_release_status(void) {
"Failed to read os-release file, ignoring: %m"); "Failed to read os-release file, ignoring: %m");
const char *label = os_release_pretty_name(pretty_name, name); const char *label = os_release_pretty_name(pretty_name, name);
if (show_status_on(arg_show_status)) {
const char *color = empty_to_null(ansi_color) ?: "1"; const char *color = empty_to_null(ansi_color) ?: "1";
/* The fancy name may contain emoji characters and ANSI sequences. Don't use it if our locale if (show_status_on(arg_show_status)) {
* doesn't allow that, or ANSI sequences are off, or if it is empty. */
if (!isempty(fancy_name)) {
_cleanup_free_ char *unescaped = NULL;
/* Undo one level of C-style unescaping for this one */
ssize_t l = cunescape(fancy_name, /* flags= */ 0, &unescaped);
if (l < 0) {
log_debug_errno(l, "Failed to unescape FANCY_NAME=, ignoring: %m");
fancy_name = mfree(fancy_name);
} else {
free_and_replace(fancy_name, unescaped);
/* FANCY_NAME= does not contain version/codename info (unlike PRETTY_NAME=),
* but in this context it makes sense to show them if defined, hence append
* them here. */
if (version && !strextend(&fancy_name, " ", version))
return log_oom();
if (codename && !strextend(&fancy_name, " (", codename, ")"))
return log_oom();
}
}
if (isempty(fancy_name) ||
(!emoji_enabled() && !ascii_is_valid(fancy_name)) ||
!log_get_show_color())
fancy_name = mfree(fancy_name);
if (!fancy_name && log_get_show_color()) {
fancy_name = strjoin("\x1B[", color, "m", label);
if (!fancy_name)
return log_oom();
}
if (in_initrd()) { if (in_initrd()) {
if (log_get_show_color()) if (log_get_show_color())
status_printf(NULL, 0, status_printf(NULL, 0,
ANSI_HIGHLIGHT "Booting initrd of " ANSI_NORMAL "%s" ANSI_NORMAL ANSI_HIGHLIGHT "." ANSI_NORMAL, ANSI_HIGHLIGHT "Booting initrd of " ANSI_NORMAL "\x1B[%sm%s" ANSI_NORMAL ANSI_HIGHLIGHT "." ANSI_NORMAL,
fancy_name); color, label);
else else
status_printf(NULL, 0, status_printf(NULL, 0,
"Booting initrd of %s...", label); "Booting initrd of %s...", label);
} else { } else {
if (log_get_show_color()) if (log_get_show_color())
status_printf(NULL, 0, status_printf(NULL, 0,
"\n" ANSI_HIGHLIGHT "Welcome to " ANSI_NORMAL "%s" ANSI_NORMAL ANSI_HIGHLIGHT "!" ANSI_NORMAL "\n", "\n" ANSI_HIGHLIGHT "Welcome to " ANSI_NORMAL "\x1B[%sm%s" ANSI_NORMAL ANSI_HIGHLIGHT "!" ANSI_NORMAL "\n",
fancy_name); color, label);
else else
status_printf(NULL, 0, status_printf(NULL, 0,
"\nWelcome to %s!\n", "\nWelcome to %s!\n",

View File

@ -29,7 +29,6 @@
#include "runtime-scope.h" #include "runtime-scope.h"
#include "string-util.h" #include "string-util.h"
#include "time-util.h" #include "time-util.h"
#include "utf8.h"
#include "verbs.h" #include "verbs.h"
static bool arg_ask_password = true; static bool arg_ask_password = true;
@ -52,7 +51,6 @@ typedef struct StatusInfo {
const char *kernel_name; const char *kernel_name;
const char *kernel_release; const char *kernel_release;
const char *os_pretty_name; const char *os_pretty_name;
const char *os_fancy_name;
const char *os_cpe_name; const char *os_cpe_name;
usec_t os_support_end; usec_t os_support_end;
const char *os_image_id; const char *os_image_id;
@ -236,14 +234,7 @@ static int print_status_info(StatusInfo *i) {
return table_log_add_error(r); return table_log_add_error(r);
} }
if (!isempty(i->os_fancy_name) && (emoji_enabled() || ascii_is_valid(i->os_fancy_name)) && colors_enabled()) { if (!isempty(i->os_pretty_name)) {
r = table_add_many(table,
TABLE_FIELD, "Operating System",
TABLE_STRING_WITH_ANSI, i->os_fancy_name,
TABLE_SET_URL, i->home_url);
if (r < 0)
return table_log_add_error(r);
} else if (!isempty(i->os_pretty_name)) {
r = table_add_many(table, r = table_add_many(table,
TABLE_FIELD, "Operating System", TABLE_FIELD, "Operating System",
TABLE_STRING, i->os_pretty_name, TABLE_STRING, i->os_pretty_name,
@ -434,7 +425,6 @@ static int show_all_names(sd_bus *bus) {
{ "KernelName", "s", NULL, offsetof(StatusInfo, kernel_name) }, { "KernelName", "s", NULL, offsetof(StatusInfo, kernel_name) },
{ "KernelRelease", "s", NULL, offsetof(StatusInfo, kernel_release) }, { "KernelRelease", "s", NULL, offsetof(StatusInfo, kernel_release) },
{ "OperatingSystemPrettyName", "s", NULL, offsetof(StatusInfo, os_pretty_name) }, { "OperatingSystemPrettyName", "s", NULL, offsetof(StatusInfo, os_pretty_name) },
{ "OperatingSystemFancyName", "s", NULL, offsetof(StatusInfo, os_fancy_name) },
{ "OperatingSystemCPEName", "s", NULL, offsetof(StatusInfo, os_cpe_name) }, { "OperatingSystemCPEName", "s", NULL, offsetof(StatusInfo, os_cpe_name) },
{ "OperatingSystemSupportEnd", "t", NULL, offsetof(StatusInfo, os_support_end) }, { "OperatingSystemSupportEnd", "t", NULL, offsetof(StatusInfo, os_support_end) },
{ "OperatingSystemImageID", "s", NULL, offsetof(StatusInfo, os_image_id) }, { "OperatingSystemImageID", "s", NULL, offsetof(StatusInfo, os_image_id) },

View File

@ -22,7 +22,6 @@
#include "device-private.h" #include "device-private.h"
#include "env-file.h" #include "env-file.h"
#include "env-util.h" #include "env-util.h"
#include "escape.h"
#include "extract-word.h" #include "extract-word.h"
#include "fileio.h" #include "fileio.h"
#include "hashmap.h" #include "hashmap.h"
@ -76,7 +75,6 @@ typedef enum {
PROP_OS_SUPPORT_END, PROP_OS_SUPPORT_END,
PROP_OS_IMAGE_ID, PROP_OS_IMAGE_ID,
PROP_OS_IMAGE_VERSION, PROP_OS_IMAGE_VERSION,
PROP_OS_FANCY_NAME,
_PROP_MAX, _PROP_MAX,
_PROP_INVALID = -EINVAL, _PROP_INVALID = -EINVAL,
} HostProperty; } HostProperty;
@ -194,7 +192,7 @@ static void context_read_machine_info(Context *c) {
} }
static void context_read_os_release(Context *c) { static void context_read_os_release(Context *c) {
_cleanup_free_ char *os_name = NULL, *os_pretty_name = NULL, *os_fancy_name = NULL, *os_ansi_color = NULL; _cleanup_free_ char *os_name = NULL, *os_pretty_name = NULL;
struct stat current_stat = {}; struct stat current_stat = {};
int r; int r;
@ -211,13 +209,10 @@ static void context_read_os_release(Context *c) {
(UINT64_C(1) << PROP_OS_HOME_URL) | (UINT64_C(1) << PROP_OS_HOME_URL) |
(UINT64_C(1) << PROP_OS_SUPPORT_END) | (UINT64_C(1) << PROP_OS_SUPPORT_END) |
(UINT64_C(1) << PROP_OS_IMAGE_ID) | (UINT64_C(1) << PROP_OS_IMAGE_ID) |
(UINT64_C(1) << PROP_OS_IMAGE_VERSION) | (UINT64_C(1) << PROP_OS_IMAGE_VERSION));
(UINT64_C(1) << PROP_OS_FANCY_NAME));
r = parse_os_release(NULL, r = parse_os_release(NULL,
"PRETTY_NAME", &os_pretty_name, "PRETTY_NAME", &os_pretty_name,
"FANCY_NAME", &os_fancy_name,
"ANSI_COLOR", &os_ansi_color,
"NAME", &os_name, "NAME", &os_name,
"CPE_NAME", &c->data[PROP_OS_CPE_NAME], "CPE_NAME", &c->data[PROP_OS_CPE_NAME],
"HOME_URL", &c->data[PROP_OS_HOME_URL], "HOME_URL", &c->data[PROP_OS_HOME_URL],
@ -230,31 +225,6 @@ static void context_read_os_release(Context *c) {
if (free_and_strdup(&c->data[PROP_OS_PRETTY_NAME], os_release_pretty_name(os_pretty_name, os_name)) < 0) if (free_and_strdup(&c->data[PROP_OS_PRETTY_NAME], os_release_pretty_name(os_pretty_name, os_name)) < 0)
log_oom(); log_oom();
if (!isempty(os_fancy_name)) {
_cleanup_free_ char *unescaped = NULL;
/* We undo one level of C escapes on this */
ssize_t l = cunescape(os_fancy_name, /* flags= */ 0, &unescaped);
if (l < 0) {
log_warning_errno(l, "Failed to unescape fancy OS name, ignoring: %m");
os_fancy_name = mfree(os_fancy_name);
} else
free_and_replace(os_fancy_name, unescaped);
}
if (isempty(os_fancy_name)) {
free(os_fancy_name); /* free if empty string */
if (isempty(os_ansi_color))
os_fancy_name = strdup(c->data[PROP_OS_PRETTY_NAME]);
else
os_fancy_name = strjoin("\x1B[", os_ansi_color, "m", c->data[PROP_OS_PRETTY_NAME]);
if (!os_fancy_name)
log_oom();
}
free_and_replace(c->data[PROP_OS_FANCY_NAME], os_fancy_name);
c->etc_os_release_stat = current_stat; c->etc_os_release_stat = current_stat;
} }
@ -1735,7 +1705,6 @@ static int build_describe_response(Context *c, bool privileged, sd_json_variant
SD_JSON_BUILD_PAIR_STRING("KernelRelease", u.release), SD_JSON_BUILD_PAIR_STRING("KernelRelease", u.release),
SD_JSON_BUILD_PAIR_STRING("KernelVersion", u.version), SD_JSON_BUILD_PAIR_STRING("KernelVersion", u.version),
SD_JSON_BUILD_PAIR_STRING("OperatingSystemPrettyName", c->data[PROP_OS_PRETTY_NAME]), SD_JSON_BUILD_PAIR_STRING("OperatingSystemPrettyName", c->data[PROP_OS_PRETTY_NAME]),
SD_JSON_BUILD_PAIR_STRING("OperatingSystemFancyName", c->data[PROP_OS_FANCY_NAME]),
SD_JSON_BUILD_PAIR_STRING("OperatingSystemCPEName", c->data[PROP_OS_CPE_NAME]), SD_JSON_BUILD_PAIR_STRING("OperatingSystemCPEName", c->data[PROP_OS_CPE_NAME]),
SD_JSON_BUILD_PAIR_STRING("OperatingSystemHomeURL", c->data[PROP_OS_HOME_URL]), SD_JSON_BUILD_PAIR_STRING("OperatingSystemHomeURL", c->data[PROP_OS_HOME_URL]),
JSON_BUILD_PAIR_FINITE_USEC("OperatingSystemSupportEnd", eol), JSON_BUILD_PAIR_FINITE_USEC("OperatingSystemSupportEnd", eol),
@ -1812,7 +1781,6 @@ static const sd_bus_vtable hostname_vtable[] = {
SD_BUS_PROPERTY("KernelRelease", "s", property_get_uname_field, offsetof(struct utsname, release), SD_BUS_VTABLE_ABSOLUTE_OFFSET|SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("KernelRelease", "s", property_get_uname_field, offsetof(struct utsname, release), SD_BUS_VTABLE_ABSOLUTE_OFFSET|SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("KernelVersion", "s", property_get_uname_field, offsetof(struct utsname, version), SD_BUS_VTABLE_ABSOLUTE_OFFSET|SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("KernelVersion", "s", property_get_uname_field, offsetof(struct utsname, version), SD_BUS_VTABLE_ABSOLUTE_OFFSET|SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OperatingSystemPrettyName", "s", property_get_os_release_field, offsetof(Context, data[PROP_OS_PRETTY_NAME]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("OperatingSystemPrettyName", "s", property_get_os_release_field, offsetof(Context, data[PROP_OS_PRETTY_NAME]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OperatingSystemFancyName", "s", property_get_os_release_field, offsetof(Context, data[PROP_OS_FANCY_NAME]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OperatingSystemCPEName", "s", property_get_os_release_field, offsetof(Context, data[PROP_OS_CPE_NAME]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("OperatingSystemCPEName", "s", property_get_os_release_field, offsetof(Context, data[PROP_OS_CPE_NAME]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OperatingSystemSupportEnd", "t", property_get_os_support_end, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("OperatingSystemSupportEnd", "t", property_get_os_support_end, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HomeURL", "s", property_get_os_release_field, offsetof(Context, data[PROP_OS_HOME_URL]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("HomeURL", "s", property_get_os_release_field, offsetof(Context, data[PROP_OS_HOME_URL]), SD_BUS_VTABLE_PROPERTY_CONST),

View File

@ -283,7 +283,6 @@ static size_t table_data_size(TableDataType type, const void *data) {
return 0; return 0;
case TABLE_STRING: case TABLE_STRING:
case TABLE_STRING_WITH_ANSI:
case TABLE_PATH: case TABLE_PATH:
case TABLE_PATH_BASENAME: case TABLE_PATH_BASENAME:
case TABLE_FIELD: case TABLE_FIELD:
@ -530,7 +529,7 @@ int table_add_cell_stringf_full(Table *t, TableCell **ret_cell, TableDataType dt
int r; int r;
assert(t); assert(t);
assert(IN_SET(dt, TABLE_STRING, TABLE_STRING_WITH_ANSI, TABLE_PATH, TABLE_PATH_BASENAME, TABLE_FIELD, TABLE_HEADER, TABLE_VERSION)); assert(IN_SET(dt, TABLE_STRING, TABLE_PATH, TABLE_PATH_BASENAME, TABLE_FIELD, TABLE_HEADER, TABLE_VERSION));
va_start(ap, format); va_start(ap, format);
r = vasprintf(&buffer, format, ap); r = vasprintf(&buffer, format, ap);
@ -934,7 +933,6 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
break; break;
case TABLE_STRING: case TABLE_STRING:
case TABLE_STRING_WITH_ANSI:
case TABLE_PATH: case TABLE_PATH:
case TABLE_PATH_BASENAME: case TABLE_PATH_BASENAME:
case TABLE_FIELD: case TABLE_FIELD:
@ -1395,7 +1393,6 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
switch (a->type) { switch (a->type) {
case TABLE_STRING: case TABLE_STRING:
case TABLE_STRING_WITH_ANSI:
case TABLE_FIELD: case TABLE_FIELD:
case TABLE_HEADER: case TABLE_HEADER:
return strcmp(a->string, b->string); return strcmp(a->string, b->string);
@ -1577,13 +1574,7 @@ static char* format_strv_width(char **strv, size_t column_width) {
return buf; return buf;
} }
static const char *table_data_format( static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercasing, size_t column_width, bool *have_soft) {
Table *t,
TableData *d,
bool avoid_uppercasing,
size_t column_width,
bool *have_soft) {
assert(d); assert(d);
if (d->formatted && if (d->formatted &&
@ -1596,7 +1587,6 @@ static const char *table_data_format(
return table_ersatz_string(t); return table_ersatz_string(t);
case TABLE_STRING: case TABLE_STRING:
case TABLE_STRING_WITH_ANSI:
case TABLE_PATH: case TABLE_PATH:
case TABLE_PATH_BASENAME: case TABLE_PATH_BASENAME:
case TABLE_FIELD: case TABLE_FIELD:
@ -2078,42 +2068,6 @@ static const char *table_data_format(
return d->formatted; return d->formatted;
} }
static const char *table_data_format_strip_ansi(
Table *t,
TableData *d,
bool avoid_uppercasing,
size_t column_width,
bool *have_soft,
char **ret_buffer) {
/* Just like table_data_format() but strips ANSI sequences for ANSI fields. */
assert(ret_buffer);
const char *c;
c = table_data_format(t, d, avoid_uppercasing, column_width, have_soft);
if (!c)
return NULL;
if (d->type != TABLE_STRING_WITH_ANSI) {
/* Shortcut: we do not consider ANSI sequences for all other column types, hence return the
* original string as-is */
*ret_buffer = NULL;
return c;
}
_cleanup_free_ char *s = strdup(c);
if (!s)
return NULL;
if (!strip_tab_ansi(&s, /* isz= */ NULL, /* highlight= */ NULL))
return NULL;
*ret_buffer = TAKE_PTR(s);
return *ret_buffer;
}
static int console_width_height( static int console_width_height(
const char *s, const char *s,
size_t *ret_width, size_t *ret_width,
@ -2168,20 +2122,14 @@ static int table_data_requested_width_height(
size_t *ret_height, size_t *ret_height,
bool *have_soft) { bool *have_soft) {
_cleanup_free_ char *truncated = NULL, *buffer = NULL; _cleanup_free_ char *truncated = NULL;
bool truncation_applied = false; bool truncation_applied = false;
size_t width, height; size_t width, height;
bool soft = false;
const char *t; const char *t;
int r; int r;
bool soft = false;
t = table_data_format_strip_ansi( t = table_data_format(table, d, false, available_width, &soft);
table,
d,
/* avoid_uppercasing= */ false,
available_width,
&soft,
&buffer);
if (!t) if (!t)
return -ENOMEM; return -ENOMEM;
@ -2404,7 +2352,7 @@ int table_print(Table *t, FILE *f) {
if (r < 0) if (r < 0)
return r; return r;
if (r > 0) { /* Truncated because too many lines? */ if (r > 0) { /* Truncated because too many lines? */
_cleanup_free_ char *last = NULL, *buffer = NULL; _cleanup_free_ char *last = NULL;
const char *field; const char *field;
/* If we are going to show only the first few lines of a cell that has /* If we are going to show only the first few lines of a cell that has
@ -2412,13 +2360,9 @@ int table_print(Table *t, FILE *f) {
* ellipsis. Hence, let's figure out the last line, and account for its * ellipsis. Hence, let's figure out the last line, and account for its
* length plus ellipsis. */ * length plus ellipsis. */
field = table_data_format_strip_ansi( field = table_data_format(t, d, false,
t,
d,
/* avoid_uppercasing= */ false,
width ? width[j] : SIZE_MAX, width ? width[j] : SIZE_MAX,
&any_soft, &any_soft);
&buffer);
if (!field) if (!field)
return -ENOMEM; return -ENOMEM;
@ -2606,7 +2550,7 @@ int table_print(Table *t, FILE *f) {
more_sublines = false; more_sublines = false;
for (size_t j = 0; j < display_columns; j++) { for (size_t j = 0; j < display_columns; j++) {
_cleanup_free_ char *buffer = NULL, *stripped_ansi_buffer = NULL, *extracted = NULL; _cleanup_free_ char *buffer = NULL, *extracted = NULL;
bool lines_truncated = false; bool lines_truncated = false;
const char *field, *color = NULL, *underline = NULL; const char *field, *color = NULL, *underline = NULL;
TableData *d; TableData *d;
@ -2614,21 +2558,7 @@ int table_print(Table *t, FILE *f) {
assert_se(d = row[t->display_map ? t->display_map[j] : j]); assert_se(d = row[t->display_map ? t->display_map[j] : j]);
if (colors_enabled()) field = table_data_format(t, d, false, width[j], NULL);
field = table_data_format(
t,
d,
/* avoid_uppercasing= */ false,
width[j],
/* have_soft= */ NULL);
else
field = table_data_format_strip_ansi(
t,
d,
/* avoid_uppercasing= */ false,
width[j],
/* have_soft= */ NULL,
&stripped_ansi_buffer);
if (!field) if (!field)
return -ENOMEM; return -ENOMEM;
@ -2735,8 +2665,7 @@ int table_print(Table *t, FILE *f) {
fputs(field, f); fputs(field, f);
/* Reset color afterwards if colors was set or the string to output contained ANSI sequences. */ if (color || underline)
if (color || underline || (d->type == TABLE_STRING_WITH_ANSI && colors_enabled()))
fputs(ANSI_NORMAL, f); fputs(ANSI_NORMAL, f);
gap_color = d->rgap_color; gap_color = d->rgap_color;
@ -2991,18 +2920,6 @@ static int table_data_to_json(TableData *d, sd_json_variant **ret) {
SD_JSON_BUILD_UNSIGNED(major(d->devnum)), SD_JSON_BUILD_UNSIGNED(major(d->devnum)),
SD_JSON_BUILD_UNSIGNED(minor(d->devnum)))); SD_JSON_BUILD_UNSIGNED(minor(d->devnum))));
case TABLE_STRING_WITH_ANSI: {
_cleanup_free_ char *s = strdup(d->string);
if (!s)
return -ENOMEM;
/* We strip the ANSI data when outputting to JSON */
if (!strip_tab_ansi(&s, /* isz= */ NULL, /* highlight= */ NULL))
return -ENOMEM;
return sd_json_variant_new_string(ret, s);
}
default: default:
return -EINVAL; return -EINVAL;
} }
@ -3046,7 +2963,7 @@ char* table_mangle_to_json_field_name(const char *str) {
} }
static int table_make_json_field_name(Table *t, TableData *d, char **ret) { static int table_make_json_field_name(Table *t, TableData *d, char **ret) {
_cleanup_free_ char *mangled = NULL, *buffer = NULL; _cleanup_free_ char *mangled = NULL;
const char *n; const char *n;
assert(t); assert(t);
@ -3056,13 +2973,7 @@ static int table_make_json_field_name(Table *t, TableData *d, char **ret) {
if (IN_SET(d->type, TABLE_HEADER, TABLE_FIELD)) if (IN_SET(d->type, TABLE_HEADER, TABLE_FIELD))
n = d->string; n = d->string;
else { else {
n = table_data_format_strip_ansi( n = table_data_format(t, d, /* avoid_uppercasing= */ true, SIZE_MAX, NULL);
t,
d,
/* avoid_uppercasing= */ true,
/* column_width= */ SIZE_MAX,
/* have_soft= */ NULL,
&buffer);
if (!n) if (!n)
return -ENOMEM; return -ENOMEM;
} }

View File

@ -10,7 +10,6 @@
typedef enum TableDataType { typedef enum TableDataType {
TABLE_EMPTY, TABLE_EMPTY,
TABLE_STRING, TABLE_STRING,
TABLE_STRING_WITH_ANSI, /* like the above, but contains ANSI sequences/TABs. They will be stripped when outputing to JSON */
TABLE_HEADER, /* in regular mode: the cells in the first row, that carry the column names */ TABLE_HEADER, /* in regular mode: the cells in the first row, that carry the column names */
TABLE_FIELD, /* in vertical mode: the cells in the first column, that carry the field names */ TABLE_FIELD, /* in vertical mode: the cells in the first column, that carry the field names */
TABLE_STRV, TABLE_STRV,

View File

@ -20,10 +20,7 @@ static SD_VARLINK_DEFINE_METHOD(
SD_VARLINK_DEFINE_OUTPUT(KernelName, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_OUTPUT(KernelName, SD_VARLINK_STRING, 0),
SD_VARLINK_DEFINE_OUTPUT(KernelRelease, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_OUTPUT(KernelRelease, SD_VARLINK_STRING, 0),
SD_VARLINK_DEFINE_OUTPUT(KernelVersion, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_OUTPUT(KernelVersion, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("'Pretty' name of the OS. This is the primary OS identifier that is suitable for presentation to the user. Typically includes a version too, but doesn't have to."),
SD_VARLINK_DEFINE_OUTPUT(OperatingSystemPrettyName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_OUTPUT(OperatingSystemPrettyName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("'Fancy' name of the OS; may contain non-ASCII Unicode chars, as well as basic ANSI sequences. This is similar to 'OperatingSystemPrettyName', but is preferably used on terminals that support ANSI sequences and full Unicode."),
SD_VARLINK_DEFINE_OUTPUT(OperatingSystemFancyName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_OUTPUT(OperatingSystemCPEName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_OUTPUT(OperatingSystemCPEName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_OUTPUT(OperatingSystemHomeURL, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_OUTPUT(OperatingSystemHomeURL, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_OUTPUT(OperatingSystemSupportEnd, SD_VARLINK_INT, SD_VARLINK_NULLABLE), SD_VARLINK_DEFINE_OUTPUT(OperatingSystemSupportEnd, SD_VARLINK_INT, SD_VARLINK_NULLABLE),

View File

@ -4,8 +4,6 @@
#include <unistd.h> #include <unistd.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "ansi-color.h"
#include "env-util.h"
#include "format-table.h" #include "format-table.h"
#include "json-util.h" #include "json-util.h"
#include "terminal-util.h" #include "terminal-util.h"
@ -837,80 +835,9 @@ TEST(table_bps) {
"2500000000 2.3G 2.5Gbps\n"); "2500000000 2.3G 2.5Gbps\n");
} }
TEST(table_ansi) {
_cleanup_(table_unrefp) Table *table = NULL;
ASSERT_NOT_NULL((table = table_new("foo", "bar", "baz", "kkk")));
ASSERT_OK(table_add_many(table,
TABLE_STRING, "hallo",
TABLE_STRING_WITH_ANSI, "knuerz" ANSI_HIGHLIGHT_RED "red" ANSI_HIGHLIGHT_GREEN "green",
TABLE_STRING_WITH_ANSI, "noansi",
TABLE_STRING_WITH_ANSI, ANSI_GREY "thisisgrey"));
unsigned saved_columns = columns();
bool saved_color = colors_enabled();
_cleanup_free_ char *saved_term = NULL;
const char *e = getenv("TERM");
if (e)
ASSERT_NOT_NULL((saved_term = strdup(e)));
ASSERT_OK_ERRNO(setenv("COLUMNS", "200", /* overwrite= */ true));
ASSERT_OK_ERRNO(setenv("SYSTEMD_COLORS", "1", /* overwrite= */ true));
ASSERT_OK_ERRNO(setenv("TERM", FALLBACK_TERM, /* overwrite= */ true));
reset_terminal_feature_caches();
_cleanup_free_ char *formatted = NULL;
ASSERT_OK(table_format(table, &formatted));
ASSERT_STREQ(formatted,
ANSI_ADD_UNDERLINE "FOO " ANSI_NORMAL
ANSI_ADD_UNDERLINE " " ANSI_NORMAL
ANSI_ADD_UNDERLINE "BAR " ANSI_NORMAL
ANSI_ADD_UNDERLINE " " ANSI_NORMAL
ANSI_ADD_UNDERLINE "BAZ " ANSI_NORMAL
ANSI_ADD_UNDERLINE " " ANSI_NORMAL
ANSI_ADD_UNDERLINE "KKK " ANSI_NORMAL "\n"
"hallo knuerz" ANSI_HIGHLIGHT_RED "red" ANSI_HIGHLIGHT_GREEN "green" ANSI_NORMAL
" noansi" ANSI_NORMAL
" " ANSI_GREY "thisisgrey" ANSI_NORMAL "\n");
/* Validate that color is correctly stripped */
ASSERT_OK_ERRNO(setenv("SYSTEMD_COLORS", "0", /* overwrite= */ true));
reset_terminal_feature_caches();
formatted = mfree(formatted);
ASSERT_OK(table_format(table, &formatted));
ASSERT_STREQ(formatted,
"FOO BAR BAZ KKK\n"
"hallo knuerzredgreen noansi thisisgrey\n");
ASSERT_OK(table_print(table, /* f= */ NULL));
_cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL, *jj = NULL;
ASSERT_OK(table_to_json(table, &j));
ASSERT_OK(sd_json_build(&jj,
SD_JSON_BUILD_ARRAY(
SD_JSON_BUILD_OBJECT(
SD_JSON_BUILD_PAIR_STRING("foo", "hallo"),
SD_JSON_BUILD_PAIR_STRING("bar", "knuerzredgreen"),
SD_JSON_BUILD_PAIR_STRING("baz", "noansi"),
SD_JSON_BUILD_PAIR_STRING("kkk", "thisisgrey")))));
ASSERT_TRUE(sd_json_variant_equal(j, jj));
ASSERT_OK(sd_json_variant_dump(j, SD_JSON_FORMAT_COLOR_AUTO|SD_JSON_FORMAT_PRETTY_AUTO, /* f= */ NULL, /* prefix= */ NULL));
ASSERT_OK(setenvf("COLUMNS", /* overwrite= */ true, "%u", saved_columns));
ASSERT_OK(setenvf("SYSTEMD_COLORS", /* overwrite= */ true, "%i", saved_color));
ASSERT_OK(set_unset_env("TERM", saved_term, /* overwrite= */ true));
}
static int intro(void) { static int intro(void) {
ASSERT_OK_ERRNO(setenv("SYSTEMD_COLORS", "0", /* overwrite= */ true)); ASSERT_OK(setenv("SYSTEMD_COLORS", "0", 1));
ASSERT_OK_ERRNO(setenv("COLUMNS", "40", /* overwrite= */ true)); ASSERT_OK(setenv("COLUMNS", "40", 1));
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }