[rtems commit] printk: Add support for long long

Sebastian Huber sebh at rtems.org
Tue Mar 11 09:57:00 UTC 2014


Module:    rtems
Branch:    master
Commit:    b1196e326810c61785d269138afd63df740bfbd1
Changeset: http://git.rtems.org/rtems/commit/?id=b1196e326810c61785d269138afd63df740bfbd1

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Mar 10 08:13:06 2014 +0100

printk: Add support for long long

---

 cpukit/libcsupport/src/vprintk.c         |   85 +++++++++++++++++++-----------
 testsuites/sptests/spprintk/init.c       |   29 ++++++++++
 testsuites/sptests/spprintk/spprintk.scn |   20 +++++++
 3 files changed, 104 insertions(+), 30 deletions(-)

diff --git a/cpukit/libcsupport/src/vprintk.c b/cpukit/libcsupport/src/vprintk.c
index b1acecc..68c7556 100644
--- a/cpukit/libcsupport/src/vprintk.c
+++ b/cpukit/libcsupport/src/vprintk.c
@@ -31,7 +31,7 @@
 #include <rtems/bspIo.h>
 
 static void printNum(
-  long num,
+  long long num,
   unsigned base,
   bool sign,
   unsigned maxwidth,
@@ -53,41 +53,57 @@ void vprintk(
   for (; *fmt != '\0'; fmt++) {
     unsigned base = 0;
     unsigned width = 0;
-    bool lflag = false;
+    enum {
+      LFLAG_INT,
+      LFLAG_LONG,
+      LFLAG_LONG_LONG
+    } lflag = LFLAG_INT;
     bool minus = false;
     bool sign = false;
     char lead = ' ';
-    char c;
+    char c = *fmt;
+    long long num;
 
-    if (*fmt != '%') {
-      rtems_putc(*fmt);
+    if (c != '%') {
+      rtems_putc(c);
       continue;
     }
-    fmt++;
-    if (*fmt == '0' ) {
+
+    ++fmt; c = *fmt;
+
+    if (c == '0') {
       lead = '0';
-      fmt++;
+      ++fmt; c = *fmt;
     }
-    if (*fmt == '-' ) {
+
+    if (c == '-') {
       minus = true;
-      fmt++;
+      ++fmt; c = *fmt;
     }
-    while (*fmt >= '0' && *fmt <= '9' ) {
+
+    while (c >= '0' && c <= '9' ) {
       width *= 10;
-      width += ((unsigned) *fmt - '0');
-      fmt++;
+      width += ((unsigned) c - '0');
+      ++fmt; c = *fmt;
     }
 
-    if ((c = *fmt) == 'l') {
-      lflag = true;
-      c = *++fmt;
+    if (c == 'l') {
+      lflag = LFLAG_LONG;
+      ++fmt; c = *fmt;
+
+      if (c == 'l') {
+        lflag = LFLAG_LONG_LONG;
+        ++fmt; c = *fmt;
+      }
     }
+
     if ( c == 'c' ) {
       /* need a cast here since va_arg() only takes fully promoted types */
       char chr = (char) va_arg(ap, int);
       rtems_putc(chr);
       continue;
     }
+
     if ( c == 's' ) {
       unsigned i, len;
       char *s, *str;
@@ -135,19 +151,27 @@ void vprintk(
     } else if ( c == 'x' || c == 'X' ) {
       base = 16; sign = false;
     } else if ( c == 'p' ) {
-      base = 16; sign = false; lflag = true;
+      base = 16; sign = false; lflag = LFLAG_LONG;
     } else {
       rtems_putc(c);
       continue;
     }
 
-    printNum(
-      lflag ? va_arg(ap, long) : (long) va_arg(ap, int),
-      base,
-      sign,
-      width,
-      lead
-    );
+    switch (lflag) {
+      case LFLAG_INT:
+        num = sign ? (long long) va_arg(ap, int)
+          : (long long) va_arg(ap, unsigned int);
+        break;
+      case LFLAG_LONG:
+        num = sign ? (long long) va_arg(ap, long)
+          : (long long) va_arg(ap, unsigned long);
+        break;
+      case LFLAG_LONG_LONG:
+        num = va_arg(ap, long long);
+        break;
+    }
+
+    printNum(num, base, sign, width, lead);
   }
 }
 
@@ -157,24 +181,25 @@ void vprintk(
  *  @param[in] base is the base used to print the number
  */
 static void printNum(
-  long num,
+  long long num,
   unsigned base,
   bool sign,
   unsigned maxwidth,
   char lead
 )
 {
-  unsigned long unsigned_num;
-  unsigned long n;
+  unsigned long long unsigned_num;
+  unsigned long long n;
   unsigned count;
-  char toPrint[20];
+  #define UINT64_MAX_IN_OCTAL_FORMAT "1777777777777777777777"
+  char toPrint[sizeof(UINT64_MAX_IN_OCTAL_FORMAT)];
 
   if ( sign && (num <  0) ) {
     rtems_putc('-');
-    unsigned_num = (unsigned long) -num;
+    unsigned_num = (unsigned long long) -num;
     if (maxwidth) maxwidth--;
   } else {
-    unsigned_num = (unsigned long) num;
+    unsigned_num = (unsigned long long) num;
   }
 
   count = 0;
diff --git a/testsuites/sptests/spprintk/init.c b/testsuites/sptests/spprintk/init.c
index e81212d..8cbbd68 100644
--- a/testsuites/sptests/spprintk/init.c
+++ b/testsuites/sptests/spprintk/init.c
@@ -56,6 +56,11 @@ void do_putk(void)
 
 void do_printk(void)
 {
+  long lm = 2147483647L;
+  unsigned long ulm = 4294967295UL;
+  long long llm = 9223372036854775807LL;
+  long long ullm = 18446744073709551615ULL;
+
   printk( "bad format -- %%q in parentheses (%q)\n" );
 
   printk( "bad format -- %%lq in parentheses (%lq)\n", 0x1234 );
@@ -73,6 +78,30 @@ void do_printk(void)
   printk( "%%x of 16 -- %x\n", 16 );
   printk( "%%p of 0x1234 -- %p\n", (void *)0x1234 );
 
+  /* long */
+  printk( "%%lo of 2147483647 -- %lo\n", lm );
+  printk( "%%li of 2147483647 -- %li\n", lm );
+  printk( "%%lu of 2147483647 -- %lu\n", lm );
+  printk( "%%lx of 2147483647 -- %lx\n", lm );
+  printk( "%%lo of -2147483648 -- %lo\n", -lm - 1L );
+  printk( "%%li of -2147483648 -- %li\n", -lm - 1L );
+  printk( "%%lx of -2147483648 -- %lx\n", -lm - 1L );
+  printk( "%%lo of 4294967295 -- %lo\n", ulm );
+  printk( "%%lu of 4294967295 -- %lu\n", ulm );
+  printk( "%%lx of 4294967295 -- %lx\n", ulm );
+
+  /* long long */
+  printk( "%%llo of 9223372036854775807 -- %llo\n", llm );
+  printk( "%%lli of 9223372036854775807 -- %lli\n", llm );
+  printk( "%%llu of 9223372036854775807 -- %llu\n", llm );
+  printk( "%%llx of 9223372036854775807 -- %llx\n", llm );
+  printk( "%%llo of -9223372036854775808 -- %llo\n", -llm - 1LL );
+  printk( "%%lli of -9223372036854775808 -- %lli\n", -llm - 1LL );
+  printk( "%%llx of -9223372036854775808 -- %llx\n", -llm - 1LL );
+  printk( "%%llo of 18446744073709551615 -- %llo\n", ullm );
+  printk( "%%llu of 18446744073709551615 -- %llu\n", ullm );
+  printk( "%%llx of 18446744073709551615 -- %llx\n", ullm );
+
   /* negative numbers */
   printk( "%%d of -16 -- %d\n", -16 );
   printk( "%%d of -16 -- %-3d\n", -16 );
diff --git a/testsuites/sptests/spprintk/spprintk.scn b/testsuites/sptests/spprintk/spprintk.scn
index 52ca483..4b8130b 100644
--- a/testsuites/sptests/spprintk/spprintk.scn
+++ b/testsuites/sptests/spprintk/spprintk.scn
@@ -15,6 +15,26 @@ bad format -- %lq in parentheses (q)
 %X of 16 -- 10
 %x of 16 -- 10
 %p of 0x1234 -- 1234
+%lo of 2147483647 -- 17777777777
+%li of 2147483647 -- 2147483647
+%lu of 2147483647 -- 2147483647
+%lx of 2147483647 -- 7FFFFFFF
+%lo of -2147483648 -- 20000000000
+%li of -2147483648 -- -2147483648
+%lx of -2147483648 -- 80000000
+%lo of 4294967295 -- 37777777777
+%lu of 4294967295 -- 4294967295
+%lx of 4294967295 -- FFFFFFFF
+%llo of 9223372036854775807 -- 777777777777777777777
+%lli of 9223372036854775807 -- 9223372036854775807
+%llu of 9223372036854775807 -- 9223372036854775807
+%llx of 9223372036854775807 -- 7FFFFFFFFFFFFFFF
+%llo of -9223372036854775808 -- 1000000000000000000000
+%lli of -9223372036854775808 -- -9223372036854775808
+%llx of -9223372036854775808 -- 8000000000000000
+%llo of 18446744073709551615 -- 1777777777777777777777
+%llu of 18446744073709551615 -- 18446744073709551615
+%llx of 18446744073709551615 -- FFFFFFFFFFFFFFFF
 %d of -16 -- -16
 %d of -16 -- -16
 %u of -16 -- 4294967280




More information about the vc mailing list