diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2004-09-22 22:05:12 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2004-09-22 22:05:12 +0000 |
commit | ef43acf1a7be490ff52be1142a65b3f77a30e60a (patch) | |
tree | 66ada87e0c858a2ff5ea0291609b3567851ce6a4 /sys/lib | |
parent | d977e3b111350e3f875d5861b7d162515b802b4d (diff) |
Add code to let 32bit code *printf() {u,}int64_t values.
Only enabled if libsa is compiled with the adequate define, so as not to
grow bootblocks which do not need this feature.
ok deraadt@
Diffstat (limited to 'sys/lib')
-rw-r--r-- | sys/lib/libsa/printf.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/sys/lib/libsa/printf.c b/sys/lib/libsa/printf.c index 3eeba5e5b93..24bdc640d36 100644 --- a/sys/lib/libsa/printf.c +++ b/sys/lib/libsa/printf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printf.c,v 1.22 2004/01/03 14:08:53 espie Exp $ */ +/* $OpenBSD: printf.c,v 1.23 2004/09/22 22:05:11 miod Exp $ */ /* $NetBSD: printf.c,v 1.10 1996/11/30 04:19:21 gwr Exp $ */ /*- @@ -62,6 +62,9 @@ #include "stand.h" void kprintn(void (*)(int), u_long, int); +#ifdef LIBSA_LONGLONG_PRINTF +void kprintn64(void (*)(int), u_int64_t, int); +#endif void kdoprnt(void (*)(int), const char *, va_list); void @@ -83,6 +86,9 @@ vprintf(const char *fmt, va_list ap) void kdoprnt(void (*put)(int), const char *fmt, va_list ap) { +#ifdef LIBSA_LONGLONG_PRINTF + u_int64_t ull; +#endif unsigned long ul; int ch, lflag; char *p; @@ -96,7 +102,7 @@ kdoprnt(void (*put)(int), const char *fmt, va_list ap) lflag = 0; reswitch: switch (ch = *fmt++) { case 'l': - lflag = 1; + lflag++; goto reswitch; #ifndef STRIPPED case 'b': @@ -135,6 +141,17 @@ reswitch: switch (ch = *fmt++) { put(ch); break; case 'd': +#ifdef LIBSA_LONGLONG_PRINTF + if (lflag > 1) { + ull = va_arg(ap, int64_t); + if ((int64_t)ull < 0) { + put('-'); + ull = -(int64_t)ull; + } + kprintn64(put, ull, 10); + break; + } +#endif ul = lflag ? va_arg(ap, long) : va_arg(ap, int); if ((long)ul < 0) { @@ -144,11 +161,25 @@ reswitch: switch (ch = *fmt++) { kprintn(put, ul, 10); break; case 'o': +#ifdef LIBSA_LONGLONG_PRINTF + if (lflag > 1) { + ull = va_arg(ap, u_int64_t); + kprintn64(put, ull, 8); + break; + } +#endif ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); kprintn(put, ul, 8); break; case 'u': +#ifdef LIBSA_LONGLONG_PRINTF + if (lflag > 1) { + ull = va_arg(ap, u_int64_t); + kprintn64(put, ull, 10); + break; + } +#endif ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); kprintn(put, ul, 10); @@ -158,13 +189,24 @@ reswitch: switch (ch = *fmt++) { put('x'); lflag += sizeof(void *)==sizeof(u_long)? 1 : 0; case 'x': +#ifdef LIBSA_LONGLONG_PRINTF + if (lflag > 1) { + ull = va_arg(ap, u_int64_t); + kprintn64(put, ull, 16); + break; + } +#endif ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); kprintn(put, ul, 16); break; default: put('%'); +#ifdef LIBSA_LONGLONG_PRINTF + while (--lflag) +#else if (lflag) +#endif put('l'); put(ch); } @@ -187,6 +229,23 @@ kprintn(void (*put)(int), unsigned long ul, int base) } while (p > buf); } +#ifdef LIBSA_LONGLONG_PRINTF +void +kprintn64(void (*put)(int), u_int64_t ull, int base) +{ + /* hold an int64_t in base 8 */ + char *p, buf[(sizeof(u_int64_t) * NBBY / 3) + 1]; + + p = buf; + do { + *p++ = "0123456789abcdef"[ull % base]; + } while (ull /= base); + do { + put(*--p); + } while (p > buf); +} +#endif + int donottwiddle = 0; void |