static const char *parse_conversion (const char *format,
struct printf_conversion *,
va_list *);
-static void format_integer (uintmax_t value, bool negative,
+static void format_integer (uintmax_t value, bool is_signed, bool negative,
const struct integer_base *,
const struct printf_conversion *,
void (*output) (char, void *), void *aux);
}
format_integer (value < 0 ? -value : value,
- value < 0, &base_d, &c, output, aux);
+ true, value < 0, &base_d, &c, output, aux);
}
break;
case 'X': b = &base_X; break;
default: NOT_REACHED ();
}
-
- format_integer (value, false, b, &c, output, aux);
+
+ format_integer (value, false, false, b, &c, output, aux);
}
break;
void *p = va_arg (args, void *);
c.flags = POUND;
- format_integer ((uintptr_t) p, false, &base_x, &c, output, aux);
+ format_integer ((uintptr_t) p, false, false,
+ &base_x, &c, output, aux);
}
break;
/* Performs an integer conversion, writing output to OUTPUT with
auxiliary data AUX. The integer converted has absolute value
- VALUE. If NEGATIVE is true the value is negative, otherwise
- positive. The output will use the given DIGITS, with
- strlen(DIGITS) indicating the output base. Details of the
- conversion are in C. */
+ VALUE. If IS_SIGNED is true, does a signed conversion with
+ NEGATIVE indicating a negative value; otherwise does an
+ unsigned conversion and ignores IS_SIGNED. The output will
+ use the given DIGITS, with strlen(DIGITS) indicating the
+ output base. Details of the conversion are in C. */
static void
-format_integer (uintmax_t value, bool negative, const struct integer_base *b,
+format_integer (uintmax_t value, bool is_signed, bool negative,
+ const struct integer_base *b,
const struct printf_conversion *c,
void (*output) (char, void *), void *aux)
{
const char *signifier; /* b->signifier or "". */
int precision; /* Rendered precision. */
int pad_cnt; /* # of pad characters to fill field width. */
- int group_cnt; /* # of digits grouped so far. */
+ int digit_cnt; /* # of digits output so far. */
/* Accumulate digits into buffer.
This algorithm produces digits in reverse order, so later we
will output the buffer's content in reverse. This is also
the reason that later we append zeros and the sign. */
cp = buf;
- group_cnt = 0;
+ digit_cnt = 0;
while (value > 0)
{
- if ((c->flags & GROUP) && group_cnt++ == b->group)
- {
- *cp++ = ',';
- group_cnt = 0;
- }
+ if ((c->flags & GROUP) && digit_cnt > 0 && digit_cnt % b->group == 0)
+ *cp++ = ',';
*cp++ = b->digits[value % b->base];
value /= b->base;
+ digit_cnt++;
}
/* Append enough zeros to match precision.
If requested precision is 0, then a value of zero is
rendered as a null string, otherwise as "0". */
precision = c->precision < 0 ? 1 : c->precision;
- if (precision < 0)
- precision = 1;
while (cp - buf < precision && cp - buf < (int) sizeof buf - 8)
*cp++ = '0';
/* Append sign. */
- if (c->flags & PLUS)
- *cp++ = negative ? '-' : '+';
- else if (c->flags & SPACE)
- *cp++ = negative ? '-' : ' ';
- else if (negative)
- *cp++ = '-';
-
+ if (is_signed)
+ {
+ if (c->flags & PLUS)
+ *cp++ = negative ? '-' : '+';
+ else if (c->flags & SPACE)
+ *cp++ = negative ? '-' : ' ';
+ else if (negative)
+ *cp++ = '-';
+ }
+
/* Calculate number of pad characters to fill field width. */
signifier = c->flags & POUND ? b->signifier : "";
pad_cnt = c->width - (cp - buf) - strlen (signifier);