Modernize AC_TRY_LINK invocations.
[gnulib.git] / m4 / iconv.m4
1 # iconv.m4 serial 11c
2 dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
6
7 dnl From Bruno Haible.
8
9 AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
10 [
11   dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
12   AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
13   AC_REQUIRE([AC_LIB_RPATH])
14
15   dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
16   dnl accordingly.
17   AC_LIB_LINKFLAGS_BODY([iconv])
18 ])
19
20 AC_DEFUN([AM_ICONV_LINK],
21 [
22   dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
23   dnl those with the standalone portable GNU libiconv installed).
24   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
25
26   dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
27   dnl accordingly.
28   AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
29
30   dnl Add $INCICONV to CPPFLAGS before performing the following checks,
31   dnl because if the user has installed libiconv and not disabled its use
32   dnl via --without-libiconv-prefix, he wants to use it. The first
33   dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
34   am_save_CPPFLAGS="$CPPFLAGS"
35   AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
36
37   AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
38     am_cv_func_iconv="no, consider installing GNU libiconv"
39     am_cv_lib_iconv=no
40     AC_LINK_IFELSE(
41       [AC_LANG_PROGRAM(
42          [[
43 #include <stdlib.h>
44 #include <iconv.h>
45          ]],
46          [[iconv_t cd = iconv_open("","");
47            iconv(cd,NULL,NULL,NULL,NULL);
48            iconv_close(cd);]])],
49       [am_cv_func_iconv=yes])
50     if test "$am_cv_func_iconv" != yes; then
51       am_save_LIBS="$LIBS"
52       LIBS="$LIBS $LIBICONV"
53       AC_LINK_IFELSE(
54         [AC_LANG_PROGRAM(
55            [[
56 #include <stdlib.h>
57 #include <iconv.h>
58            ]],
59            [[iconv_t cd = iconv_open("","");
60              iconv(cd,NULL,NULL,NULL,NULL);
61              iconv_close(cd);]])],
62         [am_cv_lib_iconv=yes]
63         [am_cv_func_iconv=yes])
64       LIBS="$am_save_LIBS"
65     fi
66   ])
67   if test "$am_cv_func_iconv" = yes; then
68     AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
69       dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
70       dnl Solaris 10.
71       am_save_LIBS="$LIBS"
72       if test $am_cv_lib_iconv = yes; then
73         LIBS="$LIBS $LIBICONV"
74       fi
75       AC_TRY_RUN([
76 #include <iconv.h>
77 #include <string.h>
78 int main ()
79 {
80   /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
81      returns.  */
82   {
83     iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
84     if (cd_utf8_to_88591 != (iconv_t)(-1))
85       {
86         static const char input[] = "\342\202\254"; /* EURO SIGN */
87         char buf[10];
88         const char *inptr = input;
89         size_t inbytesleft = strlen (input);
90         char *outptr = buf;
91         size_t outbytesleft = sizeof (buf);
92         size_t res = iconv (cd_utf8_to_88591,
93                             (char **) &inptr, &inbytesleft,
94                             &outptr, &outbytesleft);
95         if (res == 0)
96           return 1;
97       }
98   }
99   /* Test against Solaris 10 bug: Failures are not distinguishable from
100      successful returns.  */
101   {
102     iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
103     if (cd_ascii_to_88591 != (iconv_t)(-1))
104       {
105         static const char input[] = "\263";
106         char buf[10];
107         const char *inptr = input;
108         size_t inbytesleft = strlen (input);
109         char *outptr = buf;
110         size_t outbytesleft = sizeof (buf);
111         size_t res = iconv (cd_ascii_to_88591,
112                             (char **) &inptr, &inbytesleft,
113                             &outptr, &outbytesleft);
114         if (res == 0)
115           return 1;
116       }
117   }
118   /* Test against AIX 6.1..7.1 bug: Buffer overrun.  */
119   {
120     iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
121     if (cd_88591_to_utf8 != (iconv_t)(-1))
122       {
123         static const char input[] = "\304";
124         static char buf[2] = { (char)0xDE, (char)0xAD };
125         const char *inptr = input;
126         size_t inbytesleft = 1;
127         char *outptr = buf;
128         size_t outbytesleft = 1;
129         size_t res = iconv (cd_88591_to_utf8,
130                             (char **) &inptr, &inbytesleft,
131                             &outptr, &outbytesleft);
132         if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
133           return 1;
134       }
135   }
136 #if 0 /* This bug could be worked around by the caller.  */
137   /* Test against HP-UX 11.11 bug: Positive return value instead of 0.  */
138   {
139     iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
140     if (cd_88591_to_utf8 != (iconv_t)(-1))
141       {
142         static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
143         char buf[50];
144         const char *inptr = input;
145         size_t inbytesleft = strlen (input);
146         char *outptr = buf;
147         size_t outbytesleft = sizeof (buf);
148         size_t res = iconv (cd_88591_to_utf8,
149                             (char **) &inptr, &inbytesleft,
150                             &outptr, &outbytesleft);
151         if ((int)res > 0)
152           return 1;
153       }
154   }
155 #endif
156   /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
157      provided.  */
158   if (/* Try standardized names.  */
159       iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
160       /* Try IRIX, OSF/1 names.  */
161       && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
162       /* Try AIX names.  */
163       && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
164       /* Try HP-UX names.  */
165       && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
166     return 1;
167   return 0;
168 }], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
169         [
170 changequote(,)dnl
171          case "$host_os" in
172            aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
173            *)            am_cv_func_iconv_works="guessing yes" ;;
174          esac
175 changequote([,])dnl
176         ])
177       LIBS="$am_save_LIBS"
178     ])
179     case "$am_cv_func_iconv_works" in
180       *no) am_func_iconv=no am_cv_lib_iconv=no ;;
181       *)   am_func_iconv=yes ;;
182     esac
183   else
184     am_func_iconv=no am_cv_lib_iconv=no
185   fi
186   if test "$am_func_iconv" = yes; then
187     AC_DEFINE([HAVE_ICONV], [1],
188       [Define if you have the iconv() function and it works.])
189   fi
190   if test "$am_cv_lib_iconv" = yes; then
191     AC_MSG_CHECKING([how to link with libiconv])
192     AC_MSG_RESULT([$LIBICONV])
193   else
194     dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
195     dnl either.
196     CPPFLAGS="$am_save_CPPFLAGS"
197     LIBICONV=
198     LTLIBICONV=
199   fi
200   AC_SUBST([LIBICONV])
201   AC_SUBST([LTLIBICONV])
202 ])
203
204 dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
205 dnl avoid warnings like
206 dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
207 dnl This is tricky because of the way 'aclocal' is implemented:
208 dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
209 dnl   Otherwise aclocal's initial scan pass would miss the macro definition.
210 dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
211 dnl   Otherwise aclocal would emit many "Use of uninitialized value $1"
212 dnl   warnings.
213 m4_define([gl_iconv_AC_DEFUN],
214   m4_version_prereq([2.64],
215     [[AC_DEFUN_ONCE(
216         [$1], [$2])]],
217     [[AC_DEFUN(
218         [$1], [$2])]]))
219 gl_iconv_AC_DEFUN([AM_ICONV],
220 [
221   AM_ICONV_LINK
222   if test "$am_cv_func_iconv" = yes; then
223     AC_MSG_CHECKING([for iconv declaration])
224     AC_CACHE_VAL([am_cv_proto_iconv], [
225       AC_COMPILE_IFELSE(
226         [AC_LANG_PROGRAM(
227            [[
228 #include <stdlib.h>
229 #include <iconv.h>
230 extern
231 #ifdef __cplusplus
232 "C"
233 #endif
234 #if defined(__STDC__) || defined(__cplusplus)
235 size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
236 #else
237 size_t iconv();
238 #endif
239            ]],
240            [[]])],
241         [am_cv_proto_iconv_arg1=""],
242         [am_cv_proto_iconv_arg1="const"])
243       am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
244     am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
245     AC_MSG_RESULT([
246          $am_cv_proto_iconv])
247     AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
248       [Define as const if the declaration of iconv() needs const.])
249   fi
250 ])