Sync up with kern/subr_prf.c. This adds %ll, %j, %q, %z, etc.
This commit is contained in:
parent
67db8b23c3
commit
77ac203091
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113159
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user