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