bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: check for C99-compliant snprintf


From: Ben Pfaff
Subject: Re: check for C99-compliant snprintf
Date: Fri, 16 Feb 2007 16:57:15 -0800
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux)

Paul Eggert <address@hidden> writes:

> Ben Pfaff <address@hidden> writes:
>
>> We could of course test whether the system is Windows, using
>>   #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
>> or similar.  Is that a better idea?
>
> Do you mean to have two Autoconf tests, one at compile-time (with the
> above code), and one at run-time (with the code proposed earlier)?
> I.e., do the run-time test only if the compile-time test indicates
> that there may be trouble.  That sounds a bit fancy, but it would
> work.
>
> Or, you could just do the compile-time test and assume the bug exists
> if it fails.  That should be good enough, too.

The latter was what I had in mind.  I've appended a revised patch
below, which takes that approach.  To avoid duplicating the test
across snprintf and vsnprintf, I put the test into a separate
macro that is AC_REQUIREd.

This version works well for snprintf in my original test
environment, where I was using --disable-nls.  But then when I
tested it along with libintl, I noticed that snprintf broke
again.  I traced it to the following in libintl.h:
    #undef snprintf
    #define snprintf libintl_snprintf
where libintl_snprintf is a wrapper around the system snprintf,
which is still of course broken.  I'm not sure how to work around
this problem.  I guess I could submit a patch against the gettext
implementation of libintl_[v]snprintf to fix the problem, and
then recommend that mingw users of PSPP either --disable-nls or
use the fixed version.  Does that sound like an effective
solution?

vsnprintf is problematic even with --disable-nls, because mingw
<stdio.h> contains:
    __CRT_INLINE int __cdecl
    vsnprintf (char* s, size_t n, const char* format, __VALIST arg)
      { return _vsnprintf ( s, n, format, arg); }
When vsnprintf expands to rpl_vsnprintf, this turns rpl_vsnprintf
into a wrapper around the broken _vsnprintf.  I chose to fix that
by also replacing _vsnprintf, as shown in the patch below.  This
is all a little gross, and I don't know whether the method I used
is acceptable; please let me know.

Index: lib/_vsnprintf.c
===================================================================
RCS file: lib/_vsnprintf.c
diff -N lib/_vsnprintf.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/_vsnprintf.c    17 Feb 2007 00:56:08 -0000
@@ -0,0 +1,19 @@
+/* Formatted output to strings.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#define VSNPRINTF _vsnprintf
+#include "vsnprintf.c"
Index: lib/vasnprintf.c
===================================================================
RCS file: /sources/gnulib/gnulib/lib/vasnprintf.c,v
retrieving revision 1.22
diff -u -p -r1.22 vasnprintf.c
--- lib/vasnprintf.c    30 Jan 2007 01:07:22 -0000      1.22
+++ lib/vasnprintf.c    17 Feb 2007 00:56:09 -0000
@@ -27,6 +27,9 @@
 # include <alloca.h>
 #endif
 
+/* If we're replacing snprintf with rpl_snprintf, avoid a loop. */
+#undef snprintf
+
 /* Specification.  */
 #if WIDE_CHAR_VERSION
 # include "vasnwprintf.h"
Index: lib/vsnprintf.c
===================================================================
RCS file: /sources/gnulib/gnulib/lib/vsnprintf.c,v
retrieving revision 1.3
diff -u -p -r1.3 vsnprintf.c
--- lib/vsnprintf.c     28 Aug 2006 16:04:14 -0000      1.3
+++ lib/vsnprintf.c     17 Feb 2007 00:56:09 -0000
@@ -37,13 +37,17 @@
 # define EOVERFLOW E2BIG
 #endif
 
+#ifndef VSNPRINTF
+# define VSNPRINTF vsnprintf
+#endif
+
 /* Print formatted output to string STR.  Similar to vsprintf, but
    additional length SIZE limit how much is written into STR.  Returns
    string length of formatted string (which may be larger than SIZE).
    STR may be NULL, in which case nothing will be written.  On error,
    return a negative value. */
 int
