Re: %j for printf(9)

Dag-Erling Smorgrav <[email protected]>
Newsgroups gmane.os.freebsd.devel.audit
Message-ID <[email protected]>
Dag-Erling Smorgrav <[email protected]> writes:
> Applied, and renamed fetch_* to handle_*.  I'll test it a bit before
> committing.

Here's the full patch, btw.

DES
-- 
Dag-Erling Smorgrav - [email protected]
subr_prf.diff (text/x-patch, 7.2 KB)
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	2 Jun 2002 14:00:03 -0000
@@ -48,6 +48,7 @@
 #include <sys/msgbuf.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
+#include <sys/stdint.h>
 #include <sys/sysctl.h>
 #include <sys/tty.h>
 #include <sys/syslog.h>
@@ -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,18 @@
 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++; }
-	char nbuf[MAXNBUF];
-	char *p, *q, *d;
+	char nbuf[MAXNBUF], *d;
+	const char *percent, *p, *q;
 	u_char *up;
 	int ch, n;
-	u_long ul;
-	u_quad_t uq;
+	uintmax_t num;
 	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+	int jflag;
 	int dwidth;
 	char padc;
 	int retval = 0;
 
-	ul = 0;
-	uq = 0;
+	num = 0;
 	if (!func)
 		d = (char *) arg;
 	else
@@ -523,8 +504,10 @@
 				return (retval);
 			PCHAR(ch);
 		}
+		percent = fmt - 1;
 		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
 		sign = 0; dot = 0; dwidth = 0;
+		jflag = 0;
 reswitch:	switch (ch = (u_char)*fmt++) {
 		case '.':
 			dot = 1;
@@ -571,17 +554,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 +594,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;
+			sign = 1;
+			goto handle_sign;
+		case 'j':
+			jflag = 1;
+			goto reswitch;
 		case 'l':
 			if (lflag) {
 				lflag = 0;
@@ -627,34 +607,33 @@
 			} else
 				lflag = 1;
 			goto reswitch;
-		case 'o':
-			if (qflag)
-				uq = va_arg(ap, u_quad_t);
+		case 'n':
+			if (jflag)
+				*(va_arg(ap, intmax_t *)) = retval;
+			else if (qflag)
+				*(va_arg(ap, quad_t *)) = retval;
 			else if (lflag)
-				ul = va_arg(ap, u_long);
+				*(va_arg(ap, long *)) = retval;
 			else
-				ul = va_arg(ap, u_int);
+				*(va_arg(ap, int *)) = retval;
+			break;
+		case 'o':
 			base = 8;
-			goto nosign;
+			goto handle_nosign;
 		case 'p':
-			ul = (uintptr_t)va_arg(ap, void *);
 			base = 16;
 			sharpflag = (width == 0);
-			goto nosign;
+			sign = 0;
+			num = (uintptr_t)va_arg(ap, void *);
+			goto number;
 		case 'q':
 			qflag = 1;
 			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;
+			if (sign)
+				goto handle_sign;
+			goto handle_nosign;
 		case 's':
 			p = va_arg(ap, char *);
 			if (p == NULL)
@@ -677,50 +656,43 @@
 					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 handle_nosign;
 		case 'x':
 		case 'X':
-			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 = 16;
-			goto nosign;
+			goto handle_nosign;
 		case 'z':
-			if (qflag)
-				uq = va_arg(ap, u_quad_t);
+			base = 16;
+			if (sign)
+				goto handle_sign;
+handle_nosign:
+			sign = 0;
+			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 = 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);
+handle_sign:
+			if (jflag)
+				num = va_arg(ap, intmax_t);
+			else if (qflag)
+				num = va_arg(ap, quad_t);
+			else if (lflag)
+				num = va_arg(ap, long);
+			else
+				num = va_arg(ap, int);
+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 +706,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 +724,8 @@
 
 			break;
 		default:
-			PCHAR('%');
-			if (lflag)
-				PCHAR('l');
-			PCHAR(ch);
+			while (percent < fmt)
+				PCHAR(*percent++);
 			break;
 		}
 	}
@@ -783,7 +753,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;
@@ -908,7 +878,7 @@
 }
 
 SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, &msgbuf_clear, 0, 
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, &msgbuf_clear, 0,
     sysctl_kern_msgbuf_clear, "I", "Clear kernel message buffer");
 
 #include "opt_ddb.h"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.