OSDN Git Service

Avoid built-in snprintf() prototypes; fix MinGW-Bug #39224
authorKeith Marshall <keith@users.osdn.me>
Wed, 3 Jul 2019 20:49:42 +0000 (21:49 +0100)
committerKeith Marshall <keith@users.osdn.me>
Wed, 3 Jul 2019 20:49:42 +0000 (21:49 +0100)
mingwrt/ChangeLog
mingwrt/include/stdio.h
mingwrt/mingwex/stdio/snprintf.c
mingwrt/mingwex/stdio/vsnprintf.c
mingwrt/tests/ansiprintf.at

index 45aa8ab..61ec093 100644 (file)
@@ -1,3 +1,20 @@
+2019-07-03  Keith Marshall  <keith@users.osdn.me>
+
+       Avoid built-in snprintf() prototypes; fix MinGW-Bug #39224
+
+       * include/stdio.h [__USE_MINGW_ANSI_STDIO]
+       (snprintf, vsnprintf): Implement them in-line, delegating to...
+       (__mingw_vsnprintf): ...this external function.
+
+       * mingwex/stdio/snprintf.c mingwex/stdio/vsnprintf.c: Assert
+       copyright; include <stddef.h>, instead of <stdio.h>, to obtain a
+       definition of "size_t"; this is required because the new in-line
+       prototypes, now provided in <stdio.h>, conflict with the intent
+       to provide external implementations.
+
+       * tests/ansiprintf.at (MINGW_AT_CHECK_SNPRINTF): Conditionally
+       circumvent conditions which may produce -Wformat warnings.
+
 2019-07-01  Keith Marshall  <keith@users.osdn.me>
 
        Revert to macro implementation of "alloca()" functions.
index 4ab5cca..8ee3624 100644 (file)
@@ -375,7 +375,7 @@ extern int __mingw_stdio_redirect__(vsnprintf)(char*, size_t, const char*, __VAL
  */
 extern unsigned int _mingw_output_format_control( unsigned int, unsigned int );
 
-#if __USE_MINGW_ANSI_STDIO
+#if __USE_MINGW_ANSI_STDIO || defined _ISOC99_SOURCE
 /* User has expressed a preference for C99 conformance...
  */
 # undef __mingw_stdio_redirect__
@@ -393,12 +393,20 @@ extern unsigned int _mingw_output_format_control( unsigned int, unsigned int );
  */
 #  define __mingw_stdio_redirect__  static __inline__ __cdecl __MINGW_NOTHROW
 
-# else
+# else /* Neither C++ nor __GNUC__ */
 /* Can't use inlines; fall back on module local static stubs.
  */
 #  define __mingw_stdio_redirect__  static __cdecl __MINGW_NOTHROW
-# endif
 
+# endif        /* Neither C++ nor __GNUC__ */
+#endif /* __USE_MINGW_ANSI_STDIO || defined _ISOC99_SOURCE */
+
+#if __USE_MINGW_ANSI_STDIO
+/* The MinGW ISO-C conforming implementations of the printf() family
+ * of functions are to be used, in place of non-conforming Microsoft
+ * implementations; force call redirection, via the following set of
+ * in-line functions.
+ */
 __mingw_stdio_redirect__
 int fprintf (FILE *__stream, const char *__format, ...)
 {
@@ -457,7 +465,34 @@ _CRTIMP __cdecl __MINGW_NOTHROW  int vfprintf (FILE *, const char *, __VALIST);
 _CRTIMP __cdecl __MINGW_NOTHROW  int vprintf (const char *, __VALIST);
 _CRTIMP __cdecl __MINGW_NOTHROW  int vsprintf (char *, const char *, __VALIST);
 
-#endif
+#endif /* !__USE_MINGW_ANSI_STDIO */
+
+#if __GNUC__ && defined _ISOC99_SOURCE
+/* Although MinGW implementations of the ISO-C99 snprintf() and
+ * vsnprintf() functions do not conflict with any implementation
+ * in MSVCRT.DLL, (because MSVCRT.DLL does not implement either),
+ * there are -Wformat attribute conflicts with the GCC built-in
+ * prototypes associated with each; by providing the following
+ * in-line function implementations, which will override GCC's
+ * built-in prototypes, we may avoid these conflicts.
+ */
+__mingw_stdio_redirect__
+int snprintf (char *__buf, size_t __len, const char *__format, ...)
+{
+  register int __retval;
+  __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );
+  __retval = __mingw_vsnprintf( __buf, __len, __format, __local_argv );
+  __builtin_va_end( __local_argv );
+  return __retval;
+}
+
+__mingw_stdio_redirect__
+int vsnprintf (char *__buf, size_t __len, const char *__format, __VALIST __local_argv)
+{
+  return __mingw_vsnprintf( __buf, __len, __format, __local_argv );
+}
+#endif /* __GNUC__ && defined _ISOC99_SOURCE */
+
 /* Regardless of user preference, always offer these alternative
  * entry points, for direct access to the MSVCRT implementations,
  * with ms_printf -Wformat checking in each case.
index e04100d..1165d4c 100644 (file)
  * standard MSVCRT function remains available, and may  be invoked
  * directly, using this fully qualified form of its name).
  *
- * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ * Written by Keith Marshall <keith@users.osdn.me>
+ * Copyright (C) 2008, 2019, MinGW.org Project
  *
- * This is free software.  You may redistribute and/or modify it as you
- * see fit, without restriction of copyright.
+ * This replaces earlier, substantially different implementations,
+ * originally provided as snprintf.c, and later encapsulated within
+ * gdtoa/mingw_snprintf.c:
  *
- * This software is provided "as is", in the hope that it may be useful,
- * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
- * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE.  At no
- * time will the author accept any form of liability for any damages,
- * however caused, resulting from the use of this software.
+ * Written by Danny Smith <dannysmith@users.sourceforge.net>
+ * Copyright (C) 2002, 2003, 2007, 2008, MinGW.org Project
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  *
  */
-
-#include <stdio.h>
 #include <stdarg.h>
+#include <stddef.h>
 
 #include "pformat.h"
 
@@ -41,4 +59,4 @@ int __cdecl __snprintf( char *buf, size_t length, const char *fmt, ... )
   return retval;
 }
 
