From: Ralph Corderoy Date: Wed, 10 May 2017 11:13:28 +0000 (+0100) Subject: sbr/fmt_scan.c: Fix `foo%-42{bar}' right-justification bug. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/7083c89c5461aa345eec1e47e5fb047d31832c7a sbr/fmt_scan.c: Fix `foo%-42{bar}' right-justification bug. The space padding was added at the start of the output buffer, not the start of the component being formatted. Caused by 92128dac's move to dynamic allocation for fmt_scan()'s output. Only shows if the component isn't at the start of the buffer. Expand existing test/format/test-rightjustify to cover this. --- diff --git a/sbr/fmt_scan.c b/sbr/fmt_scan.c index 9377b393..de7d8b78 100644 --- a/sbr/fmt_scan.c +++ b/sbr/fmt_scan.c @@ -117,6 +117,7 @@ void cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) { int remaining; /* remaining output width available */ int rjust; + struct charstring *trimmed; size_t end; /* number of input bytes remaining in str */ #ifdef MULTIBYTE_SUPPORT int char_len; /* bytes in current character */ @@ -135,6 +136,8 @@ cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) { } if (remaining > (int) max) { remaining = max; } + trimmed = rjust ? charstring_create(remaining) : dest; + if ((sp = str)) { #ifdef MULTIBYTE_SUPPORT if (mbtowc(NULL, NULL, 0)) {} /* reset shift state */ @@ -180,7 +183,7 @@ cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) { sp++; #endif if (!prevCtrl) { - charstring_push_back (dest, ' '); + charstring_push_back (trimmed, ' '); remaining--; } @@ -191,39 +194,26 @@ cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) { #ifdef MULTIBYTE_SUPPORT if (w >= 0 && remaining >= w) { - charstring_push_back_chars (dest, altstr ? altstr : sp, + charstring_push_back_chars (trimmed, altstr ? altstr : sp, char_len, w); remaining -= w; altstr = NULL; } sp += char_len; #else - charstring_push_back (dest, *sp++); + charstring_push_back (trimmed, *sp++); remaining--; #endif } } - if (rjust) { - if (remaining > 0) { - /* copy string to the right */ - charstring_t copy = charstring_copy (dest); - - /* add padding at the beginning */ - charstring_clear (dest); - for (; remaining > 0; --remaining) { - charstring_push_back (dest, fill); - } - - charstring_append (dest, copy); + while (remaining-- > 0) { + charstring_push_back(dest, fill); + } - charstring_free (copy); - } - } else { - /* pad remaining space */ - while (remaining-- > 0) { - charstring_push_back (dest, fill); - } + if (rjust) { + charstring_append(dest, trimmed); + charstring_free(trimmed); } } diff --git a/test/format/test-rightjustify b/test/format/test-rightjustify index 6ad7e4eb..4dec55ab 100755 --- a/test/format/test-rightjustify +++ b/test/format/test-rightjustify @@ -12,16 +12,18 @@ fi setup_test -actual=`run_prog ${MH_LIBEXEC_DIR}/ap -format "%-30(friendly{text})<"` -expected=" No Such User<' '2>'; do + actual=`run_prog ${MH_LIBEXEC_DIR}/ap -format "$prefix%-20(friendly{text})<'` + expected="$prefix No Such User<&2 - echo " $expected" 1>&2 - echo "but instead got:" 1>&2 - echo " $actual" 1>&2 - failed=`expr ${failed:-0} + 1` -fi + if test x"$actual" != x"$expected"; then + echo "$0: right justification test expected:" 1>&2 + echo " $expected" 1>&2 + echo "but instead got:" 1>&2 + echo " $actual" 1>&2 + failed=`expr ${failed:-0} + 1` + fi +done exit $failed