Eli Zaretskii <e...@gnu.org> writes: > The prototype of 'iconv' in GNU libiconv's iconv.h is this: > > size_t iconv (iconv_t cd, const char** inbuf, size_t *inbytesleft, > char** outbuf, size_t *outbytesleft); > > The 'const' qualifier of the 2nd argument is decided at libiconv > configuration time, and may be absent. But the 4th argument is > _never_ given a 'const' qualifier.
Sorry about that. I have no idea why I type-casted OUTBUF (maybe I was confused by the Linux manual page saying: "Although inbuf and outbuf are typed as char **, ..."). > Next, it looks to me that the test program in iconv.m4 is > inappropriate for a C++ compiler, because (AFAIK) C++ does not allow > type-casting of the kind that the original test program (before your > changes) did to the 2nd argument. (With a C compiler, you get a > warning, which the configure script ignores.) I'm not familiar with C++, but does that really cause an error? Yes, I see warnings with: ./configure CC=g++ CFLAGS=-Wcast-qual The attached patch tries to suppress it. Perhaps gnulib/tests/test-iconv.c also needs a fix. I've tested it on MSYS after manually adding 'const' to the iconv declaration in /usr/local/include/iconv.h, and it seems to be detected. Here is a new test package: http://du-a.org/~ueno/junk/test-iconv-2.tar.gz Thanks, -- Daiki Ueno
>From 621cb2d9483053aa33cfeb1c6c6c20316aeac432 Mon Sep 17 00:00:00 2001 From: Daiki Ueno <u...@gnu.org> Date: Tue, 21 Oct 2014 18:07:00 +0900 Subject: [PATCH] iconv: avoid false detection of non-working iconv The INBUF arguments of iconv can be either 'const char **' or 'char **'. If CC is g++, the difference causes a compile error and thus leads to a false detection of non-working iconv. Reported by Eli Zaretskii and Werner LEMBERG in: <https://lists.gnu.org/archive/html/bug-gnulib/2014-10/msg00023.html>. * m4/iconv.m4 (AM_ICONV_LINK): Try all possible argument types of iconv. Bump serial number. --- ChangeLog | 11 +++++++++++ m4/iconv.m4 | 61 ++++++++++++++++++++++++++++++++----------------------------- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 23234b7..62e4824 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2014-10-21 Daiki Ueno <u...@gnu.org> + + iconv: avoid false detection of non-working iconv + The INBUF arguments of iconv can be either 'const char **' + or 'char **'. If CC is g++, the difference causes a compile error + and thus leads to a false detection of non-working iconv. + Reported by Eli Zaretskii and Werner LEMBERG in: + <https://lists.gnu.org/archive/html/bug-gnulib/2014-10/msg00023.html>. + * m4/iconv.m4 (AM_ICONV_LINK): Try all possible argument types of + iconv. Bump serial number. + 2014-10-18 Paul Eggert <egg...@cs.ucla.edu> symlinkat: port to AIX 7.1 diff --git a/m4/iconv.m4 b/m4/iconv.m4 index 4b29c5f..4e37363 100644 --- a/m4/iconv.m4 +++ b/m4/iconv.m4 @@ -1,4 +1,4 @@ -# iconv.m4 serial 18 (gettext-0.18.2) +# iconv.m4 serial 19 (gettext-0.18.2) dnl Copyright (C) 2000-2002, 2007-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -72,27 +72,33 @@ AC_DEFUN([AM_ICONV_LINK], if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" fi - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[ #include <iconv.h> #include <string.h> -int main () -{ - int result = 0; + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + ]], + [[int result = 0; /* Test against AIX 5.1 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); if (cd_utf8_to_88591 != (iconv_t)(-1)) { - static const char input[] = "\342\202\254"; /* EURO SIGN */ + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ char buf[10]; - const char *inptr = input; + ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_utf8_to_88591, - (char **) &inptr, &inbytesleft, + &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 1; @@ -105,14 +111,14 @@ int main () iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); if (cd_ascii_to_88591 != (iconv_t)(-1)) { - static const char input[] = "\263"; + static ICONV_CONST char input[] = "\263"; char buf[10]; - const char *inptr = input; + ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_ascii_to_88591, - (char **) &inptr, &inbytesleft, + &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 2; @@ -124,14 +130,14 @@ int main () iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { - static const char input[] = "\304"; + static ICONV_CONST char input[] = "\304"; static char buf[2] = { (char)0xDE, (char)0xAD }; - const char *inptr = input; + ICONV_CONST char *inptr = input; size_t inbytesleft = 1; char *outptr = buf; size_t outbytesleft = 1; size_t res = iconv (cd_88591_to_utf8, - (char **) &inptr, &inbytesleft, + &inptr, &inbytesleft, &outptr, &outbytesleft); if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) result |= 4; @@ -144,14 +150,14 @@ int main () iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { - static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; char buf[50]; - const char *inptr = input; + ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_88591_to_utf8, - (char **) &inptr, &inbytesleft, + &inptr, &inbytesleft, &outptr, &outbytesleft); if ((int)res > 0) result |= 8; @@ -171,17 +177,14 @@ int main () && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) result |= 16; return result; -}]])], - [am_cv_func_iconv_works=yes], - [am_cv_func_iconv_works=no], - [ -changequote(,)dnl - case "$host_os" in - aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; - *) am_cv_func_iconv_works="guessing yes" ;; - esac -changequote([,])dnl - ]) +]])], + [am_cv_func_iconv_works=yes], , + [case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac]) + test "$am_cv_func_iconv_works" = no || break + done LIBS="$am_save_LIBS" ]) case "$am_cv_func_iconv_works" in -- 1.9.3