Sync up with kern/subr_prf.c. This adds %ll, %j, %q, %z, etc.

This commit is contained in:
Peter Wemm 2003-04-06 05:25:48 +00:00
parent 67db8b23c3
commit 77ac203091
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113159

View File

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