commit d848bcac4b1160f9e05a9acf5d00d0418285eec3
parent 6e7cbdd918d87785b7ba41a09d92f6ab49e0b522
Author: FRIGN <dev@frign.de>
Date: Sun, 21 Jun 2015 15:52:21 +0200
Fix parameter-usage in printf(1)
1) Don't default to a space for numeric conversions. Instead,
set flag to 0 and work with it on a case-basis.
This fixes the wrong output of "printf %d 20" which had a
space prepended to it (" 20").
2) Add precision for doiuxX, which is zero-padding.
This fixes the wrong output of "printf %.5d 20" to properly
print "00020".
Thanks to emg for reporting these!
Diffstat:
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/printf.c b/printf.c
@@ -49,8 +49,8 @@ main(int argc, char *argv[])
}
/* flag */
- for (flag = ' ', i++; strchr("#-+ 0", format[i]); i++) {
- flag = format[i];
+ for (flag = '\0', i++; strchr("#-+ 0", format[i]); i++) {
+ if (!flag) flag = format[i];
}
/* field width */
@@ -135,18 +135,21 @@ main(int argc, char *argv[])
rarg = ereallocarray(NULL, utflen(arg) + 1, sizeof(*rarg));
utftorunestr(arg, rarg);
num = rarg[0];
- } else
+ } else {
num = (strlen(arg) > 0) ? estrtonum(arg, LLONG_MIN, LLONG_MAX) : 0;
- fmt = estrdup("%#*ll#");
- fmt[1] = flag;
- fmt[5] = format[i];
- printf(fmt, width, num);
+ }
+ fmt = estrdup(flag ? "%#*.*ll#" : "%*.*ll#");
+ if (flag)
+ fmt[1] = flag;
+ fmt[flag ? 7 : 6] = format[i];
+ printf(fmt, width, precision, num);
free(fmt);
break;
case 'a': case 'A': case 'e': case 'E': case 'f': case 'F': case 'g': case 'G':
- fmt = estrdup("%#*.*#");
- fmt[1] = flag;
- fmt[5] = format[i];
+ fmt = estrdup(flag ? "%#*.*#" : "%*.*#");
+ if (flag)
+ fmt[1] = flag;
+ fmt[flag ? 5 : 4] = format[i];
dou = (strlen(arg) > 0) ? estrtod(arg) : 0;
printf(fmt, width, precision, dou);
free(fmt);