bin/39116: /usr/bin/printf
Hiroo Ono
hiroo+freebsd at oikumene.gcd.org
Tue Jul 19 16:58:55 GMT 2005
The fix for this PR is done in HEAD
src/usr.bin/printf/printf.c rev.1.22 to 1.25
I made a MFC patch for this, and tested on RELENG_4,
FreeBSD 4.11-STABLE #26: Sat Jul 2 02:02:27 JST 2005.
Tested with the three cases in this PR. The results are same as on
FreeBSD 5.4R-p4.
chrysanthe% ./printf '\45\n'
%
chrysanthe% ./printf '%%%s\n' a b c
%a
%b
%c
chrysanthe% ./printf '%*i\n'
0
Would somebody commit it to RELENG_4 and close this PR?
PR: 39116
Submitted by: Egil Brendsdal <egilb at ife.no>
1.25
Fix duplicate % in %b format introduced in rev 1.22.
1.24
Let printf(1) tell the difference between zero width/precision and
unspecified width/precision.
1.23
Allow format strings containing "%%" to be reused.
1.22
Allow `%' to be written out with an octal escape (\45 or \045).
----------
--- printf.c.orig 2005-07-19 12:58:43.513437500 +0900
+++ printf.c 2005-07-19 11:04:20.013437500 +0900
@@ -73,12 +73,12 @@
#define PF(f, func) do { \
char *b = NULL; \
- if (fieldwidth) \
- if (precision) \
+ if (havewidth) \
+ if (haveprec) \
(void)asprintf(&b, f, fieldwidth, precision, func); \
else \
(void)asprintf(&b, f, fieldwidth, func); \
- else if (precision) \
+ else if (haveprec) \
(void)asprintf(&b, f, precision, func); \
else \
(void)asprintf(&b, f, func); \
@@ -89,7 +89,7 @@
} while (0)
static int asciicode(void);
-static int escape(char *);
+static int escape(char *, int);
static int getchr(void);
static int getdouble(double *);
static int getint(int *);
@@ -111,7 +111,7 @@
char *argv[];
{
static const char *skip1, *skip2;
- int ch, chopped, end, fieldwidth, precision, rval;
+ int ch, chopped, end, fieldwidth, haveprec, havewidth, precision, rval;
char convch, nextch, *format, *fmt, *start;
#ifndef BUILTIN
@@ -143,7 +143,7 @@
skip1 = "#-+ 0";
skip2 = "0123456789";
- chopped = escape(fmt = format = *argv); /* backslash interpretation */
+ chopped = escape(fmt = format = *argv, 1);/* backslash interpretation */
rval = 0;
gargv = ++argv;
for (;;) {
@@ -173,8 +173,8 @@
if (*fmt == '%') {
if (*++fmt != '%')
break;
- *fmt++ = '\0';
- (void)printf("%s", start);
+ (void)printf("%.*s", (int)(fmt - start), start);
+ fmt++;
goto next;
}
}
@@ -184,9 +184,10 @@
if (*fmt == '*') {
if (getint(&fieldwidth))
return (1);
+ havewidth = 1;
++fmt;
} else {
- fieldwidth = 0;
+ havewidth = 0;
/* skip to possible '.', get following precision */
for (; strchr(skip2, *fmt); ++fmt);
@@ -197,15 +198,16 @@
if (*fmt == '*') {
if (getint(&precision))
return (1);
+ haveprec = 1;
++fmt;
} else {
- precision = 0;
+ haveprec = 0;
/* skip to conversion char */
for (; strchr(skip2, *fmt); ++fmt);
}
} else
- precision = 0;
+ haveprec = 0;
if (!*fmt) {
warnx1("missing format character", NULL, NULL);
return (1);
@@ -228,7 +230,7 @@
warnx2("%s", strerror(ENOMEM), NULL);
return (1);
}
- getout = escape(p);
+ getout = escape(p, 0);
*(fmt - 1) = 's';
PF(start, p);
*(fmt - 1) = 'b';
@@ -323,8 +325,9 @@
}
static int
-escape(fmt)
+escape(fmt, percent)
register char *fmt;
+ int percent;
{
register char *store;
register int value, c;
@@ -376,7 +379,11 @@
value += *fmt - '0';
}
--fmt;
- *store = value;
+ if (percent && value == '%') {
+ *store++ = '%';
+ *store = '%';
+ } else
+ *store = value;
break;
default:
*store = *fmt;
----------
More information about the freebsd-bugs
mailing list