Add support for 'j' flag. Simplify the size modifier code and reduce code

duplication.  Also add support for 'n' specifier.

Reviewed by:	bde
This commit is contained in:
des 2002-06-02 21:54:55 +00:00
parent 28bcbfe85d
commit a79d7499e2

View File

@ -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 (*v_putc)(int) = cnputc; /* routine to putc on virtual console */
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 @@ snprintf_func(int ch, void *arg)
* 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 @@ ksprintn(nbuf, ul, base, lenp)
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);
@ -492,18 +474,18 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_lis
{
#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
char nbuf[MAXNBUF];
char *p, *q, *d;
char *d;
const char *p, *percent, *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 +505,10 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_lis
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 +555,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(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 +595,12 @@ reswitch: switch (ch = (u_char)*fmt++) {
}
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 +608,33 @@ reswitch: switch (ch = (u_char)*fmt++) {
} 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 +657,43 @@ reswitch: switch (ch = (u_char)*fmt++) {
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);
else if (lflag)
ul = va_arg(ap, u_long);
else
ul = sign ?
(u_long)va_arg(ap, int) : va_arg(ap, u_int);
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)
num = va_arg(ap, u_long);
else
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 +707,7 @@ nosign: sign = 0;
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 +725,8 @@ nosign: sign = 0;
break;
default:
PCHAR('%');
if (lflag)
PCHAR('l');
PCHAR(ch);
while (percent < fmt)
PCHAR(*percent++);
break;
}
}
@ -783,7 +754,7 @@ msglogchar(int c, int pri)
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;