From b1196e326810c61785d269138afd63df740bfbd1 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 10 Mar 2014 08:13:06 +0100 Subject: 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 b1aceccbe9..68c7556793 100644 --- a/cpukit/libcsupport/src/vprintk.c +++ b/cpukit/libcsupport/src/vprintk.c @@ -31,7 +31,7 @@ #include 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 e81212d88b..8cbbd685c0 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 52ca4834c4..4b8130b75c 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 -- cgit v1.2.3