Fix the incorrect handling of %b and \c in printf(1)

This is required for POSIX compliance.

Obtained from:	Garrett D'Amore (Illumos)
MFC after:	4 days
This commit is contained in:
Pedro F. Giffuni 2014-05-08 20:20:59 +00:00
parent 9f8e153645
commit 437bce620f

View File

@ -110,7 +110,7 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
size_t len; size_t len;
int chopped, end, rval; int end, rval;
char *format, *fmt, *start; char *format, *fmt, *start;
#ifndef SHELL #ifndef SHELL
int ch; int ch;
@ -151,7 +151,7 @@ main(int argc, char *argv[])
* up the format string. * up the format string.
*/ */
fmt = format = *argv; fmt = format = *argv;
chopped = escape(fmt, 1, &len); /* backslash interpretation */ escape(fmt, 1, &len); /* backslash interpretation */
rval = end = 0; rval = end = 0;
gargv = ++argv; gargv = ++argv;
@ -195,7 +195,7 @@ main(int argc, char *argv[])
return (1); return (1);
} }
fwrite(start, 1, fmt - start, stdout); fwrite(start, 1, fmt - start, stdout);
if (chopped || !*gargv) { if (!*gargv) {
#ifdef SHELL #ifdef SHELL
INTON; INTON;
#endif #endif
@ -241,8 +241,8 @@ printf_doformat(char *fmt, int *rval)
maxargv = gargv; maxargv = gargv;
fmt += l + 1; fmt += l + 1;
/* save format argument */ /* save format argument */
fargv = gargv; fargv = gargv;
} else { } else {
fargv = NULL; fargv = NULL;
} }
@ -352,7 +352,7 @@ printf_doformat(char *fmt, int *rval)
/* save the current arg offset, and set to the format arg */ /* save the current arg offset, and set to the format arg */
if (fargv != NULL) { if (fargv != NULL) {
gargv = fargv; gargv = fargv;
} }
convch = *fmt; convch = *fmt;
@ -371,12 +371,10 @@ printf_doformat(char *fmt, int *rval)
return (NULL); return (NULL);
} }
getout = escape(p, 0, &len); getout = escape(p, 0, &len);
*(fmt - 1) = 's'; fputs(p, stdout);
PF(start, p);
*(fmt - 1) = 'b';
free(p); free(p);
if (getout) if (getout)
return (fmt); exit(*rval);
break; break;
} }
case 'c': { case 'c': {
@ -488,9 +486,13 @@ escape(char *fmt, int percent, size_t *len)
*store = '\b'; *store = '\b';
break; break;
case 'c': case 'c':
*store = '\0'; if (!percent) {
*len = store - save; *store = '\0';
return (1); *len = store - save;
return (1);
}
*store = 'c';
break;
case 'f': /* form-feed */ case 'f': /* form-feed */
*store = '\f'; *store = '\f';
break; break;