On Wednesday 09 November 2005 02:15, Raphael wrote: > Hi, > > Changelog: > - add I64 modifier support on msvcrt *printf functions > - correct ll modifier support on msvcrt *printf functions > - correct tests > > this should correct bug 3759 and 2075 (and many others) > > Now for libc who don't support %ll modifiers (which one?) > Jesse Allen provide the patch (see bug 2075 content) > > Regards, > Raphael
better patch than previous: now Jesse can put his code into #else / #endif :) Changelog: - add configure check to detect support of %ll modifier on libc printf - add I64 modifier support on msvcrt *printf functions - add I32 modifier support on msvcrt *printf functions - correct ll and LL modifier support on msvcrt *printf functions - some FIXMEs on unsupported cases - correct tests Regards, Raphael
Index: configure.ac =================================================================== RCS file: /home/wine/wine/configure.ac,v retrieving revision 1.412 diff -u -r1.412 configure.ac --- configure.ac 31 Oct 2005 21:10:38 -0000 1.412 +++ configure.ac 14 Nov 2005 22:47:30 -0000 @@ -1244,6 +1244,31 @@ AC_CHECK_TYPES([sigset_t],,,[#include <signal.h>]) AC_CHECK_TYPES([request_sense],,,[#include <linux/cdrom.h>]) +if test "$ac_cv_type_long_long" = "yes" +then + dnl Check for %ll + AC_CACHE_CHECK( [printf format %ll support], wine_cv_libc_printf_ll_support, + AC_TRY_RUN([ +#include <stdio.h> +#include <assert.h> +int main(void) { + char buffer[[48]]; + long long test64 = 1U; + test64 <<= 30; + int r = sprintf(buffer, "%lld", test64 * test64); + assert( 15 < r ); + return( 0 == strcmp(buffer, "1152921504606846976") ); +}], + wine_cv_libc_printf_ll_support="no", + wine_cv_libc_printf_ll_support="yes", + wine_cv_libc_printf_ll_support="yes") ) + + if test "$wine_cv_libc_printf_ll_support" = "yes" + then + AC_DEFINE(HAVE_PRINTF_FORMAT_LL_SUPPORT, 1, [Define to 1 if printf functions support %ll format]) + fi +fi + AC_CHECK_MEMBERS([struct ff_effect.direction],,, [#ifdef HAVE_LINUX_INPUT_H #include <linux/input.h> @@ -1717,6 +1742,7 @@ dlls/wsock32/Makefile dlls/wtsapi32/Makefile dlls/x11drv/Makefile +dlls/hal/Makefile documentation/Makefile fonts/Makefile include/Makefile Index: dlls/msvcrt/wcs.c =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/wcs.c,v retrieving revision 1.27 diff -u -r1.27 wcs.c --- dlls/msvcrt/wcs.c 28 Oct 2005 09:40:16 -0000 1.27 +++ dlls/msvcrt/wcs.c 14 Nov 2005 22:47:30 -0000 @@ -22,6 +22,7 @@ #include <stdio.h> #include <math.h> #include <assert.h> +#include "config.h" #include "msvcrt.h" #include "winnls.h" #include "wine/unicode.h" @@ -374,6 +375,20 @@ *p++ = flags->Alternate; if( flags->PadZero ) *p++ = flags->PadZero; + if( flags->IntegerDouble ) { + if( 'l' == flags->IntegerLength || 'L' == flags->IntegerLength ) { +#if defined( HAVE_PRINTF_FORMAT_LL_SUPPORT ) + sprintf(p, "ll"); + p += 2; +#else + FIXME( "Your platform don't seems to support %%ll format modifier on sprintf. Expect problems\n" ); + sprintf(p, "l"); + p++; +#endif + } else { + FIXME( "Unsupported %%%c%c format modifier on sprintf. Expect problems\n", flags->IntegerLength, flags->IntegerLength ); + } + } if( flags->FieldLength ) { sprintf(p, "%d", flags->FieldLength); @@ -398,6 +413,8 @@ int r; LPCWSTR q, p = format; pf_flags flags; + static const WCHAR sz_I32[] = {'I','3','2',0}; + static const WCHAR sz_I64[] = {'I','6','4',0}; TRACE("format is %s\n",debugstr_w(format)); while (*p) @@ -485,11 +502,19 @@ } /* deal with integer width modifier */ + flags.IntegerLength = 0; + flags.IntegerDouble = 0; while( *p ) { if( *p == 'h' || *p == 'l' || *p == 'L' ) { - if( flags.IntegerLength == *p ) /* FIXME: this is wrong */ + /* + * @FIXME: this is wrong ? + * + * %hh don't seems to be supported by MS + * %LL <=> %ll ? + */ + if( flags.IntegerLength == *p && *p != 'h' ) flags.IntegerDouble++; else flags.IntegerLength = *p; @@ -499,6 +524,17 @@ flags.WideString = *p++; else if( *p == 'F' ) p++; /* ignore */ + else if( !strncmpW( p, sz_I64, 3 ) ) + { + flags.IntegerLength = 'l'; + flags.IntegerDouble++; + p += 3; + } + else if( !strncmpW( p, sz_I32, 3 ) ) + { + flags.IntegerLength = 'l'; + p += 3; + } else break; } @@ -583,9 +619,12 @@ pf_rebuild_format_string( fmt, &flags ); if( pf_is_double_format( flags.Format ) ) - sprintf( x, fmt, va_arg(valist, double) ); + sprintf( x, fmt, va_arg(valist, double) ); + else if( flags.IntegerDouble && 'l' == flags.IntegerLength ) + sprintf( x, fmt, va_arg(valist, long long) ); else sprintf( x, fmt, va_arg(valist, int) ); + TRACE("used fmt(%s) on sprintf\n", fmt ); r = pf_output_stringA( out, x, -1 ); if( x != number ) Index: dlls/msvcrt/tests/printf.c =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/tests/printf.c,v retrieving revision 1.8 diff -u -r1.8 printf.c --- dlls/msvcrt/tests/printf.c 27 Oct 2005 12:25:18 -0000 1.8 +++ dlls/msvcrt/tests/printf.c 14 Nov 2005 22:47:30 -0000 @@ -29,6 +29,7 @@ char buffer[100]; const char *format; double pnumber=789456123; + ULONGLONG test_i64; int x, r; WCHAR wide[] = { 'w','i','d','e',0}; @@ -39,17 +40,21 @@ } ok( r==23, "return count wrong\n"); - todo_wine { format = "%I64d"; - r = sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); - ok(!strcmp(buffer,"-8589934591"),"Problem with long long\n"); + test_i64 = 1U; + r = sprintf(buffer,format,test_i64 << 34); + trace("I64: found res as '%s' (%d)\n", buffer, r); + ok(!strcmp(buffer,"17179869184"),"Problem with \"I64\" interpretation\n"); ok( r==11, "return count wrong\n"); - } format = "%lld"; - r = sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); - ok(!strcmp(buffer, "1"), "Problem with \"ll\" interpretation\n"); - ok( r==1, "return count wrong\n"); + /** ((1 << 30) ^ 2) -> 2 ^ 60 ) */ + test_i64 = 1U; + test_i64 <<= 30; + r = sprintf(buffer,format,test_i64 * test_i64); + trace("lld: found res as '%s' (%d)\n", buffer, r); + ok(!strcmp(buffer, "1152921504606846976"), "Problem with \"ll\" interpretation\n"); + ok( r==19, "return count wrong\n"); format = "%S"; r = sprintf(buffer,format,wide); @@ -295,18 +300,16 @@ const wchar_t e008[] = {'e','+','0','0','8',0}; const char string[]={'s','t','r','i','n','g',0}; const wchar_t S[]={'%','S',0}; + const ULONGLONG test_ll = 0xffffffff; swprintf(buffer,TwentyThreePoint15e,pnumber); todo_wine { ok(wcsstr(buffer,e008) != 0,"Sprintf different\n"); } - swprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff); - todo_wine - { - ok(wcslen(buffer) == 11,"Problem with long long\n"); - } + swprintf(buffer,I64d, test_ll * test_ll); + ok(wcslen(buffer) == 11,"Problem with long long\n"); swprintf(buffer,S,string); - ok(wcslen(buffer) == 6,"Problem with \"%%S\" interpretation\n"); + ok(wcslen(buffer) == 6,"Problem with \"%%S\" interpretation\n"); } static void test_fwprintf( void ) Index: include/config.h.in =================================================================== RCS file: /home/wine/wine/include/config.h.in,v retrieving revision 1.234 diff -u -r1.234 config.h.in --- include/config.h.in 15 Sep 2005 09:39:09 -0000 1.234 +++ include/config.h.in 14 Nov 2005 22:47:30 -0000 @@ -449,6 +449,9 @@ /* Define to 1 if you have the `pread' function. */ #undef HAVE_PREAD +/* Define to 1 if printf functions support %ll format */ +#undef HAVE_PRINTF_FORMAT_LL_SUPPORT + /* Define to 1 if you have the <process.h> header file. */ #undef HAVE_PROCESS_H
pgpynv6UaOcGn.pgp
Description: PGP signature