From 4a2af48e64b63e266948b9341ef11c6c4e5575b7 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 4 Jun 2020 20:14:55 +0100 Subject: printf: emit more contiguous text to improve escape sequences Users have a reasonable expectation that printf should be able to construct ANSI escape sequences and have them take effect. This expectation isn't met because printf tends to output one character at a time whereas busybox-w32 needs escape sequences to be output contiguously Force printf to output contiguous text in two cases: - literal text in the format string - string arguments output using the '%b' format specifier (See GitHub issue #189.) --- coreutils/printf.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/coreutils/printf.c b/coreutils/printf.c index a20fc3301..45d761d1c 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -155,6 +155,12 @@ static double my_xstrtod(const char *arg) static int print_esc_string(const char *str) { char c; +#if ENABLE_PLATFORM_MINGW32 + char *s, *t; + int ret = 0; + + s = t = xstrdup(str); +#endif while ((c = *str) != '\0') { str++; if (c == '\\') { @@ -166,7 +172,12 @@ static int print_esc_string(const char *str) } } else if (*str == 'c') { +#if ENABLE_PLATFORM_MINGW32 + ret = 1; + goto finish; +#else return 1; +#endif } { /* optimization: don't force arg to be on-stack, @@ -176,10 +187,21 @@ static int print_esc_string(const char *str) str = z; } } +#if ENABLE_PLATFORM_MINGW32 + *t++ = c; +#else putchar(c); +#endif } - +#if ENABLE_PLATFORM_MINGW32 + finish: + *t = '\0'; + printf(s); + free(s); + return ret; +#else return 0; +#endif } static void print_direc(char *format, unsigned fmt_length, @@ -293,10 +315,19 @@ static char **print_formatted(char *f, char **argv, int *conv_err) int field_width; /* Arg to first '*' */ int precision; /* Arg to second '*' */ char **saved_argv = argv; +#if ENABLE_PLATFORM_MINGW32 + char *s, *t; + s = t = auto_string(xstrdup(f)); +#endif for (; *f; ++f) { switch (*f) { case '%': +#if ENABLE_PLATFORM_MINGW32 + *t = '\0'; + printf(s); + t = s; +#endif direc_start = f++; direc_length = 1; field_width = precision = 0; @@ -385,6 +416,19 @@ static char **print_formatted(char *f, char **argv, int *conv_err) free(p); } break; +#if ENABLE_PLATFORM_MINGW32 + case '\\': + if (*++f == 'c') { + *t = '\0'; + printf(s); + return saved_argv; /* causes main() to exit */ + } + *t++ = bb_process_escape_sequence((const char **)&f); + f--; + break; + default: + *t++ = *f; +#else case '\\': if (*++f == 'c') { return saved_argv; /* causes main() to exit */ @@ -394,8 +438,13 @@ static char **print_formatted(char *f, char **argv, int *conv_err) break; default: putchar(*f); +#endif } } +#if ENABLE_PLATFORM_MINGW32 + *t = '\0'; + printf(s); +#endif return argv; } -- cgit v1.2.3-55-g6feb