diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-05-05 12:53:53 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-05-05 13:59:23 +0200 |
commit | fc96e5c0536ae6d9d689a373b696f4fd3659f7d3 (patch) | |
tree | dcd2abb7deafeeaff8efd704f4574737e47a2455 /src/basic/escape.c | |
parent | basic/escape: flagsify xescape_full() (diff) | |
download | systemd-fc96e5c0536ae6d9d689a373b696f4fd3659f7d3.tar.xz systemd-fc96e5c0536ae6d9d689a373b696f4fd3659f7d3.zip |
basic/escape: allow truncation mode where "…" is always appended
So far we would append "…" or "..." when the string was wider than the specified
output width. But let's add a mode where the caller knows that the string being
passed is already truncated.
The condition for jumping back in utf8_escape_non_printable_full() was
off-by-one. But we only jumped to that label after doing a check with a
stronger condition, so I think it didn't matter. Now it matters because we'd
output the forced ellipsis one column too early.
Diffstat (limited to 'src/basic/escape.c')
-rw-r--r-- | src/basic/escape.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/basic/escape.c b/src/basic/escape.c index f579f15d87..2a3a0e31a1 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -368,7 +368,8 @@ char* xescape_full(const char *s, const char *bad, size_t console_width, XEscape * reversed with cunescape(). If XESCAPE_8_BIT is specified, characters >= 127 are let through * unchanged. This corresponds to non-ASCII printable characters in pre-unicode encodings. * - * If console_width is reached, output is truncated and "..." is appended. */ + * If console_width is reached, or XESCAPE_FORCE_ELLIPSIS is set, output is truncated and "..." is + * appended. */ if (console_width == 0) return strdup(""); @@ -380,10 +381,15 @@ char* xescape_full(const char *s, const char *bad, size_t console_width, XEscape memset(ans, '_', MIN(strlen(s), console_width) * 4); ans[MIN(strlen(s), console_width) * 4] = 0; + bool force_ellipsis = FLAGS_SET(flags, XESCAPE_FORCE_ELLIPSIS); + for (f = s, t = prev = prev2 = ans; ; f++) { char *tmp_t = t; if (!*f) { + if (force_ellipsis) + break; + *t = 0; return ans; } @@ -391,7 +397,7 @@ char* xescape_full(const char *s, const char *bad, size_t console_width, XEscape if ((unsigned char) *f < ' ' || (!FLAGS_SET(flags, XESCAPE_8_BIT) && (unsigned char) *f >= 127) || *f == '\\' || strchr(bad, *f)) { - if ((size_t) (t - ans) + 4 > console_width) + if ((size_t) (t - ans) + 4 + 3 * force_ellipsis > console_width) break; *(t++) = '\\'; @@ -399,7 +405,7 @@ char* xescape_full(const char *s, const char *bad, size_t console_width, XEscape *(t++) = hexchar(*f >> 4); *(t++) = hexchar(*f); } else { - if ((size_t) (t - ans) + 1 > console_width) + if ((size_t) (t - ans) + 1 + 3 * force_ellipsis > console_width) break; *(t++) = *f; @@ -432,7 +438,9 @@ char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFl if (FLAGS_SET(flags, XESCAPE_8_BIT)) return xescape_full(str, "", console_width, flags); else - return utf8_escape_non_printable_full(str, console_width); + return utf8_escape_non_printable_full(str, + console_width, + FLAGS_SET(flags, XESCAPE_FORCE_ELLIPSIS)); } char* octescape(const char *s, size_t len) { |