diff options
author | Yuri Pankov <yuri.pankov@nexenta.com> | 2018-01-12 01:28:27 +0300 |
---|---|---|
committer | Richard Lowe <richlowe@richlowe.net> | 2018-01-11 22:35:31 +0000 |
commit | 77889f88de304cc448614fdeea6fe6c189350319 (patch) | |
tree | 9f32598b07cbbe3dbc6878669996ec197ce976f8 /usr/src/common/util | |
parent | adb387b454acdfe5e18984006af166809cfe9fdc (diff) | |
download | illumos-gate-77889f88de304cc448614fdeea6fe6c189350319.tar.gz |
8944 vsnprintf is still confused about padding numbers
Reviewed by: Andy Stormont <astormont@racktopsystems.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src/common/util')
-rw-r--r-- | usr/src/common/util/string.c | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/usr/src/common/util/string.c b/usr/src/common/util/string.c index 26e5744485..5fe5ddab13 100644 --- a/usr/src/common/util/string.c +++ b/usr/src/common/util/string.c @@ -26,6 +26,7 @@ /* * Copyright (c) 2016 by Delphix. All rights reserved. + * Copyright 2018 Nexenta Systems, Inc. */ /* @@ -70,11 +71,13 @@ vsnprintf(char *buf, size_t buflen, const char *fmt, va_list aargs) { uint64_t ul, tmp; char *bufp = buf; /* current buffer pointer */ - int pad, width, base, sign, c, num; + char c, pad; + int width, base, sign, num; int prec, h_count, l_count, dot_count; int pad_count, transfer_count, left_align; char *digits, *sp, *bs; char numbuf[65]; /* sufficient for a 64-bit binary value */ + int numwidth; va_list args; /* @@ -91,7 +94,7 @@ vsnprintf(char *buf, size_t buflen, const char *fmt, va_list aargs) continue; } - width = prec = 0; + width = prec = numwidth = 0; left_align = base = sign = 0; h_count = l_count = dot_count = 0; pad = ' '; @@ -256,34 +259,53 @@ next_fmt: base = *bs++; } - /* avoid repeated division if width is 0 */ - if (width > 0) { - tmp = ul; - do { - width--; - } while ((tmp /= base) != 0); - } + /* + * Fill in the number string buffer and calculate the + * number string length. + */ + tmp = ul; + sp = numbuf; + do { + *sp++ = digits[tmp % base]; + numwidth++; + } while ((tmp /= base) != 0); + + /* + * Reduce the total field width by precision or the number + * string length depending on which one is bigger, and sign. + */ + if (prec >= numwidth) + width -= prec; + else + width -= numwidth; + width -= sign; + /* Add the sign if width is '0'-padded */ if (sign && pad == '0') ADDCHAR('-'); - while ((!left_align) && (width-- > sign)) - ADDCHAR(pad); - if (sign && pad == ' ') + + /* If not left-aligned, add the width padding */ + if (!left_align) { + while (width-- > 0) + ADDCHAR(pad); + } + + /* Add the sign if width is NOT '0'-padded */ + if (sign && pad != '0') ADDCHAR('-'); - sp = numbuf; - tmp = ul; - do { - *sp++ = digits[tmp % base]; - } while ((tmp /= base) != 0); + /* Add the precision '0'-padding */ + while (prec-- > numwidth) + ADDCHAR('0'); + /* Print out the number */ while (sp > numbuf) { sp--; ADDCHAR(*sp); } - /* add left-alignment padding */ - while (width-- > sign) + /* Add left-alignment padding */ + while (width-- > 0) ADDCHAR(' '); if (c == 'b' && ul != 0) { |