svn commit: r210306 - stable/8/lib/libstand

Jung-uk Kim jkim at FreeBSD.org
Tue Jul 20 18:59:10 UTC 2010


Author: jkim
Date: Tue Jul 20 18:59:10 2010
New Revision: 210306
URL: http://svn.freebsd.org/changeset/base/210306

Log:
  MFC:	r209837, r209842, r209949
  
  Sync. printf() of libstand(3) with sys/kern/subr_prf.c.
  
  CVS r1.94	jhb:
  Cast the integer read as the first argument for %b to an unsigned integer
  so it's value is not sign extended when assigned to the uintmax_t variable
  used internally by printf.  For example, if bit 31 is set in the cpuid
  feature word, then %b would print out the initial value as a 16 character
  hexadecimal value.  Now it only prints out an 8 character value.
  
  CVS r1.109	njl:
  Add support for 'h' and 'hh' modifiers for printf(9).
  
  CVS r1.117	phk:
  If we ignore an unknown % sequence, we must stop interpreting the remaining
  % arguments because the varargs are now out of sync and there is a risk that
  we might for instance dereference an integer in a %s argument.
  
  SVN r209836	jkim:
  Implement optional 'precision' for numbers.  Previously, it was parsed but
  ignored.  Some third-party modules (e.g., ACPICA) prefer this format over
  zero padding flag '0'.

Modified:
  stable/8/lib/libstand/printf.c
Directory Properties:
  stable/8/lib/libstand/   (props changed)

Modified: stable/8/lib/libstand/printf.c
==============================================================================
--- stable/8/lib/libstand/printf.c	Tue Jul 20 18:55:13 2010	(r210305)
+++ stable/8/lib/libstand/printf.c	Tue Jul 20 18:59:10 2010	(r210306)
@@ -159,10 +159,10 @@ kvprintf(char const *fmt, void (*func)(i
 	int ch, n;
 	uintmax_t num;
 	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
-	int jflag, tflag, zflag;
+	int cflag, hflag, jflag, tflag, zflag;
 	int dwidth, upper;
 	char padc;
-	int retval = 0;
+	int stop = 0, retval = 0;
 
 	num = 0;
 	if (!func)
@@ -179,7 +179,7 @@ kvprintf(char const *fmt, void (*func)(i
 	for (;;) {
 		padc = ' ';
 		width = 0;
-		while ((ch = (u_char)*fmt++) != '%') {
+		while ((ch = (u_char)*fmt++) != '%' || stop) {
 			if (ch == '\0')
 				return (retval);
 			PCHAR(ch);
@@ -187,7 +187,7 @@ kvprintf(char const *fmt, void (*func)(i
 		percent = fmt - 1;
 		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
 		sign = 0; dot = 0; dwidth = 0; upper = 0;
-		jflag = 0; tflag = 0; zflag = 0;
+		cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
 reswitch:	switch (ch = (u_char)*fmt++) {
 		case '.':
 			dot = 1;
@@ -234,7 +234,7 @@ reswitch:	switch (ch = (u_char)*fmt++) {
 				width = n;
 			goto reswitch;
 		case 'b':
-			num = va_arg(ap, int);
+			num = (u_int)va_arg(ap, int);
 			p = va_arg(ap, char *);
 			for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
 				PCHAR(*q--);
@@ -278,6 +278,13 @@ reswitch:	switch (ch = (u_char)*fmt++) {
 			base = 10;
 			sign = 1;
 			goto handle_sign;
+		case 'h':
+			if (hflag) {
+				hflag = 0;
+				cflag = 1;
+			} else
+				hflag = 1;
+			goto reswitch;
 		case 'j':
 			jflag = 1;
 			goto reswitch;
@@ -297,6 +304,10 @@ reswitch:	switch (ch = (u_char)*fmt++) {
 				*(va_arg(ap, long *)) = retval;
 			else if (zflag)
 				*(va_arg(ap, size_t *)) = retval;
+			else if (hflag)
+				*(va_arg(ap, short *)) = retval;
+			else if (cflag)
+				*(va_arg(ap, char *)) = retval;
 			else
 				*(va_arg(ap, int *)) = retval;
 			break;
@@ -368,6 +379,10 @@ handle_nosign:
 				num = va_arg(ap, u_long);
 			else if (zflag)
 				num = va_arg(ap, size_t);
+			else if (hflag)
+				num = (u_short)va_arg(ap, int);
+			else if (cflag)
+				num = (u_char)va_arg(ap, int);
 			else
 				num = va_arg(ap, u_int);
 			goto number;
@@ -382,6 +397,10 @@ handle_sign:
 				num = va_arg(ap, long);
 			else if (zflag)
 				num = va_arg(ap, ssize_t);
+			else if (hflag)
+				num = (short)va_arg(ap, int);
+			else if (cflag)
+				num = (char)va_arg(ap, int);
 			else
 				num = va_arg(ap, int);
 number:
@@ -389,7 +408,8 @@ number:
 				neg = 1;
 				num = -(intmax_t)num;
 			}
-			p = ksprintn(nbuf, num, base, &tmp, upper);
+			p = ksprintn(nbuf, num, base, &n, upper);
+			tmp = 0;
 			if (sharpflag && num != 0) {
 				if (base == 8)
 					tmp++;
@@ -399,9 +419,13 @@ number:
 			if (neg)
 				tmp++;
 
-			if (!ladjust && width && (width -= tmp) > 0)
-				while (width--)
-					PCHAR(padc);
+			if (!ladjust && padc == '0')
+				dwidth = width - tmp;
+			width -= tmp + imax(dwidth, n);
+			dwidth -= n;
+			if (!ladjust)
+				while (width-- > 0)
+					PCHAR(' ');
 			if (neg)
 				PCHAR('-');
 			if (sharpflag && num != 0) {
@@ -412,18 +436,27 @@ number:
 					PCHAR('x');
 				}
 			}
+			while (dwidth-- > 0)
+				PCHAR('0');
 
 			while (*p)
 				PCHAR(*p--);
 
-			if (ladjust && width && (width -= tmp) > 0)
-				while (width--)
-					PCHAR(padc);
+			if (ladjust)
+				while (width-- > 0)
+					PCHAR(' ');
 
 			break;
 		default:
 			while (percent < fmt)
 				PCHAR(*percent++);
+			/*
+			 * Since we ignore an formatting argument it is no 
+			 * longer safe to obey the remaining formatting
+			 * arguments as the arguments will no longer match
+			 * the format specs.
+			 */
+			stop = 1;
 			break;
 		}
 	}


More information about the svn-src-all mailing list