diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c index d8a5537658..4eb4858931 100644 --- a/src/shared/pretty-print.c +++ b/src/shared/pretty-print.c @@ -183,34 +183,20 @@ int terminal_urlify_man(const char *page, const char *section, char **ret) { return terminal_urlify(url, text, ret); } -typedef enum { - LINE_SECTION, - LINE_COMMENT, - LINE_NORMAL, -} LineType; - -static LineType classify_line_type(const char *line, CatFlags flags) { - const char *t = skip_leading_chars(line, WHITESPACE); - - if ((flags & CAT_FORMAT_HAS_SECTIONS) && *t == '[') - return LINE_SECTION; - if (IN_SET(*t, '#', ';', '\0')) - return LINE_COMMENT; - return LINE_NORMAL; -} - static int cat_file(const char *filename, bool newline, CatFlags flags) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *urlified = NULL, *section = NULL, *old_section = NULL; int r; + assert(filename); + f = fopen(filename, "re"); if (!f) - return -errno; + return log_error_errno(errno, "Failed to open \"%s\": %m", filename); r = terminal_urlify_path(filename, NULL, &urlified); if (r < 0) - return r; + return log_error_errno(r, "Failed to urlify path \"%s\": %m", filename); printf("%s%s# %s%s\n", newline ? "\n" : "", @@ -219,7 +205,7 @@ static int cat_file(const char *filename, bool newline, CatFlags flags) { ansi_normal()); fflush(stdout); - for (;;) { + for (bool continued = false;;) { _cleanup_free_ char *line = NULL; r = read_line(f, LONG_LINE_MAX, &line); @@ -228,58 +214,78 @@ static int cat_file(const char *filename, bool newline, CatFlags flags) { if (r == 0) break; - LineType line_type = classify_line_type(line, flags); - if (FLAGS_SET(flags, CAT_TLDR)) { - if (line_type == LINE_SECTION) { - /* The start of a section, let's not print it yet. */ + const char *l = skip_leading_chars(line, WHITESPACE); + + /* comment */ + if (*l != '\0' && strchr(COMMENTS, *l)) { + if (!FLAGS_SET(flags, CAT_TLDR)) + printf("%s%s%s\n", ansi_highlight_grey(), line, ansi_normal()); + continue; + } + + /* empty line */ + if (FLAGS_SET(flags, CAT_TLDR) && (isempty(l) || streq(l, "\\"))) + continue; + + /* section */ + if (FLAGS_SET(flags, CAT_FORMAT_HAS_SECTIONS) && *l == '[' && !continued) { + if (FLAGS_SET(flags, CAT_TLDR)) + /* On TLDR, let's not print it yet. */ free_and_replace(section, line); - continue; - } + else + printf("%s%s%s\n", ansi_highlight_cyan(), line, ansi_normal()); + continue; + } - if (line_type == LINE_COMMENT) - continue; + /* normal line */ - /* Before we print the actual line, print the last section header */ - if (section) { - /* Do not print redundant section headers */ - if (!streq_ptr(section, old_section)) - printf("%s%s%s\n", - ansi_highlight_cyan(), - section, - ansi_normal()); + /* Before we print the line, print the last section header. */ + if (FLAGS_SET(flags, CAT_TLDR) && section) { + /* Do not print redundant section headers */ + if (!streq_ptr(section, old_section)) + printf("%s%s%s\n", ansi_highlight_cyan(), section, ansi_normal()); - free_and_replace(old_section, section); - } + free_and_replace(old_section, section); + } + + /* Check if the line ends with a backslash. */ + bool escaped = false; + char *e; + for (e = line; *e != '\0'; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + } + + /* Highlight the trailing backslash. */ + if (escaped) { + assert(e > line); + *(e-1) = '\0'; + + if (!strextend(&line, ansi_highlight_red(), "\\", ansi_normal())) + return log_oom(); } /* Highlight the left side (directive) of a Foo=bar assignment */ - if (FLAGS_SET(flags, CAT_FORMAT_HAS_SECTIONS) && line_type == LINE_NORMAL) { + if (FLAGS_SET(flags, CAT_FORMAT_HAS_SECTIONS) && !continued) { const char *p = strchr(line, '='); if (p) { - _cleanup_free_ char *highlighted = NULL, *directive = NULL; + _cleanup_free_ char *directive = NULL; directive = strndup(line, p - line); if (!directive) return log_oom(); - highlighted = strjoin(ansi_highlight_green(), - directive, - "=", - ansi_normal(), - p + 1); - if (!highlighted) - return log_oom(); - - free_and_replace(line, highlighted); + printf("%s%s=%s%s\n", ansi_highlight_green(), directive, ansi_normal(), p + 1); + continued = escaped; + continue; } } - printf("%s%s%s\n", - line_type == LINE_SECTION ? ansi_highlight_cyan() : - line_type == LINE_COMMENT ? ansi_highlight_grey() : - "", - line, - line_type != LINE_NORMAL ? ansi_normal() : ""); + /* Otherwise, print the line as is. */ + printf("%s\n", line); + continued = escaped; } return 0; diff --git a/test/units/TEST-65-ANALYZE.sh b/test/units/TEST-65-ANALYZE.sh index ac39c42da4..ac4b220ed9 100755 --- a/test/units/TEST-65-ANALYZE.sh +++ b/test/units/TEST-65-ANALYZE.sh @@ -202,6 +202,105 @@ systemd-analyze cat-config --tldr /etc/systemd/system.conf >/dev/null systemd-analyze cat-config --tldr systemd/system.conf systemd/journald.conf >/dev/null systemd-analyze cat-config --tldr systemd/system.conf foo/bar systemd/journald.conf >/dev/null systemd-analyze cat-config --tldr foo/bar +mkdir -p /run/test-analyze-cat-config/main.conf.d +cat >/run/test-analyze-cat-config/main.conf </run/test-analyze-cat-config/main.conf.d/override.conf <