OSDN Git Service

Make MinGW printf() "%p" format compatible with MSVCRT scanf().
authorkeithmarshall <keithmarshall>
Tue, 29 Sep 2009 20:43:49 +0000 (20:43 +0000)
committerkeithmarshall <keithmarshall>
Tue, 29 Sep 2009 20:43:49 +0000 (20:43 +0000)
winsup/mingw/ChangeLog
winsup/mingw/mingwex/stdio/pformat.c

index 27c4089..70c644f 100644 (file)
@@ -1,3 +1,16 @@
+2009-09-29  Keith Marshall  <keithmarshall@users.sourceforge.net>
+
+       Make MinGW printf() "%p" format compatible with MSVCRT scanf().
+       (Based on MinGW-patch 2844514 by Peter Rosin <peda@lysator.liu.se>)
+
+       * mingwex/stdio/pformat.c (__printf) [%p]: Do not arbitrarily apply...
+       (PFORMAT_HASHED): ...this formatting attribute; honour only user
+       specified format qualifiers, except in special case...
+       [%p && stream.flags == flags && state == PFORMAT_INIT]: Apply...
+       (PFORMAT_ZEROFILL): ...this default formatting attribute...
+       (stream.precision): ...filled to at least 2 * sizeof( uintptr_t )
+       hexadecimal digits.
+
 2009-09-01  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
        Avoid multiple link time definitions of _printf() for C++;
index a59d513..55972fc 100644 (file)
@@ -2021,9 +2021,22 @@ int __pformat( int flags, void *dest, int max, const char *fmt, va_list argv )
 
          case 'p':
            /*
-            * Pointer argument; format as hexadecimal, with `0x' prefix...
+            * Pointer argument; format as hexadecimal, subject to...
             */
-           stream.flags |= PFORMAT_HASHED;
+           if( (state == PFORMAT_INIT) && (stream.flags == flags) )
+           {
+             /* Here, the user didn't specify any particular
+              * formatting attributes.  We must choose a default
+              * which will be compatible with Microsoft's (broken)
+              * scanf() implementation, (i.e. matching the default
+              * used by MSVCRT's printf(), which appears to resemble
+              * "%0.8X" for 32-bit pointers); in particular, we MUST
+              * NOT adopt a GNU-like format resembling "%#x", because
+              * Microsoft's scanf() will choke on the "0x" prefix.
+              */
+             stream.flags |= PFORMAT_ZEROFILL;
+             stream.precision = 2 * sizeof( uintptr_t );
+           }
            argval.__pformat_ullong_t = va_arg( argv, uintptr_t );
            __pformat_xint( 'x', argval, &stream );
            goto format_scan;