From owner-svn-src-all@FreeBSD.ORG Thu Jul 8 22:21:20 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 45792106566B; Thu, 8 Jul 2010 22:21:19 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 335CC8FC13; Thu, 8 Jul 2010 22:21:19 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o68MLJ4X044292; Thu, 8 Jul 2010 22:21:19 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o68MLJPX044290; Thu, 8 Jul 2010 22:21:19 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <201007082221.o68MLJPX044290@svn.freebsd.org> From: Jung-uk Kim Date: Thu, 8 Jul 2010 22:21:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r209837 - head/lib/libstand X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Jul 2010 22:21:20 -0000 Author: jkim Date: Thu Jul 8 22:21:18 2010 New Revision: 209837 URL: http://svn.freebsd.org/changeset/base/209837 Log: 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., APCICA) prefer this format over zero padding flag '0'. Modified: head/lib/libstand/printf.c Modified: head/lib/libstand/printf.c ============================================================================== --- head/lib/libstand/printf.c Thu Jul 8 22:13:23 2010 (r209836) +++ head/lib/libstand/printf.c Thu Jul 8 22:21:18 2010 (r209837) @@ -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 + MAX(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; } }