-vsnprintf (char *str, size_t size, const char *format, va_list args)
+VSNPRINTF (char *str, size_t size, const char *format, va_list args)
 {
   char *output;
   size_t len;
Index: m4/native-w32.m4
===================================================================
RCS file: m4/native-w32.m4
diff -N m4/native-w32.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/native-w32.m4    17 Feb 2007 00:56:09 -0000
@@ -0,0 +1,21 @@
+#serial 1   -*- autoconf -*-
+
+# Helper macro to detect native w32; that is, a Windows environment
+# without Cygwin as a wrapper layer.
+
+# Copyright (C) 2007 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_AC_NATIVE_W32], [
+  AC_CACHE_CHECK([whether system is native Windows (without Cygwin)], 
+    [gl_cv_native_w32], [
+      AC_COMPILE_IFELSE([[
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+native w32 environment
+#endif]],
+      [gl_cv_native_w32=no],
+      [gl_cv_native_w32=yes])
+    ])
+])
Index: m4/snprintf.m4
===================================================================
RCS file: /sources/gnulib/gnulib/m4/snprintf.m4,v
retrieving revision 1.3
diff -u -p -r1.3 snprintf.m4
--- m4/snprintf.m4      23 Jan 2005 08:06:57 -0000      1.3
+++ m4/snprintf.m4      17 Feb 2007 00:56:09 -0000
@@ -1,12 +1,22 @@
-# snprintf.m4 serial 2
-dnl Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+# snprintf.m4 serial 3
+dnl Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_FUNC_SNPRINTF],
 [
-  AC_REPLACE_FUNCS(snprintf)
+  AC_REQUIRE([gl_AC_NATIVE_W32])
+  AC_CHECK_FUNCS_ONCE(snprintf)
+  AC_MSG_CHECKING([for C99-compliant snprintf])
+  if test $ac_cv_func_snprintf = no || test $gl_cv_native_w32 = yes; then
+    AC_LIBOBJ(snprintf)
+    AC_DEFINE(snprintf, rpl_snprintf,
+      [Define to rpl_snprintf if the replacement function should be used.])
+    AC_MSG_RESULT([no])
+  else
+    AC_MSG_RESULT([yes])
+  fi
   AC_CHECK_DECLS_ONCE(snprintf)
   gl_PREREQ_SNPRINTF
 ])
Index: m4/vsnprintf.m4
===================================================================
RCS file: /sources/gnulib/gnulib/m4/vsnprintf.m4,v
retrieving revision 1.2
diff -u -p -r1.2 vsnprintf.m4
--- m4/vsnprintf.m4     23 Jan 2005 08:06:57 -0000      1.2
+++ m4/vsnprintf.m4     17 Feb 2007 00:56:09 -0000
@@ -1,12 +1,27 @@
-# vsnprintf.m4 serial 2
-dnl Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+# vsnprintf.m4 serial 3
+dnl Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_FUNC_VSNPRINTF],
 [
-  AC_REPLACE_FUNCS(vsnprintf)
+  AC_REQUIRE([gl_AC_NATIVE_W32])
+  AC_CHECK_FUNCS_ONCE(vsnprintf)
+  AC_MSG_CHECKING([for C99-compliant vsnprintf])
+  if test $ac_cv_func_vsnprintf = no || test $gl_cv_native_w32 = yes; then
+    AC_LIBOBJ(vsnprintf)
+    AC_DEFINE(vsnprintf, rpl_vsnprintf,
+      [Define to rpl_vsnprintf if the replacement function should be used.])
+    AC_MSG_RESULT([no])
+  else
+    AC_MSG_RESULT([yes])
+  fi
+  if test $gl_cv_native_w32 = yes; then
+    AC_LIBOBJ(_vsnprintf)
+    AC_DEFINE(_vsnprintf, rpl__vsnprintf,
+      [Define to rpl__vsnprintf if the replacement function should be used.])
+  fi
   AC_CHECK_DECLS_ONCE(vsnprintf)
   gl_PREREQ_VSNPRINTF
 ])
Index: modules/snprintf
===================================================================
RCS file: /sources/gnulib/gnulib/modules/snprintf,v
retrieving revision 1.6
diff -u -p -r1.6 snprintf
--- modules/snprintf    13 Oct 2006 12:40:23 -0000      1.6
+++ modules/snprintf    17 Feb 2007 00:56:10 -0000
@@ -5,6 +5,7 @@ Files:
 lib/snprintf.h
 lib/snprintf.c
 m4/snprintf.m4
+m4/native-w32.m4
 
 Depends-on:
 vasnprintf
Index: modules/vsnprintf
===================================================================
RCS file: /sources/gnulib/gnulib/modules/vsnprintf,v
retrieving revision 1.3
diff -u -p -r1.3 vsnprintf
--- modules/vsnprintf   13 Oct 2006 12:40:23 -0000      1.3
+++ modules/vsnprintf   17 Feb 2007 00:56:10 -0000
@@ -5,7 +5,9 @@ to a fixed length string
 Files:
 lib/vsnprintf.h
 lib/vsnprintf.c
+lib/_vsnprintf.c
 m4/vsnprintf.m4
+m4/native-w32.m4
 
 Depends-on:
 vasnprintf
-- 
"In the PARTIES partition there is a small section called the BEER.
 Prior to turning control over to the PARTIES partition,
 the BIOS must measure the BEER area into PCR[5]."
--TCPA PC Specific Implementation Specification




reply via email to

[Prev in Thread] Current Thread [Next in Thread]