Fix collision between gnulib's and libintl's printf replacements.
authorBruno Haible <bruno@clisp.org>
Sun, 16 May 2010 12:16:03 +0000 (14:16 +0200)
committerBruno Haible <bruno@clisp.org>
Sun, 16 May 2010 12:16:03 +0000 (14:16 +0200)
ChangeLog
lib/printf.c
lib/stdio-write.c
lib/stdio.in.h
m4/asm-underscore.m4 [new file with mode: 0644]
m4/stdio_h.m4
modules/stdio

index f146728..c365994 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2010-05-16  Bruno Haible  <bruno@clisp.org>
 
+       Fix collision between gnulib's and libintl's printf replacements.
+       * lib/stdio.in.h (_GL_STDIO_STRINGIZE,
+       _GL_STDIO_MACROEXPAND_AND_STRINGIZE): New macros.
+       (printf): When using GNU C, map the __printf__ function to rpl_printf
+       via __asm__. When not using GNU C, define rpl_printf instead of
+       __printf__.
+       * lib/printf.c: Ignore DEPENDS_ON_LIBINTL. Undoes the 2010-03-25
+       commit.
+       * lib/stdio-write.c: Ignore DEPENDS_ON_LIBINTL. Undoes the 2009-08-10
+       commit.
+       * m4/asm-underscore.m4: New file.
+       * m4/stdio_h.m4 (gl_STDIO_H): Require gl_ASM_SYMBOL_PREFIX.
+       * modules/stdio (Files): Add m4/asm-underscore.m4.
+       (Makefile.am): Substitute ASM_SYMBOL_PREFIX.
+       Reported by Ben Pfaff.
+
+2010-05-16  Bruno Haible  <bruno@clisp.org>
+
        verify: Avoid skipping the test on openSUSE 11.0.
        * tests/test-verify.sh: Unset MALLOC_PERTURB_.
 
index c48042a..3746afe 100644 (file)
@@ -23,8 +23,6 @@
 
 #include <stdarg.h>
 
-#if !DEPENDS_ON_LIBINTL /* avoid collision with intl/printf.c */
-
 /* Print formatted output to standard output.
    Return string length of formatted string.  On error, return a negative
    value.  */
@@ -40,5 +38,3 @@ printf (const char *format, ...)
 
   return retval;
 }
-
-#endif
index f7da9e4..a6a0eb1 100644 (file)
@@ -63,7 +63,6 @@
     }
 
 #  if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */
-#   if !DEPENDS_ON_LIBINTL /* avoid collision with intl/printf.c */
 int
 printf (const char *format, ...)
 {
@@ -76,7 +75,6 @@ printf (const char *format, ...)
 
   return retval;
 }
-#   endif
 #  endif
 
 #  if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */
index 2b09256..ca8960e 100644 (file)
 
 /* The definition of _GL_WARN_ON_USE is copied here.  */
 
+/* Macros for stringification.  */
+#define _GL_STDIO_STRINGIZE(token) #token
+#define _GL_STDIO_MACROEXPAND_AND_STRINGIZE(token) _GL_STDIO_STRINGIZE(token)
+
 
 #if @GNULIB_DPRINTF@
 # if @REPLACE_DPRINTF@
@@ -640,16 +644,26 @@ _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - "
 #if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@
 # if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \
      || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@)
-#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#  if defined __GNUC__
+#   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 /* Don't break __attribute__((format(printf,M,N))).  */
-#   define printf __printf__
-#  endif
-#  define GNULIB_overrides_printf 1
+#    define printf __printf__
+#   endif
 _GL_FUNCDECL_RPL_1 (__printf__, int,
                     (const char *format, ...)
+                    __asm__ (@ASM_SYMBOL_PREFIX@
+                             _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf))
                     __attribute__ ((__format__ (__printf__, 1, 2)))
                     _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...));
+#  else
+_GL_FUNCDECL_RPL (printf, int,
+                  (const char *format, ...)
+                  __attribute__ ((__format__ (__printf__, 1, 2)))
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (printf, printf, int, (const char *format, ...));
+#  endif
+#  define GNULIB_overrides_printf 1
 # else
 _GL_CXXALIAS_SYS (printf, int, (const char *format, ...));
 # endif
diff --git a/m4/asm-underscore.m4 b/m4/asm-underscore.m4
new file mode 100644 (file)
index 0000000..1736cc4
--- /dev/null
@@ -0,0 +1,48 @@
+# asm-underscore.m4 serial 1
+dnl Copyright (C) 2010 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.
+
+dnl From Bruno Haible. Based on as-underscore.m4 in GNU clisp.
+
+# gl_ASM_SYMBOL_PREFIX
+# Tests for the prefix of C symbols at the assembly language level and the
+# linker level. This prefix is either an underscore or empty. Defines the
+# C macro USER_LABEL_PREFIX to this prefix, and sets ASM_SYMBOL_PREFIX to
+# a stringified variant of this prefix.
+
+AC_DEFUN([gl_ASM_SYMBOL_PREFIX],
+[
+  dnl We don't use GCC's __USER_LABEL_PREFIX__ here, because
+  dnl 1. It works only for GCC.
+  dnl 2. It is incorrectly defined on some platforms, in some GCC versions.
+  AC_CACHE_CHECK(
+    [whether C symbols are prefixed with underscore at the linker level],
+    [gl_cv_prog_as_underscore],
+    [cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" int foo (void);
+#endif
+int foo(void) { return 0; }
+EOF
+     # Look for the assembly language name in the .s file.
+     AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c) >/dev/null 2>&1
+     if grep _foo conftest.s >/dev/null ; then
+       gl_cv_prog_as_underscore=yes
+     else
+       gl_cv_prog_as_underscore=no
+     fi
+     rm -f conftest*
+    ])
+  if test $gl_cv_prog_as_underscore = yes; then
+    USER_LABEL_PREFIX=_
+  else
+    USER_LABEL_PREFIX=
+  fi
+  AC_DEFINE_UNQUOTED([USER_LABEL_PREFIX], [$USER_LABEL_PREFIX],
+    [Define to the prefix of C symbols at the assembler and linker level,
+     either an underscore or empty.])
+  ASM_SYMBOL_PREFIX='"'${USER_LABEL_PREFIX}'"'
+  AC_SUBST([ASM_SYMBOL_PREFIX])
+])
index 1d1d95e..f5650cd 100644 (file)
@@ -1,4 +1,4 @@
-# stdio_h.m4 serial 30
+# stdio_h.m4 serial 31
 dnl Copyright (C) 2007-2010 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,6 +8,7 @@ AC_DEFUN([gl_STDIO_H],
 [
   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
   AC_REQUIRE([AC_C_INLINE])
+  AC_REQUIRE([gl_ASM_SYMBOL_PREFIX])
   gl_CHECK_NEXT_HEADERS([stdio.h])
   dnl No need to create extra modules for these functions. Everyone who uses
   dnl <stdio.h> likely needs them.
index c982dac..218d99e 100644 (file)
@@ -5,6 +5,7 @@ Files:
 lib/stdio.in.h
 lib/stdio-write.c
 m4/stdio_h.m4
+m4/asm-underscore.m4
 
 Depends-on:
 include_next
@@ -112,6 +113,7 @@ stdio.h: stdio.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
              -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \
              -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \
              -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \
+             -e 's|@''ASM_SYMBOL_PREFIX''@|$(ASM_SYMBOL_PREFIX)|g' \
              -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
              -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
              -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \