OSDN Git Service

Implement conditional replacement for printf() family functions.
authorkeithmarshall <keithmarshall>
Sat, 30 Aug 2008 17:27:18 +0000 (17:27 +0000)
committerkeithmarshall <keithmarshall>
Sat, 30 Aug 2008 17:27:18 +0000 (17:27 +0000)
winsup/mingw/ChangeLog
winsup/mingw/include/_mingw.h
winsup/mingw/include/stdio.h

index 0d6c2f6..f01c009 100644 (file)
@@ -1,3 +1,35 @@
+2008-08-30  Keith Marshall  <keithmarshall@users.sourceforge.net>
+
+       Implement conditional replacement for printf() family functions.
+
+       * include/_mingw.h (__USE_MINGW_ANSI_STDIO): New macro; define it.
+       (__MINGW_ANSI_STDIO__): New manifest constant; define as bitmapped
+       flag for use in user specified __MINGW_FEATURES__ attribute.
+       (__MINGW_LC_MESSAGES__, __MINGW_LC_ENVVARS__): New manifest constants;
+       currently unused: reserved as components of...
+       (__MINGW_LC_EXTENSIONS__): ...this new manifest constant; earmarked as
+       a __MINGW_FEATURES__ enhancement to setlocale().
+
+       * include/stdio.h (__mingw_printf, __mingw_vprintf): Prototype them.
+       (__mingw_fprintf, __mingw_vfprintf): Likewise.
+       (__mingw_sprintf, __mingw_vsprintf): Likewise.
+       (__msvcrt_printf, __msvcrt_vprintf): Likewise.
+       (__msvcrt_fprintf, __msvcrt_vfprintf): Likewise.
+       (__msvcrt_sprintf, __msvcrt_vsprintf): Likewise.
+       (printf, vprintf) [!__USE_MINGW_ANSI_STDIO]: Prototype for default
+       usage; link to DLL import stub, importing from MSVCRT.
+       (fprintf, vfprintf) [!__USE_MINGW_ANSI_STDIO]: Likewise.
+       (sprintf, vsprintf) [!__USE_MINGW_ANSI_STDIO]: Likewise.
+       (printf) [__USE_MINGW_ANSI_STDIO]: Redirect to __mingw_printf; use
+       locally defined static stub implementation.
+       (fprintf, sprintf) [__USE_MINGW_ANSI_STDIO]: Likewise; redirect to
+       __mingw_fprintf and __mingw_sprintf respectively.
+       (vprintf) [__USE_MINGW_ANSI_STDIO]: Redirect to __mingw_vprintf; use
+       static inline implementation for C++ and GNU C, or locally defined
+       static stub otherwise. 
+       (vfprintf, vsprintf) [__USE_MINGW_ANSI_STDIO]: Likewise; redirect to
+       __mingw_vfprintf and __mingw_vsprintf respectively.
+
 2008-08-27  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
        Avoid access violations, passing NULL to printf( "...%s..." );
index 2307272..65f23a5 100644 (file)
@@ -1,3 +1,4 @@
+#ifndef __MINGW_H
 /*
  * _mingw.h
  *
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  *
  */
-
-#ifndef __MINGW_H
 #define __MINGW_H
 
+#define __MINGW32_VERSION           3.14
+#define __MINGW32_MAJOR_VERSION     3
+#define __MINGW32_MINOR_VERSION     14
+
 #if __GNUC__ >= 3
 #pragma GCC system_header
 #endif
 /* These are defined by the user (or the compiler)
    to specify how identifiers are imported from a DLL.
 
-   __DECLSPEC_SUPPORTED    Defined if dllimport attribute is supported.
-   __MINGW_IMPORT          The attribute definition to specify imported
-                           variables/functions.
-   _CRTIMP                 As above.  For MS compatibility.
-   __MINGW32_VERSION       Runtime version.
-   __MINGW32_MAJOR_VERSION Runtime major version.
-   __MINGW32_MINOR_VERSION Runtime minor version.
-   __MINGW32_BUILD_DATE    Runtime build date.
+   __DECLSPEC_SUPPORTED            Defined if dllimport attribute is supported.
+   __MINGW_IMPORT                  The attribute definition to specify imported
+                                   variables/functions.
+   _CRTIMP                         As above.  For MS compatibility.
+   __MINGW32_VERSION               Runtime version.
+   __MINGW32_MAJOR_VERSION         Runtime major version.
+   __MINGW32_MINOR_VERSION         Runtime minor version.
+   __MINGW32_BUILD_DATE            Runtime build date.
+
+   Macros to enable MinGW features which deviate from standard MSVC
+   compatible behaviour; these may be specified directly in user code,
+   activated implicitly, (e.g. by specifying _POSIX_C_SOURCE or such),
+   or by inclusion in __MINGW_FEATURES__:
+
+   __USE_MINGW_ANSI_STDIO          Select a more ANSI C99 compatible
+                                   implementation of printf() and friends.
 
    Other macros:
 
-   __int64                 define to be long long. Using a typedef doesn't
-                           work for "unsigned __int64"
+   __int64                         define to be long long.  Using a typedef
+                                   doesn't work for "unsigned __int64"
 
    All headers should include this first, and then use __DECLSPEC_SUPPORTED
    to choose between the old ``__imp__name'' style or __MINGW_IMPORT
    style declarations.  */
 
