summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2003-04-06 05:25:48 +0000
committerpeter <peter@FreeBSD.org>2003-04-06 05:25:48 +0000
commita3ab268ea4a2d89378e4f5bd090431a7347366b3 (patch)
tree67e4741c45e9a9ca4a54062b30af7b7d8532c21a /lib
parent099c5dc3815f7d00dba37bb95396870048a049ce (diff)
downloadFreeBSD-src-a3ab268ea4a2d89378e4f5bd090431a7347366b3.zip
FreeBSD-src-a3ab268ea4a2d89378e4f5bd090431a7347366b3.tar.gz
Sync up with kern/subr_prf.c. This adds %ll, %j, %q, %z, etc.
Diffstat (limited to 'lib')
-rw-r--r--lib/libstand/printf.c162
1 files changed, 115 insertions, 47 deletions
diff --git a/lib/libstand/printf.c b/lib/libstand/printf.c
index 5f1bedc..e877a53 100644
--- a/lib/libstand/printf.c
+++ b/lib/libstand/printf.c
@@ -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;
+ 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 +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
}
-
OpenPOWER on IntegriCloud