Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/lib/libsa Add long long (%lld etc.) support and width (%...
details: https://anonhg.NetBSD.org/src/rev/cf5d9418f593
branches: trunk
changeset: 750937:cf5d9418f593
user: tsutsui <tsutsui%NetBSD.org@localhost>
date: Tue Jan 19 15:26:45 2010 +0000
description:
Add long long (%lld etc.) support and width (%02x etc.) support
in libsa printf(3). Disabled by default but enabled by
-DLIBSA_PRINTF_LONGLONG_SUPPORT and -DLIBSA_PRINTF_WIDTH_SUPPORT.
Provided by tnozaki@ for my libsa debugging. Thanks!
diffstat:
sys/lib/libsa/subr_prf.c | 226 ++++++++++++++++++++++++++++++++++++++++------
1 files changed, 193 insertions(+), 33 deletions(-)
diffs (truncated from 306 to 300 lines):
diff -r 7d73b50f8a81 -r cf5d9418f593 sys/lib/libsa/subr_prf.c
--- a/sys/lib/libsa/subr_prf.c Tue Jan 19 15:23:14 2010 +0000
+++ b/sys/lib/libsa/subr_prf.c Tue Jan 19 15:26:45 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_prf.c,v 1.16 2007/11/24 13:20:57 isaki Exp $ */
+/* $NetBSD: subr_prf.c,v 1.17 2010/01/19 15:26:45 tsutsui Exp $ */
/*-
* Copyright (c) 1993
@@ -42,7 +42,25 @@
#include "stand.h"
-static void kprintn(void (*)(int), u_long, int);
+#ifdef LIBSA_PRINTF_LONGLONG_SUPPORT
+#define INTMAX_T longlong_t
+#define UINTMAX_T u_longlong_t
+#else
+#define INTMAX_T long
+#define UINTMAX_T u_long
+#endif
+
+#if 0 /* XXX: abuse intptr_t until the situation with ptrdiff_t is clear */
+#define PTRDIFF_T ptrdiff_t
+#else
+#define PTRDIFF_T intptr_t
+#endif
+
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+static void kprintn(void (*)(int), UINTMAX_T, int, int, int);
+#else
+static void kprintn(void (*)(int), UINTMAX_T, int);
+#endif
static void sputchar(int);
static void kdoprnt(void (*)(int), const char *, va_list);
@@ -51,6 +69,65 @@
const char HEXDIGITS[] = "0123456789ABCDEF";
const char hexdigits[] = "0123456789abcdef";
+#define LONG 0x01
+#ifdef LIBSA_PRINTF_LONGLONG_SUPPORT
+#define LLONG 0x02
+#endif
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+#define ALT 0x04
+#define SPACE 0x08
+#define LADJUST 0x10
+#define SIGN 0x20
+#define ZEROPAD 0x40
+#define NEGATIVE 0x80
+#define KPRINTN(base) kprintn(put, ul, base, lflag, width)
+#define RZERO() \
+do { \
+ if ((lflag & (ZEROPAD|LADJUST)) == ZEROPAD) { \
+ while (width-- > 0) \
+ put('0'); \
+ } \
+} while (/*CONSTCOND*/0)
+#define RPAD() \
+do { \
+ if (lflag & LADJUST) { \
+ while (width-- > 0) \
+ put(' '); \
+ } \
+} while (/*CONSTCOND*/0)
+#define LPAD() \
+do { \
+ if ((lflag & (ZEROPAD|LADJUST)) == 0) { \
+ while (width-- > 0) \
+ put(' '); \
+ } \
+} while (/*CONSTCOND*/0)
+#else /* LIBSA_PRINTF_WIDTH_SUPPORT */
+#define KPRINTN(base) kprintn(put, ul, base)
+#define RZERO() /**/
+#define RPAD() /**/
+#define LPAD() /**/
+#endif /* LIBSA_PRINTF_WIDTH_SUPPORT */
+
+#ifdef LIBSA_PRINTF_LONGLONG_SUPPORT
+#define KPRINT(base) \
+do { \
+ ul = (lflag & LLONG) \
+ ? va_arg(ap, u_longlong_t) \
+ : (lflag & LONG) \
+ ? va_arg(ap, u_long) \
+ : va_arg(ap, u_int); \
+ KPRINTN(base); \
+} while (/*CONSTCOND*/0)
+#else /* LIBSA_PRINTF_LONGLONG_SUPPORT */
+#define KPRINT(base) \
+do { \
+ ul = (lflag & LONG) \
+ ? va_arg(ap, u_long) : va_arg(ap, u_int); \
+ KPRINTN(base); \
+} while (/*CONSTCOND*/0)
+#endif /* LIBSA_PRINTF_LONGLONG_SUPPORT */
+
static void
sputchar(int c)
{
@@ -82,8 +159,12 @@
{
char *p;
int ch;
- unsigned long ul;
+ UINTMAX_T ul;
int lflag;
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ int width;
+ char *q;
+#endif
for (;;) {
while ((ch = *fmt++) != '%') {
@@ -92,63 +173,110 @@
put(ch);
}
lflag = 0;
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ width = 0;
+#endif
reswitch:
switch (ch = *fmt++) {
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ case '#':
+ lflag |= ALT;
+ goto reswitch;
+ case ' ':
+ lflag |= SPACE;
+ goto reswitch;
+ case '-':
+ lflag |= LADJUST;
+ goto reswitch;
+ case '+':
+ lflag |= SIGN;
+ goto reswitch;
+ case '0':
+ lflag |= ZEROPAD;
+ goto reswitch;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ for (;;) {
+ width *= 10;
+ width += ch - '0';
+ ch = *fmt;
+ if ((unsigned)ch - '0' > 9)
+ break;
+ ++fmt;
+ }
+#endif
+ goto reswitch;
case 'l':
- lflag = 1;
+#ifdef LIBSA_PRINTF_LONGLONG_SUPPORT
+ if (*fmt == 'l') {
+ ++fmt;
+ lflag |= LLONG;
+ } else
+#endif
+ lflag |= LONG;
goto reswitch;
case 't':
-#if 0 /* XXX: abuse intptr_t until the situation with ptrdiff_t is clear */
- lflag = (sizeof(ptrdiff_t) == sizeof(long));
-#else
- lflag = (sizeof(intptr_t) == sizeof(long));
-#endif
+ if (sizeof(PTRDIFF_T) == sizeof(long))
+ lflag |= LONG;
goto reswitch;
case 'z':
- lflag = (sizeof(size_t) == sizeof(unsigned long));
+ if (sizeof(ssize_t) == sizeof(long))
+ lflag |= LONG;
goto reswitch;
case 'c':
ch = va_arg(ap, int);
- put(ch & 0x7f);
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ --width;
+#endif
+ RPAD();
+ put(ch & 0xFF);
+ LPAD();
break;
case 's':
p = va_arg(ap, char *);
- while ((ch = *p++))
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ for (q = p; *q; ++q);
+ width -= q - p;
+#endif
+ RPAD();
+ while ((ch = (unsigned char)*p++))
put(ch);
+ LPAD();
break;
case 'd':
- ul = lflag ?
- va_arg(ap, long) : va_arg(ap, int);
- if ((long)ul < 0) {
+ ul =
+#ifdef LIBSA_PRINTF_LONGLONG_SUPPORT
+ (lflag & LLONG) ? va_arg(ap, longlong_t) :
+#endif
+ (lflag & LONG) ? va_arg(ap, long) : va_arg(ap, int);
+ if ((INTMAX_T)ul < 0) {
+ ul = -(INTMAX_T)ul;
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ lflag |= NEGATIVE;
+#else
put('-');
- ul = -(long)ul;
+#endif
}
- kprintn(put, ul, 10);
+ KPRINTN(10);
break;
case 'o':
- ul = lflag ?
- va_arg(ap, u_long) : va_arg(ap, u_int);
- kprintn(put, ul, 8);
+ KPRINT(8);
break;
case 'u':
- ul = lflag ?
- va_arg(ap, u_long) : va_arg(ap, u_int);
- kprintn(put, ul, 10);
+ KPRINT(10);
break;
case 'p':
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ lflag |= (LONG|ALT);
+#else
put('0');
put('x');
- lflag = 1;
+#endif
/* FALLTHROUGH */
case 'x':
- ul = lflag ?
- va_arg(ap, u_long) : va_arg(ap, u_int);
- kprintn(put, ul, 16);
+ KPRINT(16);
break;
default:
- put('%');
- if (lflag)
- put('l');
if (ch == '\0')
return;
put(ch);
@@ -158,16 +286,48 @@
}
static void
-kprintn(void (*put)(int), unsigned long ul, int base)
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+kprintn(void (*put)(int), UINTMAX_T ul, int base, int lflag, int width)
+#else
+kprintn(void (*put)(int), UINTMAX_T ul, int base)
+#endif
{
- /* hold a long in base 8 */
- char *p, buf[(sizeof(long) * NBBY / 3) + 1];
+ /* hold a INTMAX_T in base 8 */
+ char *p, buf[(sizeof(INTMAX_T) * NBBY / 3) + 1 + 2 /* ALT + SIGN */];
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ char *q;
+#endif
p = buf;
do {
*p++ = hexdigits[ul % base];
} while (ul /= base);
+#ifdef LIBSA_PRINTF_WIDTH_SUPPORT
+ q = p;
+ if (lflag & ALT && *(p - 1) != '0') {
+ if (base == 8) {
+ *p++ = '0';
+ } else if (base == 16) {
+ *p++ = 'x';
+ *p++ = '0';
+ }
+ }
+ if (lflag & NEGATIVE)
+ *p++ = '-';
+ else if (lflag & SIGN)
+ *p++ = '+';
+ else if (lflag & SPACE)
+ *p++ = ' ';
+ width -= p - buf;
+ if ((lflag & LADJUST) == 0) {
+ while (p > q)
+ put(*--p);
+ }
+#endif
+ RPAD();
Home |
Main Index |
Thread Index |
Old Index