From a4c8bd5224002cd793f67dc5f232dcfce8c1be08 Mon Sep 17 00:00:00 2001 From: Quy Tonthat Date: Tue, 10 Nov 2015 03:40:35 +1100 Subject: [PATCH 1/2] Added 0 padded output to printf. Also removed the prefix 0x for hex output. For example, printf("0x%08x", 0x123) would produce previously 0x0x 123 now becomes 0x00000123 Signed-off-by: Quy Tonthat --- Sming/system/include/stringconversion.h | 1 + Sming/system/m_printf.cpp | 13 +++++++++---- Sming/system/stringconversion.cpp | 6 +++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Sming/system/include/stringconversion.h b/Sming/system/include/stringconversion.h index 14de860cdf..46e0bcde14 100644 --- a/Sming/system/include/stringconversion.h +++ b/Sming/system/include/stringconversion.h @@ -17,6 +17,7 @@ int atoi(const char *nptr); // Already implemented extern char* ltoa_w (long, char*, int, int width); extern char* ltoa (long, char*, int); +extern char* ultoa_wp(unsigned long val, char* buffer, unsigned int base, int width, char pad); extern char* ultoa_w(unsigned long val, char* buffer, unsigned int base, int width); extern char* ultoa(unsigned long val, char* buffer, unsigned int base); diff --git a/Sming/system/m_printf.cpp b/Sming/system/m_printf.cpp index bd5bc251db..7eccf2692a 100644 --- a/Sming/system/m_printf.cpp +++ b/Sming/system/m_printf.cpp @@ -64,6 +64,7 @@ int m_vsnprintf(char *buf, size_t maxLen, const char *fmt, va_list args) char *str; const char *s; int8_t precision, width; + char pad; char tempNum[24]; @@ -96,6 +97,7 @@ int m_vsnprintf(char *buf, size_t maxLen, const char *fmt, va_list args) //reset attributes to defaults precision = -1; width = 0; + pad = ' '; base = 10; do @@ -104,8 +106,13 @@ int m_vsnprintf(char *buf, size_t maxLen, const char *fmt, va_list args) while ('+' == *fmt || '-' == *fmt || '#' == *fmt || '*' == *fmt || 'l' == *fmt) fmt++; - if (is_digit(*fmt)) + if (is_digit(*fmt)) { + if (*fmt == '0') { + pad = '0'; + fmt++; + } width = skip_atoi(&fmt); + } if('.' == *fmt) { @@ -150,8 +157,6 @@ int m_vsnprintf(char *buf, size_t maxLen, const char *fmt, va_list args) case 'x': case 'X': - *str++ = '0'; - *str++ = 'x'; base = 16; break; @@ -181,7 +186,7 @@ int m_vsnprintf(char *buf, size_t maxLen, const char *fmt, va_list args) if (flags & SIGN) s = ltoa_w(va_arg(args, int), tempNum, base, width); else - s = ultoa_w(va_arg(args, unsigned int), tempNum, base, width); + s = ultoa_wp(va_arg(args, unsigned int), tempNum, base, width, pad); while (*s) *str++ = *s++; diff --git a/Sming/system/stringconversion.cpp b/Sming/system/stringconversion.cpp index 9ad865791d..55c56b224b 100644 --- a/Sming/system/stringconversion.cpp +++ b/Sming/system/stringconversion.cpp @@ -45,6 +45,10 @@ char* ultoa(unsigned long val, char* buffer, unsigned int base) } char* ultoa_w(unsigned long val, char* buffer, unsigned int base, int width) +{ + return ultoa_wp(val, buffer, base, 0, ' '); +} +char* ultoa_wp(unsigned long val, char* buffer, unsigned int base, int width, char pad) { int i = 34, p = 0; char buf[36] = {0}; @@ -58,7 +62,7 @@ char* ultoa_w(unsigned long val, char* buffer, unsigned int base, int width) width -= strlen(&buf[i+1]); if(width > 0) { - memset(buffer, ' ', width); + memset(buffer, pad, width); } } strcpy(buffer + width, &buf[i+1]); From a7df0790a762b815d9efcbecc280e4c1d79f579b Mon Sep 17 00:00:00 2001 From: Quy Tonthat Date: Tue, 10 Nov 2015 12:43:31 +1100 Subject: [PATCH 2/2] Update serial examples to latest changes in printf. Using the optional printf flag '#' (as in "%#x") in the examples is some what misleading. The old code simply ignores the flag and always adds prefix "0x" regardless, which is against the C printf standard (and looks pretty ugly in some cases). The new code also ignores the flag, but does not add the 0x prefix The '#' example is left there, with a note. That hopefully makes it serve as a feature (a reminder of a minor missing feature) rather than a bug. Signed-off-by: Quy Tonthat --- Basic_Serial/app/application.cpp | 3 +++ Basic_Serial/printf_test_output.txt | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Basic_Serial/app/application.cpp b/Basic_Serial/app/application.cpp index 97d2797b74..3e0ded5d52 100644 --- a/Basic_Serial/app/application.cpp +++ b/Basic_Serial/app/application.cpp @@ -31,8 +31,11 @@ void testPrintf() "wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, " \ "wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, got to the end :)\n"); + // Note that the leading '#' (as in %#x) is currently ignored Serial.printf("\nShow a decimal %d, a hex %#x, an unsigned %u, an octal %o.\n", 123456, 0x00C0FFEE, 250, 06675); + Serial.printf("Field width is supported: [%8d], with optional zero-padding: 0x%08x\n", + 123456, 0xC0FFEE); Serial.printf("\nPrint pretty table\n"); diff --git a/Basic_Serial/printf_test_output.txt b/Basic_Serial/printf_test_output.txt index 439813905f..e5888612d5 100644 --- a/Basic_Serial/printf_test_output.txt +++ b/Basic_Serial/printf_test_output.txt @@ -6,7 +6,9 @@ Pi without specifying precision(default 9): 3.141592654 A number with leading fraction zeroes like 1.050250=1.05025 Test crazy line lengths: wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait f or it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, wait for it, got to the end :) -Show a decimal 123456, a hex 0xc0ffee, an unsigned 250, an octal 6675. + +Show a decimal 123456, a hex c0ffee, an unsigned 250, an octal 6675. +Field width is supported: [ 123456], with optional zero-padding: 0x00c0ffee Print pretty table LENGTH WIDTH HEIGHT