-/* $RCSfile$$Revision$: end of file */
+/* $RCSfile$: end of file */
index b96b7e1..1def294 100644 (file)
  * standard MSVCRT function remains available, and may  be invoked
  * directly, using this fully qualified form of its name).
  *
- * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ * Written by Keith Marshall <keith@users.osdn.me>
+ * Copyright (C) 2008, 2019, MinGW.org Project
  *
- * This is free software.  You may redistribute and/or modify it as you
- * see fit, without restriction of copyright.
+ * This replaces earlier, substantially different implementations,
+ * originally provided as vsnprintf.c, and later encapsulated within
+ * gdtoa/mingw_snprintf.c:
  *
- * This software is provided "as is", in the hope that it may be useful,
- * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
- * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE.  At no
- * time will the author accept any form of liability for any damages,
- * however caused, resulting from the use of this software.
+ * Written by Danny Smith <dannysmith@users.sourceforge.net>
+ * Copyright (C) 2002, 2003, 2007, 2008, MinGW.org Project
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  *
  */
-
-#include <stdio.h>
 #include <stdarg.h>
+#include <stddef.h>
 
 #include "pformat.h"
 
@@ -52,4 +70,4 @@ int __cdecl __vsnprintf( char *buf, size_t length, const char *fmt, va_list argv
   return retval;
 }
 
-/* $RCSfile$$Revision$: end of file */
+/* $RCSfile$: end of file */
index 65cbc30..6486637 100644 (file)
@@ -249,26 +249,31 @@ MINGW_AT_CHECK_PRINTF([[%16.0La%4d]], [1.450L, 44], [::          0xcp-3  44::])
 MINGW_AT_CHECK_PRINTF([[%16.1La%4d]], [1.999L, 99], [::        0x8.0p-2  99::])
 
 
-# MINGW_AT_CHECK_SNPRINTF( FORMAT, MAXCOUNT, INITCOUNT )
-# ------------------------------------------------------
+# MINGW_AT_CHECK_SNPRINTF( FORMAT, COUNT, MAXCOUNT, INITCOUNT )
+# -------------------------------------------------------------
 # Test the behaviour of the snprintf() function, with respect to
 # output truncation at specified MAXCOUNT (no more than 32), when
 # writing string "Sample text; sufficient buffer" subject to the
-# specified.  Also supports testing the effect of "%n" counting
-# on an internal integer variable, initialized to INITCOUNT.
+# specified FORMAT and COUNT (concatenated to define the format
+# string).  Also supports testing the effect of "%n" counting on
+# an internal integer variable, initialized to INITCOUNT, when
+# COUNT is specified as "n", (with optional "hh" length modifier
+# prefix; if this option is not to be exercised, FORMAT should
+# be passed as "%", with COUNT as "s").
 #
 m4_define([MINGW_AT_CHECK_SNPRINTF],[dnl
-AT_SETUP([snprintf (output, $2, "$1", ...)])
-AT_KEYWORDS([C printf])MINGW_AT_DATA_CRLF([expout],[[$4
+AT_SETUP([snprintf (output, $3, "$1$2", ...)])
+AT_KEYWORDS([C printf])MINGW_AT_DATA_CRLF([expout],[[$5
 ]])MINGW_AT_CHECK_RUN([[[
 #define _XOPEN_SOURCE 700
 #include <stdio.h>
 int main()
-{ char output[32]; int capture = ]$3[;
+{ char output[32]; union { int n; char hhn; } capture = {]$4[};
   const char *sample = "Sample text; sufficient buffer";
-  int total = snprintf (output, ]$2[, "]$1[", sample, &capture);
-  snprintf (NULL, 0, "]$1[", output, &capture);
-  printf ("%s: %d required; %d captured\n", output, total, capture);
+  int total = snprintf (output, ]$3[, "]$1$2[", sample]m4_if([$2],[s],]dnl
+    [,[, &capture.$2])[);
+  snprintf (NULL, 0, "]$1$2[", output]m4_if([$2],[s],,[, &capture.$2])[);
+  printf ("%s: %d required; %d captured\n", output, total, capture.n);
   return 0;
 }]]],,[expout])dnl
 AT_CLEANUP
@@ -278,20 +283,20 @@ AT_CLEANUP
 # Tests for snprintf() with limited length internal buffer.
 #
 AT_BANNER([ISO-C99 snprintf() buffer length control.])
-MINGW_AT_CHECK_SNPRINTF([[%s]],[32],[1024],dnl
+MINGW_AT_CHECK_SNPRINTF([[%]],[s],[32],[1024],dnl
 [Sample text; sufficient buffer: 30 required; 1024 captured])
-MINGW_AT_CHECK_SNPRINTF([[%s]],[12],[1024],dnl
+MINGW_AT_CHECK_SNPRINTF([[%]],[s],[12],[1024],dnl
 [Sample text: 30 required; 1024 captured])
 
 
 # Tests for effect of "%n" output length counting.
 #
 AT_BANNER([ISO-C99 snprintf() intermediate output counting.])
-MINGW_AT_CHECK_SNPRINTF([[%s%n]],[32],[1024],dnl
+MINGW_AT_CHECK_SNPRINTF([[%s%]],[n],[32],[1024],dnl
 [Sample text; sufficient buffer: 30 required; 30 captured])
-MINGW_AT_CHECK_SNPRINTF([[%s%n]],[12],[1024],dnl
+MINGW_AT_CHECK_SNPRINTF([[%s%]],[n],[12],[1024],dnl
 [Sample text: 30 required; 11 captured])
-MINGW_AT_CHECK_SNPRINTF([[%s%hhn]],[12],[1024],dnl
+MINGW_AT_CHECK_SNPRINTF([[%s%]],[hhn],[12],[1024],dnl
 [Sample text: 30 required; 1035 captured])
 
 # vim: filetype=config formatoptions=croql