From f3d92faffa4e4199f65bc655d2a399484c88301c Mon Sep 17 00:00:00 2001 From: borutr Date: Sun, 25 Jun 2006 12:22:18 +0000 Subject: [PATCH] * device/lib/pic16/libc/stdio/sprintf.c: return the number of characters printed (not including the trailing '\0' used to end output to strings). Problem detected in regression test bug-927659.c. NOTE: printf() family functions should return int instead unsigned int! * device/lib/pic16/libc/stdio/vfprintf.c: "%%" prints "%", unknown specifier are printed as themselves * sdcc/support/regression/tests/bug1057979.c: pic16 printf doesn't support flags, width and precision specifiers git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4249 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 12 ++ device/lib/pic16/libc/stdio/sprintf.c | 2 +- device/lib/pic16/libc/stdio/vfprintf.c | 182 +++++++++++++------------ support/regression/tests/bug1057979.c | 17 ++- 4 files changed, 127 insertions(+), 86 deletions(-) diff --git a/ChangeLog b/ChangeLog index a91877cf..7d2d2df6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-06-25 Borut Razem + + * device/lib/pic16/libc/stdio/sprintf.c: return the number of + characters printed (not including the trailing '\0' used to end + output to strings). Problem detected in regression test bug-927659.c. + NOTE: printf() family functions should return int instead + unsigned int! + * device/lib/pic16/libc/stdio/vfprintf.c: "%%" prints "%", unknown + specifier are printed as themselves + * sdcc/support/regression/tests/bug1057979.c: pic16 printf doesn't + support flags, width and precision specifiers + 2006-06-24 Borut Razem * sdcc/support/regression/tests/bitvars.c: added gbz80, pic16 and pic16 diff --git a/device/lib/pic16/libc/stdio/sprintf.c b/device/lib/pic16/libc/stdio/sprintf.c index 548c531a..be9dee40 100644 --- a/device/lib/pic16/libc/stdio/sprintf.c +++ b/device/lib/pic16/libc/stdio/sprintf.c @@ -42,5 +42,5 @@ unsigned int sprintf(char *ebuf, char *fmt, ...) i = vfprintf((FILE *) &ebuf, cfmt, ap); *ebuf='\0'; - return (i+1); + return (i); } diff --git a/device/lib/pic16/libc/stdio/vfprintf.c b/device/lib/pic16/libc/stdio/vfprintf.c index 19327ad1..706d9704 100644 --- a/device/lib/pic16/libc/stdio/vfprintf.c +++ b/device/lib/pic16/libc/stdio/vfprintf.c @@ -30,14 +30,17 @@ /* following formats are supported :- format output type argument-type + %% - - %u* unsigned * - %b binary + %b binary int + %lb binary long + %hb binary char %d decimal int %ld decimal long %hd decimal char - %x hexadecimal int - %lxX hexadecimal long - %hxX hexadecimal char + %[xX] hexadecimal int + %l[xX] hexadecimal long + %h[xX] hexadecimal char %o octal int %lo octal long %ho octal char @@ -71,98 +74,109 @@ unsigned int vfprintf(FILE *stream, char *fmt, va_list ap) #if _DEBUG - io_str( "vfprintf: " ); - io_long( (unsigned long)stream ); - io_long( (unsigned long)fmt ); + io_str( "vfprintf: " ); + io_long( (unsigned long)stream ); + io_long( (unsigned long)fmt ); #endif // va_start(ap,fmt); - ch = fmt; + ch = fmt; - while( *ch ) { //for (; *fmt ; fmt++ ) - if (*ch == '%') { - flong = 0; - fstr = 0; - fchar = 0; - nosign = 0; - radix = 0; - upcase = 0; - ch++; - - if(*ch == 'u') { - nosign = 1; - ch++; - } - - if(*ch == 'l') { - flong = 1; - ch++; - } else - if(*ch == 'h') { - fchar = 1; - ch++; - } - - if(*ch == 's')fstr = 1; - else if(*ch == 'd')radix = 10; - else if(*ch == 'x'){ radix = 16; upcase = 0; } - else if(*ch == 'X'){ radix = 16; upcase = 1; } - else if(*ch == 'c')radix = 0; - else if(*ch == 'o')radix = 8; - else if(*ch == 'b')radix = 2; - - if(fstr) { - str = va_arg(ap, char *); - while(*str) { __stream_putchar(stream, *str); str++; count++; } - } else { - val = 0; - if(flong) { - val = va_arg(ap, long); + while( *ch ) { //for (; *fmt ; fmt++ ) + if (*ch == '%') { + flong = 0; + fstr = 0; + fchar = 0; + nosign = 0; + radix = 0; + upcase = 0; + ch++; + + if(*ch == '%') { + __stream_putchar(stream, *ch); + ++count; + ++ch; + continue; + } + + if(*ch == 'u') { + nosign = 1; + ch++; + } + + if(*ch == 'l') { + flong = 1; + ch++; + } else if(*ch == 'h') { + fchar = 1; + ch++; + } + + if(*ch == 's')fstr = 1; + else if(*ch == 'd')radix = 10; + else if(*ch == 'x'){ radix = 16; upcase = 0; } + else if(*ch == 'X'){ radix = 16; upcase = 1; } + else if(*ch == 'c')radix = 0; + else if(*ch == 'o')radix = 8; + else if(*ch == 'b')radix = 2; + else { + __stream_putchar(stream, *ch); + ++count; + ++ch; + continue; + } + + if(fstr) { + str = va_arg(ap, char *); + while(*str) { __stream_putchar(stream, *str); str++; count++; } + } else { + val = 0; + if(flong) { + val = va_arg(ap, long); #if _DEBUG - io_long(val); + io_long(val); #endif - } - else - if(fchar) { - val = va_arg(ap, char); + } + else if(fchar) { + val = va_arg(ap, char); #if _DEBUG - io_long(val); + io_long(val); #endif - } - else { - val = va_arg(ap, int); + } + else { + val = va_arg(ap, int); #if _DEBUG - io_long(val); + io_long(val); #endif - } - - if(radix) { - if(nosign) - ultoa(val, buffer, radix); - else - ltoa (val, buffer, radix); - - str1 = buffer; - while( (*str1) ) { - radix = *str1; - if(upcase) - radix = toupper( radix ); - __stream_putchar(stream, (unsigned char)radix); - count++; - str1++; - } - } else { - __stream_putchar(stream, (unsigned char)val); - count++; - } - } - } else { - __stream_putchar(stream, *ch); + } + + if(radix) { + if(nosign) + ultoa(val, buffer, radix); + else + ltoa (val, buffer, radix); + + str1 = buffer; + while( (*str1) ) { + radix = *str1; + if(upcase) + radix = toupper( radix ); + __stream_putchar(stream, (unsigned char)radix); count++; + str1++; } - - ch++; + } else { + __stream_putchar(stream, (unsigned char)val); + count++; + } + } + } else { + __stream_putchar(stream, *ch); + count++; } - + + ch++; + } + return (count); } diff --git a/support/regression/tests/bug1057979.c b/support/regression/tests/bug1057979.c index 68882498..392b0ccd 100644 --- a/support/regression/tests/bug1057979.c +++ b/support/regression/tests/bug1057979.c @@ -24,12 +24,26 @@ test_sprintf(void) ASSERT( 0 == strcmp( s, "2147483647" ) ); //and from bug 1073386 +#ifdef SDCC_pic16 + //pic16 printf doesn't support flags, width and precision specifiers + sprintf( s, "%04X", 0x8765u ); + ASSERT( 0 == strcmp( s, "04X" ) ); + + //and from bug 1193299 + sprintf( s, "%3.3s", "abcd" ); + ASSERT( 0 == strcmp( s, "3.3s" ) ); + sprintf( s, "%-3.3s", "abcd" ); + ASSERT( 0 == strcmp( s, "-3.3s" ) ); + sprintf( s, "%3.3s", "ab" ); + ASSERT( 0 == strcmp( s, "3.3s" ) ); + sprintf( s, "%-3.3s", "ab" ); + ASSERT( 0 == strcmp( s, "-3.3s" ) ); +#else sprintf( s, "%04X", 0x8765u ); ASSERT( 0 == strcmp( s, "8765" ) ); //and from bug 1193299 sprintf( s, "%3.3s", "abcd" ); - LOG((s)); ASSERT( 0 == strcmp( s, "abc" ) ); sprintf( s, "%-3.3s", "abcd" ); ASSERT( 0 == strcmp( s, "abc" ) ); @@ -37,6 +51,7 @@ test_sprintf(void) ASSERT( 0 == strcmp( s, " ab" ) ); sprintf( s, "%-3.3s", "ab" ); ASSERT( 0 == strcmp( s, "ab " ) ); +#endif #if defined(SDCC__ds390) || defined(PORT_HOST) //and from bug 1358192 -- 2.47.2