printf: Output formatted data directly, instead of via asprintf.

Long ago, sh used to have its own optimized and restricted string formatting
implementation, which the printf builtin had to bypass via asprintf() to a
temporary buffer. Since sh has used libc's string formatting implementation
for a long time, remove the workaround.

Add a check to keep  printf %c ''  working the same way (output nothing);
POSIX allows both outputting nothing and outputting a NUL byte.

Also, this change avoids silently discarding format directives for whose
output asprintf() cannot allocate memory.
This commit is contained in:
Jilles Tjoelker 2017-04-29 21:48:11 +00:00
parent 10e0318afa
commit 342b089bca

View File

@ -70,20 +70,15 @@ static const char rcsid[] =
#endif
#define PF(f, func) do { \
char *b = NULL; \
if (havewidth) \
if (haveprec) \
(void)asprintf(&b, f, fieldwidth, precision, func); \
(void)printf(f, fieldwidth, precision, func); \
else \
(void)asprintf(&b, f, fieldwidth, func); \
(void)printf(f, fieldwidth, func); \
else if (haveprec) \
(void)asprintf(&b, f, precision, func); \
(void)printf(f, precision, func); \
else \
(void)asprintf(&b, f, func); \
if (b) { \
(void)fputs(b, stdout); \
free(b); \
} \
(void)printf(f, func); \
} while (0)
static int asciicode(void);
@ -394,7 +389,8 @@ printf_doformat(char *fmt, int *rval)
char p;
p = getchr();
PF(start, p);
if (p != '\0')
PF(start, p);
break;
}
case 's': {