From owner-freebsd-audit Sat May 25 6:29:29 2002 Delivered-To: freebsd-audit@freebsd.org Received: from flood.ping.uio.no (flood.ping.uio.no [129.240.78.31]) by hub.freebsd.org (Postfix) with ESMTP id ABD8A37B407 for ; Sat, 25 May 2002 06:29:17 -0700 (PDT) Received: by flood.ping.uio.no (Postfix, from userid 2602) id 55FFE5307; Sat, 25 May 2002 15:29:12 +0200 (CEST) X-URL: http://www.ofug.org/~des/ X-Disclaimer: The views expressed in this message do not necessarily coincide with those of any organisation or company with which I am or have been affiliated. To: Dima Dorfman Cc: audit@freebsd.org Subject: Re: %j for printf(9) References: <20020523050017.E3A2A3E22@turbine.trit.org> From: Dag-Erling Smorgrav Date: 25 May 2002 15:29:11 +0200 In-Reply-To: <20020523050017.E3A2A3E22@turbine.trit.org> Message-ID: Lines: 13 User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.2 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --=-=-= Dima Dorfman writes: > Attached is a patch that implements the %j length modifier in > printf(9). Here's an alternative (IMHO less disruptive) patch, which also fixes the default case. DES -- Dag-Erling Smorgrav - des@ofug.org --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=kvprintf.diff Index: subr_prf.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_prf.c,v retrieving revision 1.81 diff -u -r1.81 subr_prf.c --- subr_prf.c 29 Apr 2002 09:15:38 -0000 1.81 +++ subr_prf.c 25 May 2002 13:25:11 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -65,7 +66,7 @@ #define TOLOG 0x04 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */ -#define MAXNBUF (sizeof(quad_t) * NBBY + 1) +#define MAXNBUF (sizeof(intmax_t) * NBBY + 1) struct putchar_arg { int flags; @@ -86,8 +87,7 @@ static void msglogchar(int c, int pri); static void msgaddchar(int c, void *dummy); static void putchar(int ch, void *arg); -static char *ksprintn(char *nbuf, u_long num, int base, int *len); -static char *ksprintqn(char *nbuf, u_quad_t num, int base, int *len); +static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len); static void snprintf_func(int ch, void *arg); static int consintr = 1; /* Ok to handle console interrupts? */ @@ -426,9 +426,9 @@ * The buffer pointed to by `nbuf' must have length >= MAXNBUF. */ static char * -ksprintn(nbuf, ul, base, lenp) +ksprintn(nbuf, num, base, lenp) char *nbuf; - u_long ul; + uintmax_t num; int base, *lenp; { char *p; @@ -436,26 +436,8 @@ p = nbuf; *p = '\0'; do { - *++p = hex2ascii(ul % base); - } while (ul /= base); - if (lenp) - *lenp = p - nbuf; - return (p); -} -/* ksprintn, but for a quad_t. */ -static char * -ksprintqn(nbuf, uq, base, lenp) - char *nbuf; - u_quad_t uq; - int base, *lenp; -{ - char *p; - - p = nbuf; - *p = '\0'; - do { - *++p = hex2ascii(uq % base); - } while (uq /= base); + *++p = hex2ascii(num % base); + } while (num /= base); if (lenp) *lenp = p - nbuf; return (p); @@ -491,19 +473,19 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) { #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; } + const char *percent; char nbuf[MAXNBUF]; char *p, *q, *d; u_char *up; int ch, n; - u_long ul; - u_quad_t uq; - int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + uintmax_t num; + int base, lflag, jflag, qflag, tmp, width; + int ladjust, sharpflag, neg, sign, dot; int dwidth; char padc; int retval = 0; - ul = 0; - uq = 0; + num = 0; if (!func) d = (char *) arg; else @@ -523,9 +505,11 @@ return (retval); PCHAR(ch); } - qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; - sign = 0; dot = 0; dwidth = 0; -reswitch: switch (ch = (u_char)*fmt++) { + percent = fmt - 1; + qflag = jflag = lflag = ladjust = sharpflag = + neg = sign = dot = dwidth = 0; +reswitch: + switch (ch = (u_char)*fmt++) { case '.': dot = 1; goto reswitch; @@ -571,17 +555,17 @@ width = n; goto reswitch; case 'b': - ul = va_arg(ap, int); + num = va_arg(ap, int); p = va_arg(ap, char *); - for (q = ksprintn(nbuf, ul, *p++, NULL); *q;) + for (q = ksprintn(nbuf, num, *p++, NULL); *q;) PCHAR(*q--); - if (!ul) + if (num == 0) break; for (tmp = 0; *p;) { n = *p++; - if (ul & (1 << (n - 1))) { + if (num & (1 << (n - 1))) { PCHAR(tmp ? ',' : '<'); for (; (n = *p) > ' '; ++p) PCHAR(n); @@ -611,15 +595,12 @@ } break; case 'd': - if (qflag) - uq = va_arg(ap, quad_t); - else if (lflag) - ul = va_arg(ap, long); - else - ul = va_arg(ap, int); sign = 1; base = 10; - goto number; + goto fetch_number; + case 'j': + jflag = 1; + goto reswitch; case 'l': if (lflag) { lflag = 0; @@ -628,16 +609,10 @@ lflag = 1; goto reswitch; case 'o': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = va_arg(ap, u_int); base = 8; - goto nosign; + goto fetch_nosign; case 'p': - ul = (uintptr_t)va_arg(ap, void *); + num = (uintptr_t)va_arg(ap, void *); base = 16; sharpflag = (width == 0); goto nosign; @@ -646,15 +621,8 @@ goto reswitch; case 'n': case 'r': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = sign ? - (u_long)va_arg(ap, int) : va_arg(ap, u_int); base = radix; - goto number; + goto fetch_number; case 's': p = va_arg(ap, char *); if (p == NULL) @@ -677,50 +645,45 @@ PCHAR(padc); break; case 'u': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = va_arg(ap, u_int); base = 10; - goto nosign; + goto fetch_nosign; case 'x': case 'X': - if (qflag) - uq = va_arg(ap, u_quad_t); + base = 16; + goto fetch_nosign; + case 'z': + base = 16; + goto fetch_number; +fetch_nosign: + if (jflag) + num = va_arg(ap, uintmax_t); + else if (qflag) + num = va_arg(ap, u_quad_t); else if (lflag) - ul = va_arg(ap, u_long); + num = va_arg(ap, u_long); else - ul = va_arg(ap, u_int); - base = 16; + num = va_arg(ap, u_int); goto nosign; - case 'z': - if (qflag) - uq = va_arg(ap, u_quad_t); +fetch_number: + if (jflag) + num = va_arg(ap, uintmax_t); + else if (qflag) + num = va_arg(ap, u_quad_t); else if (lflag) - ul = va_arg(ap, u_long); + num = va_arg(ap, u_long); else - ul = sign ? - (u_long)va_arg(ap, int) : va_arg(ap, u_int); - base = 16; + num = sign ? (uintmax_t)va_arg(ap, int) : + va_arg(ap, u_int); goto number; -nosign: sign = 0; -number: - if (qflag) { - if (sign && (quad_t)uq < 0) { - neg = 1; - uq = -(quad_t)uq; - } - p = ksprintqn(nbuf, uq, base, &tmp); - } else { - if (sign && (long)ul < 0) { - neg = 1; - ul = -(long)ul; - } - p = ksprintn(nbuf, ul, base, &tmp); +nosign: + sign = 0; +number: + if (sign && (intmax_t)num < 0) { + neg = 1; + num = -(intmax_t)num; } - if (sharpflag && (qflag ? uq != 0 : ul != 0)) { + p = ksprintn(nbuf, num, base, &tmp); + if (sharpflag && num != 0) { if (base == 8) tmp++; else if (base == 16) @@ -734,7 +697,7 @@ PCHAR(padc); if (neg) PCHAR('-'); - if (sharpflag && (qflag ? uq != 0 : ul != 0)) { + if (sharpflag && num != 0) { if (base == 8) { PCHAR('0'); } else if (base == 16) { @@ -752,10 +715,8 @@ break; default: - PCHAR('%'); - if (lflag) - PCHAR('l'); - PCHAR(ch); + while (percent < fmt) + PCHAR(*percent++); break; } } @@ -783,7 +744,7 @@ dangling = 0; } msgaddchar('<', NULL); - for (p = ksprintn(nbuf, (u_long)pri, 10, NULL); *p;) + for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL); *p;) msgaddchar(*p--, NULL); msgaddchar('>', NULL); lastpri = pri; --=-=-=-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message