+
+/* Manifest definitions identifying the flag bits, controlling activation
+ * of MinGW features, as specified by the user in __MINGW_FEATURES__.
+ */
+#define __MINGW_ANSI_STDIO__           0x0000000000000001ULL
+/*
+ * The following three are not yet formally supported; they are
+ * included here, to document anticipated future usage.
+ */
+#define __MINGW_LC_EXTENSIONS__        0x0000000000000050ULL
+#define __MINGW_LC_MESSAGES__          0x0000000000000010ULL
+#define __MINGW_LC_ENVVARS__           0x0000000000000040ULL
+
 /* Try to avoid problems with outdated checks for GCC __attribute__ support.  */
 #undef __attribute__
 
@@ -188,8 +212,28 @@ allow GCC to optimize away some EH unwind code, at least in DW2 case.  */
 # define __MSVCRT_VERSION__ 0x0600
 #endif
 
-#define __MINGW32_VERSION 3.14
-#define __MINGW32_MAJOR_VERSION 3
-#define __MINGW32_MINOR_VERSION 14
+/* Activation of MinGW specific extended features:
+ */
+#ifndef __USE_MINGW_ANSI_STDIO
+/*
+ * If user didn't specify it explicitly...
+ */
+# if   defined __STRICT_ANSI__  ||  defined _ISOC99_SOURCE \
+   ||  defined _POSIX_SOURCE    ||  defined _POSIX_C_SOURCE \
+   ||  defined _XOPEN_SOURCE    ||  defined _XOPEN_SOURCE_EXTENDED \
+   ||  defined _GNU_SOURCE      ||  defined _BSD_SOURCE \
+   ||  defined _SVID_SOURCE
+   /*
+    * but where any of these source code qualifiers are specified,
+    * then assume ANSI I/O standards are preferred over Microsoft's...
+    */
+#  define __USE_MINGW_ANSI_STDIO    1
+# else
+   /*
+    * otherwise use whatever __MINGW_FEATURES__ specifies...
+    */
+#  define __USE_MINGW_ANSI_STDIO    (__MINGW_FEATURES__ & __MINGW_ANSI_STDIO__)
+# endif
+#endif
 
 #endif /* __MINGW_H */
index c01de5e..c05b1b1 100644 (file)
@@ -194,16 +194,130 @@ _CRTIMP void __cdecl __MINGW_NOTHROW     setbuf (FILE*, char*);
 
 /*
  * Formatted Output
+ *
+ * MSVCRT implementations are not ANSI C99 conformant...
+ * we offer these conforming alternatives from libmingwex.a
+ */
+#undef  __mingw_stdio_redirect__
+#define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __mingw_##F
+
+extern int __mingw_stdio_redirect__(fprintf)(FILE*, const char*, ...);
+extern int __mingw_stdio_redirect__(printf)(const char*, ...);
+extern int __mingw_stdio_redirect__(sprintf)(char*, const char*, ...);
+extern int __mingw_stdio_redirect__(snprintf)(char*, size_t, const char*, ...);
+extern int __mingw_stdio_redirect__(vfprintf)(FILE*, const char*, __VALIST);
+extern int __mingw_stdio_redirect__(vprintf)(const char*, __VALIST);
+extern int __mingw_stdio_redirect__(vsprintf)(char*, const char*, __VALIST);
+extern int __mingw_stdio_redirect__(vsnprintf)(char*, size_t, const char*, __VALIST);
+
+#if __USE_MINGW_ANSI_STDIO
+/*
+ * User has expressed a preference for C99 conformance...
  */
+# undef __mingw_stdio_redirect__
+# ifdef __cplusplus
+/*
+ * For C++ we use inline implementations, to avoid interference
+ * with namespace qualification, which may result from using #defines.
+ */
+#  define __mingw_stdio_redirect__  static inline __cdecl __MINGW_NOTHROW
+
+# elif defined __GNUC__
+/*
+ * FIXME: Is there any GCC version prerequisite here?
+ *
+ * We also prefer inline implementations for C, when we can be confident
+ * that the GNU specific __inline__ mechanism is supported.
+ */
+#  define __mingw_stdio_redirect__  static __inline__ __cdecl __MINGW_NOTHROW
+
+# else
+/*
+ * Can't use inlines; fall back on module local static stubs.
+ */
+#  define __mingw_stdio_redirect__  static __cdecl __MINGW_NOTHROW
+# endif
+
+__mingw_stdio_redirect__
+int fprintf (FILE *__stream, const char *__format, ...)
+{
+  register int __retval;
+  __builtin_va_list __argv; __builtin_va_start( __argv, __format );
+  __retval = __mingw_vfprintf( __stream, __format, __argv );
+  __builtin_va_end( __argv );
+  return __retval;
+}
+
+__mingw_stdio_redirect__
+int printf (const char *__format, ...)
+{
+  register int __retval;
+  __builtin_va_list __argv; __builtin_va_start( __argv, __format );
+  __retval = __mingw_vprintf( __format, __argv );
+  __builtin_va_end( __argv );
+  return __retval;
+}
+
+__mingw_stdio_redirect__
+int sprintf (char *__stream, const char *__format, ...)
+{
+  register int __retval;
+  __builtin_va_list __argv; __builtin_va_start( __argv, __format );
+  __retval = __mingw_vsprintf( __stream, __format, __argv );
+  __builtin_va_end( __argv );
+  return __retval;
+}
 
