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/stddef.h>
#include <sys/stdint.h>
#include <limits.h>
#include <string.h>
#include "stand.h"
@ -56,7 +58,9 @@ __FBSDID("$FreeBSD$");
*/
#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);
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
* 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 +155,19 @@ static int
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 +183,14 @@ kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
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 +237,17 @@ reswitch: switch (ch = (u_char)*fmt++) {
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 +277,49 @@ reswitch: switch (ch = (u_char)*fmt++) {
}
break;
case 'd':
ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
sign = 1;
case 'i':
base = 10;
goto number;
sign = 1;
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 +341,58 @@ reswitch: switch (ch = (u_char)*fmt++) {
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;
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;
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 +406,7 @@ number: if (sign && (long)ul < 0L) {
PCHAR(padc);
if (neg)
PCHAR('-');
if (sharpflag && ul != 0) {
if (sharpflag && num != 0) {
if (base == 8) {
PCHAR('0');
} else if (base == 16) {
@ -353,13 +424,10 @@ number: if (sign && (long)ul < 0L) {
break;
default:
PCHAR('%');
if (lflag)
PCHAR('l');
PCHAR(ch);
while (percent < fmt)
PCHAR(*percent++);
break;
}
}
#undef PCHAR
}