Jesse Allen : msvcrt: pf_integer_conv for I64.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Dec 26 11:46:15 CST 2005


Module: wine
Branch: refs/heads/master
Commit: 419d493aacd808ebc0a1abfe8d760b5b4aed93d6
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=419d493aacd808ebc0a1abfe8d760b5b4aed93d6

Author: Jesse Allen <the3dfxdude at gmail.com>
Date:   Mon Dec 26 13:01:38 2005 +0100

msvcrt: pf_integer_conv for I64.
- Add pf_integer_conv and pf_is_integer_format.
- Update pf_fill to handle printing the sign for signed integers.
- Handle I64 integer sizes using pf_integer_conv and pf_output_format_A.

---

 dlls/msvcrt/wcs.c |  100 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c
index 503a998..db86437 100644
--- a/dlls/msvcrt/wcs.c
+++ b/dlls/msvcrt/wcs.c
@@ -285,6 +285,16 @@ static inline int pf_fill( pf_output *ou
 {
     int i, r = 0;
 
+    if( flags->Sign && !( flags->Format == 'd' || flags->Format == 'i' ) )
+        flags->Sign = 0;
+
+    if( left && flags->Sign )
+    {
+        flags->FieldLength--;
+        if( flags->PadZero )
+            r = pf_output_stringA( out, &flags->Sign, 1 );
+    }
+
     if( ( !left &&  flags->LeftAlign ) || 
         (  left && !flags->LeftAlign ))
     {
@@ -297,6 +307,9 @@ static inline int pf_fill( pf_output *ou
         }
     }
 
+    if( left && flags->Sign && !flags->PadZero )
+        r = pf_output_stringA( out, &flags->Sign, 1 );
+
     return r;
 }
 
@@ -344,6 +357,14 @@ static inline int pf_output_format_A( pf
     return r;
 }
 
+static inline BOOL pf_is_integer_format( char fmt )
+{
+    static const char float_fmts[] = "diouxX";
+    if (!fmt)
+        return FALSE;
+    return strchr( float_fmts, fmt ) ? TRUE : FALSE;
+}
+
 static inline BOOL pf_is_double_format( char fmt )
 {
     static const char float_fmts[] = "aeEfgG";
@@ -385,6 +406,70 @@ static void pf_rebuild_format_string( ch
     *p++ = 0;
 }
 
+/* pf_integer_conv:  prints x to buf, including alternate formats,
+   but not the sign */
+static void pf_integer_conv( char *buf, pf_flags *flags, LONGLONG x )
+{
+    unsigned int base;
+    char *digits;
+
+    int i, j, k;
+    char tmp[40];
+
+    base = 10;
+    if( flags->Format == 'o' )
+        base = 8;
+    else if( flags->Format == 'x' || flags->Format == 'X' )
+        base = 16;
+
+    if( flags->Format == 'X' )
+        digits = "0123456789ABCDEFX";
+    else
+        digits = "0123456789abcdefx";
+
+    if( x < 0 && ( flags->Format == 'd' || flags->Format == 'i' ) )
+    {
+        x = -x;
+        flags->Sign = '-';
+    }
+
+    /* Do conversion (backwards) */
+    i = 0;
+    if( x == 0 && flags->Precision )
+        tmp[i++] = '0';
+    else
+        while( x != 0 )
+        {
+            j = (ULONGLONG) x % base;
+            x = (ULONGLONG) x / base;
+            tmp[i++] = digits[j];
+        }
+    k = flags->Precision - i;
+    while( k-- > 0 )
+        tmp[i++] = '0';
+    if( flags->Alternate )
+    {
+        if( base == 16 )
+        {
+            tmp[i++] = digits[16];
+            tmp[i++] = '0';
+        }
+        else if( base == 8 && tmp[i-1] != '0' )
+            tmp[i++] = '0';
+    }
+
+    /* Reverse for buf */
+    j = 0;
+    while( i-- > 0 )
+        buf[j++] = tmp[i];
+    buf[j] = '\0';
+
+    /* Adjust precision so pf_fill won't truncate the number later */
+    flags->Precision = strlen( buf );
+
+    return;
+}
+
 /*********************************************************************
  *  pf_vsnprintf  (INTERNAL)
  *
@@ -583,6 +668,21 @@ static int pf_vsnprintf( pf_output *out,
             *x = out->used;
         }
 
+        /* deal with 64-bit integers */
+        else if( pf_is_integer_format( flags.Format ) && flags.IntegerDouble )
+        {
+            char number[40], *x = number;
+
+            if( flags.FieldLength >= sizeof number )
+                x = HeapAlloc( GetProcessHeap(), 0, flags.FieldLength+1 );
+
+            pf_integer_conv( x, &flags, va_arg(valist, LONGLONG) );
+
+            r = pf_output_format_A( out, x, -1, &flags );
+            if( x != number )
+                HeapFree( GetProcessHeap(), 0, number );
+        }
+
         /* deal with integers and floats using libc's printf */
         else if( pf_is_valid_format( flags.Format ) )
         {




More information about the wine-cvs mailing list