-_CRTIMP int __cdecl __MINGW_NOTHROW    fprintf (FILE*, const char*, ...);
-_CRTIMP int __cdecl __MINGW_NOTHROW    printf (const char*, ...);
-_CRTIMP int __cdecl __MINGW_NOTHROW    sprintf (char*, const char*, ...);
-_CRTIMP int __cdecl __MINGW_NOTHROW    _snprintf (char*, size_t, const char*, ...);
-_CRTIMP int __cdecl __MINGW_NOTHROW    vfprintf (FILE*, const char*, __VALIST);
-_CRTIMP int __cdecl __MINGW_NOTHROW    vprintf (const char*, __VALIST);
-_CRTIMP int __cdecl __MINGW_NOTHROW    vsprintf (char*, const char*, __VALIST);
-_CRTIMP int __cdecl __MINGW_NOTHROW    _vsnprintf (char*, size_t, const char*, __VALIST);
+__mingw_stdio_redirect__
+int vfprintf (FILE *__stream, const char *__format, __VALIST __argv)
+{
+  return __mingw_vfprintf( __stream, __format, __argv );
+}
+
+__mingw_stdio_redirect__
+int vprintf (const char *__format, __VALIST __argv)
+{
+  return __mingw_vprintf( __format, __argv );
+}
+
+__mingw_stdio_redirect__
+int vsprintf (char *__stream, const char *__format, __VALIST __argv)
+{
+  return __mingw_vsprintf( __stream, __format, __argv );
+}
+
+#else
+/*
+ * Default configuration: simply direct all calls to MSVCRT...
+ */
+_CRTIMP int __cdecl __MINGW_NOTHROW fprintf (FILE*, const char*, ...);
+_CRTIMP int __cdecl __MINGW_NOTHROW printf (const char*, ...);
+_CRTIMP int __cdecl __MINGW_NOTHROW sprintf (char*, const char*, ...);
+_CRTIMP int __cdecl __MINGW_NOTHROW vfprintf (FILE*, const char*, __VALIST);
+_CRTIMP int __cdecl __MINGW_NOTHROW vprintf (const char*, __VALIST);
+_CRTIMP int __cdecl __MINGW_NOTHROW vsprintf (char*, const char*, __VALIST);
+
+#endif
+/*
+ * Regardless of user preference, always offer these alternative
+ * entry points, for direct access to the MSVCRT implementations.
+ */
+#undef  __mingw_stdio_redirect__
+#define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __msvcrt_##F
+
+_CRTIMP int __mingw_stdio_redirect__(fprintf)(FILE*, const char*, ...);
+_CRTIMP int __mingw_stdio_redirect__(printf)(const char*, ...);
+_CRTIMP int __mingw_stdio_redirect__(sprintf)(char*, const char*, ...);
+_CRTIMP int __mingw_stdio_redirect__(vfprintf)(FILE*, const char*, __VALIST);
+_CRTIMP int __mingw_stdio_redirect__(vprintf)(const char*, __VALIST);
+_CRTIMP int __mingw_stdio_redirect__(vsprintf)(char*, const char*, __VALIST);
+
+#undef  __mingw_stdio_redirect__
+
+/* The following pair ALWAYS refer to the MSVCRT implementations...
+ */
+_CRTIMP int __cdecl __MINGW_NOTHROW _snprintf (char*, size_t, const char*, ...);
+_CRTIMP int __cdecl __MINGW_NOTHROW _vsnprintf (char*, size_t, const char*, __VALIST);
 
 #ifndef __NO_ISOCEXT  /* externs in libmingwex.a */
 /*
@@ -213,7 +327,7 @@ _CRTIMP int __cdecl __MINGW_NOTHROW _vsnprintf (char*, size_t, const char*, __VA
  * compatible with C99, but the following are; if you want the MSVCRT
  * behaviour, you *must* use the Microsoft uglified names.
  */
-int __cdecl __MINGW_NOTHROW snprintf(char *, size_t, const char *, ...);
+int __cdecl __MINGW_NOTHROW snprintf (char *, size_t, const char *, ...);
 int __cdecl __MINGW_NOTHROW vsnprintf (char *, size_t, const char *, __VALIST);
 
 int __cdecl __MINGW_NOTHROW vscanf (const char * __restrict__, __VALIST);