summaryrefslogtreecommitdiff
path: root/sys/lib
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2004-09-22 22:05:12 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2004-09-22 22:05:12 +0000
commitef43acf1a7be490ff52be1142a65b3f77a30e60a (patch)
tree66ada87e0c858a2ff5ea0291609b3567851ce6a4 /sys/lib
parentd977e3b111350e3f875d5861b7d162515b802b4d (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.c63
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