From d848bcac4b1160f9e05a9acf5d00d0418285eec3 Mon Sep 17 00:00:00 2001 From: FRIGN Date: Sun, 21 Jun 2015 15:52:21 +0200 Subject: [PATCH] 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! --- printf.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/printf.c b/printf.c index 1335906..d5d852d 100644 --- 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);