summaryrefslogtreecommitdiff
path: root/usr/src/common/util
diff options
context:
space:
mode:
authorYuri Pankov <yuri.pankov@nexenta.com>2018-01-12 01:28:27 +0300
committerRichard Lowe <richlowe@richlowe.net>2018-01-11 22:35:31 +0000
commit77889f88de304cc448614fdeea6fe6c189350319 (patch)
tree9f32598b07cbbe3dbc6878669996ec197ce976f8 /usr/src/common/util
parentadb387b454acdfe5e18984006af166809cfe9fdc (diff)
downloadillumos-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.c60
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) {