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
 

Attachment: pgpynv6UaOcGn.pgp
Description: PGP signature



Reply via email to