[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: multiple definitions of __printf__
From: |
Bruno Haible |
Subject: |
Re: multiple definitions of __printf__ |
Date: |
Sun, 16 May 2010 14:21:25 +0200 |
User-agent: |
KMail/1.9.9 |
Ben Pfaff wrote:
> This fixes the build in the case where both libintl and PSPP's
> Gnulib define __printf__. But it broke the build in the
> previously working case where libintl did not define __printf__
> but PSPP's Gnulib did and no longer does. This is the case on,
> for example, FreeBSD 7.3 and, according to reports on pspp-dev,
> OpenSUSE as well.
>
> Is the best solution to check whether libintl defines __printf__
> and, if so, avoid defining it in Gnulib?
This would have been better than what I committed in March, yes.
But it would not fix another problem: On a platform when libintl
defines __printf__, this replacement is not necessarily POSIX compliant.
(It only adds the support for argument reordering, which is essential
for i18n.) If then the user requires gnulib module 'printf-posix',
he would still not be getting a POSIX compliant printf() function.
This should fix both problems:
2010-05-16 Bruno Haible <address@hidden>
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.
--- lib/printf.c.orig Sun May 16 14:08:11 2010
+++ lib/printf.c Sun May 16 12:11:07 2010
@@ -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 @@
return retval;
}
-
-#endif
--- lib/stdio-write.c.orig Sun May 16 14:08:12 2010
+++ lib/stdio-write.c Sun May 16 12:11:22 2010
@@ -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 @@
return retval;
}
-# endif
# endif
# if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */
--- lib/stdio.in.h.orig Sun May 16 14:08:12 2010
+++ lib/stdio.in.h Sun May 16 13:01:19 2010
@@ -63,6 +63,10 @@
/* 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 @@
#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
--- m4/stdio_h.m4.orig Sun May 16 14:08:12 2010
+++ m4/stdio_h.m4 Sun May 16 12:57:02 2010
@@ -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_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.
--- modules/stdio.orig Sun May 16 14:08:12 2010
+++ modules/stdio Sun May 16 12:56:21 2010
@@ -5,6 +5,7 @@
lib/stdio.in.h
lib/stdio-write.c
m4/stdio_h.m4
+m4/asm-underscore.m4
Depends-on:
include_next
@@ -112,6 +113,7 @@
-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)'; \
============================ m4/asm-underscore.m4 ============================
# 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])
])