From 8e86162be59d999b35a5d8664bee22ceda5b75a8 Mon Sep 17 00:00:00 2001 From: Jon Griffiths Date: Sun, 13 Jul 2008 10:35:37 -0700 Subject: [PATCH] msvcrt: Fix exponents in *printf family. --- dlls/msvcrt/tests/printf.c | 26 +++++++++++++++-------- dlls/msvcrt/wcs.c | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/dlls/msvcrt/tests/printf.c b/dlls/msvcrt/tests/printf.c index 846b8443104..d7abacd966d 100644 --- a/dlls/msvcrt/tests/printf.c +++ b/dlls/msvcrt/tests/printf.c @@ -39,11 +39,24 @@ static void test_sprintf( void ) format = "%+#23.15e"; r = sprintf(buffer,format,pnumber); - todo_wine { - ok(!strcmp(buffer,"+7.894561230000000e+008"),"exponent format incorrect\n"); - } + ok(!strcmp(buffer,"+7.894561230000000e+008"),"+#23.15e failed: '%s'\n", buffer); ok( r==23, "return count wrong\n"); + format = "%-#23.15e"; + r = sprintf(buffer,format,pnumber); + ok(!strcmp(buffer,"7.894561230000000e+008 "),"-#23.15e failed: '%s'\n", buffer); + ok( r==23, "return count wrong\n"); + + format = "%#23.15e"; + r = sprintf(buffer,format,pnumber); + ok(!strcmp(buffer," 7.894561230000000e+008"),"#23.15e failed: '%s'\n", buffer); + ok( r==23, "return count wrong\n"); + + format = "%#1.1g"; + r = sprintf(buffer,format,pnumber); + ok(!strcmp(buffer,"8.e+008"),"#1.1g failed: '%s'\n", buffer); + ok( r==7, "return count wrong\n"); + format = "%I64d"; r = sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); ok(!strcmp(buffer,"-8589934591"),"Problem with long long\n"); @@ -401,12 +414,10 @@ static void test_sprintf( void ) ok(!strcmp(buffer,"1"), "failed\n"); ok( r==1, "return count wrong\n"); - todo_wine { format = "%2.4e"; r = sprintf(buffer, format,8.6); ok(!strcmp(buffer,"8.6000e+000"), "failed\n"); ok( r==11, "return count wrong\n"); - } format = "%2.4g"; r = sprintf(buffer, format,8.6); @@ -507,10 +518,7 @@ static void test_swprintf( void ) const wchar_t hs[] = {'%', 'h', 's', 0}; swprintf(buffer,TwentyThreePoint15e,pnumber); - todo_wine - { - ok(wcsstr(buffer,e008) != 0,"Sprintf different\n"); - } + ok(wcsstr(buffer,e008) != 0,"Sprintf different\n"); swprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff); ok(wcslen(buffer) == 11,"Problem with long long\n"); swprintf(buffer,S,string); diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 14daf90ca3c..8eccb39552b 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -481,6 +481,45 @@ static void pf_integer_conv( char *buf, int buf_len, pf_flags *flags, return; } +/* pf_fixup_exponent: convert a string containing a 2 digit exponent + to 3 digits, accounting for padding, in place. Needed to match + the native printf's which always use 3 digits. */ +static void pf_fixup_exponent( char *buf ) +{ + char* tmp = buf; + + while (tmp[0] && toupper(tmp[0]) != 'E') + tmp++; + + if (tmp[0] && (tmp[1] == '+' || tmp[1] == '-') && + isdigit(tmp[2]) && isdigit(tmp[3])) + { + char final; + + if (isdigit(tmp[4])) + return; /* Exponent already 3 digits */ + + /* We have a 2 digit exponent. Prepend '0' to make it 3 */ + tmp += 2; + final = tmp[2]; + tmp[2] = tmp[1]; + tmp[1] = tmp[0]; + tmp[0] = '0'; + if (final == '\0') + { + /* We didn't expand into trailing space, so this string isn't left + * justified. Terminate the string and strip a ' ' at the start of + * the string if there is one (as there may be if the string is + * right justified). + */ + tmp[3] = '\0'; + if (buf[0] == ' ') + memmove(buf, buf + 1, (tmp - buf) + 3); + } + /* Otherwise, we expanded into trailing space -> nothing to do */ + } +} + /********************************************************************* * pf_vsnprintf (INTERNAL) * @@ -693,7 +732,11 @@ static int pf_vsnprintf( pf_output *out, const WCHAR *format, va_list valist ) pf_rebuild_format_string( fmt, &flags ); if( pf_is_double_format( flags.Format ) ) + { sprintf( x, fmt, va_arg(valist, double) ); + if (toupper(flags.Format) == 'E' || toupper(flags.Format) == 'G') + pf_fixup_exponent( x ); + } else sprintf( x, fmt, va_arg(valist, int) );