mirror of
https://github.com/systemd/systemd.git
synced 2025-01-09 01:18:19 +03:00
journalctl: strip TABs and ANSI color sequences from log messages when displaying them
This commit is contained in:
parent
2d0b0528ac
commit
e8bc0ea2b1
1
.gitignore
vendored
1
.gitignore
vendored
@ -103,6 +103,7 @@
|
||||
/test-replace-var
|
||||
/test-sched-prio
|
||||
/test-sleep
|
||||
/test-strip-tab-ansi
|
||||
/test-strv
|
||||
/test-udev
|
||||
/test-unit-file
|
||||
|
12
Makefile.am
12
Makefile.am
@ -1232,7 +1232,8 @@ noinst_PROGRAMS += \
|
||||
test-sleep \
|
||||
test-replace-var \
|
||||
test-sched-prio \
|
||||
test-calendarspec
|
||||
test-calendarspec \
|
||||
test-strip-tab-ansi
|
||||
|
||||
TESTS += \
|
||||
test-job-type \
|
||||
@ -1244,7 +1245,8 @@ TESTS += \
|
||||
test-sleep \
|
||||
test-replace-var \
|
||||
test-sched-prio \
|
||||
test-calendarspec
|
||||
test-calendarspec \
|
||||
test-strip-tab-ansi
|
||||
|
||||
EXTRA_DIST += \
|
||||
test/sched_idle_bad.service \
|
||||
@ -1341,6 +1343,12 @@ test_calendarspec_SOURCES = \
|
||||
test_calendarspec_LDADD = \
|
||||
libsystemd-shared.la
|
||||
|
||||
test_strip_tab_ansi_SOURCES = \
|
||||
src/test/test-strip-tab-ansi.c
|
||||
|
||||
test_strip_tab_ansi_LDADD = \
|
||||
libsystemd-shared.la
|
||||
|
||||
test_daemon_SOURCES = \
|
||||
src/test/test-daemon.c
|
||||
|
||||
|
@ -179,6 +179,9 @@ static int output_short(
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
if (!(flags & OUTPUT_SHOW_ALL))
|
||||
strip_tab_ansi(&message, &message_len);
|
||||
|
||||
if (priority_len == 1 && *priority >= '0' && *priority <= '7')
|
||||
p = *priority - '0';
|
||||
|
||||
|
@ -5666,3 +5666,86 @@ oom:
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
||||
const char *i, *begin;
|
||||
enum {
|
||||
STATE_OTHER,
|
||||
STATE_ESCAPE,
|
||||
STATE_BRACKET
|
||||
} state = STATE_OTHER;
|
||||
char *obuf = NULL;
|
||||
size_t osz = 0, isz;
|
||||
FILE *f;
|
||||
|
||||
assert(ibuf);
|
||||
assert(*ibuf);
|
||||
|
||||
/* Strips ANSI color and replaces TABs by 8 spaces */
|
||||
|
||||
isz = _isz ? *_isz : strlen(*ibuf);
|
||||
|
||||
f = open_memstream(&obuf, &osz);
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
for (i = *ibuf; i < *ibuf + isz + 1; i++) {
|
||||
|
||||
switch (state) {
|
||||
|
||||
case STATE_OTHER:
|
||||
if (i >= *ibuf + isz) /* EOT */
|
||||
break;
|
||||
else if (*i == '\x1B')
|
||||
state = STATE_ESCAPE;
|
||||
else if (*i == '\t')
|
||||
fputs(" ", f);
|
||||
else
|
||||
fputc(*i, f);
|
||||
break;
|
||||
|
||||
case STATE_ESCAPE:
|
||||
if (i >= *ibuf + isz) { /* EOT */
|
||||
fputc('\x1B', f);
|
||||
break;
|
||||
} else if (*i == '[') {
|
||||
state = STATE_BRACKET;
|
||||
begin = i + 1;
|
||||
} else {
|
||||
fputc('\x1B', f);
|
||||
fputc(*i, f);
|
||||
state = STATE_OTHER;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case STATE_BRACKET:
|
||||
|
||||
if (i >= *ibuf + isz || /* EOT */
|
||||
(!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
|
||||
fputc('\x1B', f);
|
||||
fputc('[', f);
|
||||
state = STATE_OTHER;
|
||||
i = begin-1;
|
||||
} else if (*i == 'm')
|
||||
state = STATE_OTHER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(f)) {
|
||||
fclose(f);
|
||||
free(obuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
free(*ibuf);
|
||||
*ibuf = obuf;
|
||||
|
||||
if (_isz)
|
||||
*_isz = osz;
|
||||
|
||||
return obuf;
|
||||
}
|
||||
|
@ -559,3 +559,5 @@ typedef enum DrawSpecialChar {
|
||||
const char *draw_special_char(DrawSpecialChar ch);
|
||||
|
||||
char *strreplace(const char *text, const char *old_string, const char *new_string);
|
||||
|
||||
char *strip_tab_ansi(char **p, size_t *l);
|
||||
|
52
src/test/test-strip-tab-ansi.c
Normal file
52
src/test/test-strip-tab-ansi.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2012 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char *p;
|
||||
|
||||
assert_se(p = strdup("\tFoobar\tbar\twaldo\t"));
|
||||
assert_se(strip_tab_ansi(&p, NULL));
|
||||
fprintf(stdout, "<%s>\n", p);
|
||||
assert_se(streq(p, " Foobar bar waldo "));
|
||||
free(p);
|
||||
|
||||
assert_se(p = strdup(ANSI_HIGHLIGHT_ON "Hello" ANSI_HIGHLIGHT_OFF ANSI_HIGHLIGHT_RED_ON " world!" ANSI_HIGHLIGHT_OFF));
|
||||
assert_se(strip_tab_ansi(&p, NULL));
|
||||
fprintf(stdout, "<%s>\n", p);
|
||||
assert_se(streq(p, "Hello world!"));
|
||||
free(p);
|
||||
|
||||
assert_se(p = strdup("\x1B[\x1B[\t\x1B[" ANSI_HIGHLIGHT_ON "\x1B[" "Hello" ANSI_HIGHLIGHT_OFF ANSI_HIGHLIGHT_RED_ON " world!" ANSI_HIGHLIGHT_OFF));
|
||||
assert_se(strip_tab_ansi(&p, NULL));
|
||||
assert_se(streq(p, "\x1B[\x1B[ \x1B[\x1B[Hello world!"));
|
||||
free(p);
|
||||
|
||||
assert_se(p = strdup("\x1B[waldo"));
|
||||
assert_se(strip_tab_ansi(&p, NULL));
|
||||
assert_se(streq(p, "\x1B[waldo"));
|
||||
free(p);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user