PERFORCE change 28273 for review

Peter Wemm peter at FreeBSD.org
Sat Apr 5 15:54:04 PST 2003


http://perforce.freebsd.org/chv.cgi?CH=28273

Change 28273 by peter at peter_overcee on 2003/04/05 15:53:34

	Bring printf kicking and screaming up to 2003
	(translation: sync with kernel printf for things
	 like %j, %q/%ll etc)

Affected files ...

.. //depot/projects/hammer/lib/libstand/printf.c#3 edit

Differences ...

==== //depot/projects/hammer/lib/libstand/printf.c#3 (text+ko) ====

@@ -45,7 +45,10 @@
  * Standaloneified version of the FreeBSD kernel printf family.
  */
 
+#include <sys/param.h>
 #include <sys/types.h>
+#include <sys/stddef.h>
+#include <sys/stdint.h>
 #include <limits.h>
 #include <string.h>
 #include "stand.h"
@@ -56,7 +59,9 @@
  */
 #include <machine/stdarg.h>
 
-static char	*ksprintn (u_long num, int base, int *len);
+#define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
+
+static char	*ksprintn (char *buf, uintmax_t num, int base, int *len);
 static int	kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
 
 int
@@ -101,24 +106,23 @@
 }
 
 /*
- * Put a number (base <= 16) in a buffer in reverse order; return an
- * optional length and a pointer to the NULL terminated (preceded?)
- * buffer.
+ * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
+ * order; return an optional length and a pointer to the last character
+ * written in the buffer (i.e., the first character of the string).
+ * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
  */
 static char *
-ksprintn(ul, base, lenp)
-	u_long ul;
-	int base, *lenp;
-{					/* A long in base 8, plus NULL. */
-	static char buf[sizeof(long) * CHAR_BIT / 3 + 2];
+ksprintn(char *nbuf, uintmax_t num, int base, int *lenp)
+{
 	char *p;
 
-	p = buf;
+	p = nbuf;
+	*p = '\0';
 	do {
-		*++p = hex2ascii(ul % base);
-	} while (ul /= base);
+		*++p = hex2ascii(num % base);
+	} while (num /= base);
 	if (lenp)
-		*lenp = p - buf;
+		*lenp = p - nbuf;
 	return (p);
 }
 
@@ -152,15 +156,19 @@
 kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
 {
 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
-	char *p, *q, *d;
+	char nbuf[MAXNBUF];
+	char *d;
+	const char *p, *percent, *q;
 	u_char *up;
 	int ch, n;
-	u_long ul;
-	int base, lflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+	uintmax_t num;
+	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+	int jflag, tflag, zflag;
 	int dwidth;
 	char padc;
 	int retval = 0;
 
+	num = 0;
 	if (!func)
 		d = (char *) arg;
 	else
@@ -176,12 +184,14 @@
 		padc = ' ';
 		width = 0;
 		while ((ch = (u_char)*fmt++) != '%') {
-			if (ch == '\0') 
-				return retval;
+			if (ch == '\0')
+				return (retval);
 			PCHAR(ch);
 		}
-		lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
+		percent = fmt - 1;
+		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
 		sign = 0; dot = 0; dwidth = 0;
+		jflag = 0; tflag = 0; zflag = 0;
 reswitch:	switch (ch = (u_char)*fmt++) {
 		case '.':
 			dot = 1;
@@ -228,17 +238,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(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);
@@ -268,26 +278,49 @@
 			}
 			break;
 		case 'd':
-			ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
+		case 'i':
+			base = 10;
 			sign = 1;
-			base = 10;
-			goto number;
+			goto handle_sign;
+		case 'j':
+			jflag = 1;
+			goto reswitch;
 		case 'l':
-			lflag = 1;
+			if (lflag) {
+				lflag = 0;
+				qflag = 1;
+			} else
+				lflag = 1;
 			goto reswitch;
 		case 'n':
-			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
-			base = radix;
-			goto number;
+			if (jflag)
+				*(va_arg(ap, intmax_t *)) = retval;
+			else if (qflag)
+				*(va_arg(ap, quad_t *)) = retval;
+			else if (lflag)
+				*(va_arg(ap, long *)) = retval;
+			else if (zflag)
+				*(va_arg(ap, size_t *)) = retval;
+			else
+				*(va_arg(ap, int *)) = retval;
+			break;
 		case 'o':
-			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
 			base = 8;
-			goto number;
+			goto handle_nosign;
 		case 'p':
-			ul = (u_long)va_arg(ap, void *);
 			base = 16;
-			sharpflag = 1;
+			sharpflag = (width == 0);
+			sign = 0;
+			num = (uintptr_t)va_arg(ap, void *);
 			goto number;
+		case 'q':
+			qflag = 1;
+			goto reswitch;
+		case 'r':
+			base = radix;
+			if (sign)
+				goto handle_sign;
+			goto handle_nosign;
 		case 's':
 			p = va_arg(ap, char *);
 			if (p == NULL)
@@ -309,19 +342,58 @@
 				while (width--)
 					PCHAR(padc);
 			break;
+		case 't':
+			tflag = 1;
+			goto reswitch;
 		case 'u':
-			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
 			base = 10;
-			goto number;
+			goto handle_nosign;
 		case 'x':
-			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
+		case 'X':
+			base = 16;
+			goto handle_nosign;
+		case 'y':
 			base = 16;
-number:			if (sign && (long)ul < 0L) {
+			sign = 1;
+			goto handle_sign;
+		case 'z':
+			zflag = 1;
+			goto reswitch;
+handle_nosign:
+			sign = 0;
+			if (jflag)
+				num = va_arg(ap, uintmax_t);
+			else if (qflag)
+				num = va_arg(ap, u_quad_t);
+			else if (tflag)
+				num = va_arg(ap, ptrdiff_t);
+			else if (lflag)
+				num = va_arg(ap, u_long);
+			else if (zflag)
+				num = va_arg(ap, size_t);
+			else
+				num = va_arg(ap, u_int);
+			goto number;
+handle_sign:
+			if (jflag)
+				num = va_arg(ap, intmax_t);
+			else if (qflag)
+				num = va_arg(ap, quad_t);
+			else if (tflag)
+				num = va_arg(ap, ptrdiff_t);
+			else if (lflag)
+				num = va_arg(ap, long);
+			else if (zflag)
+				num = va_arg(ap, size_t);
+			else
+				num = va_arg(ap, int);
+number:
+			if (sign && (intmax_t)num < 0) {
 				neg = 1;
-				ul = -(long)ul;
+				num = -(intmax_t)num;
 			}
-			p = ksprintn(ul, base, &tmp);
-			if (sharpflag && ul != 0) {
+			p = ksprintn(nbuf, num, base, &tmp);
+			if (sharpflag && num != 0) {
 				if (base == 8)
 					tmp++;
 				else if (base == 16)
@@ -335,7 +407,7 @@
 					PCHAR(padc);
 			if (neg)
 				PCHAR('-');
-			if (sharpflag && ul != 0) {
+			if (sharpflag && num != 0) {
 				if (base == 8) {
 					PCHAR('0');
 				} else if (base == 16) {
@@ -353,13 +425,10 @@
 
 			break;
 		default:
-			PCHAR('%');
-			if (lflag)
-				PCHAR('l');
-			PCHAR(ch);
+			while (percent < fmt)
+				PCHAR(*percent++);
 			break;
 		}
 	}
 #undef PCHAR
 }
-


More information about the p4-projects mailing list