iconv.m4 (11052B)
1 # iconv.m4 2 # serial 28 3 dnl Copyright (C) 2000-2002, 2007-2014, 2016-2024 Free Software Foundation, 4 dnl Inc. 5 dnl This file is free software; the Free Software Foundation 6 dnl gives unlimited permission to copy and/or distribute it, 7 dnl with or without modifications, as long as this notice is preserved. 8 dnl This file is offered as-is, without any warranty. 9 10 dnl From Bruno Haible. 11 12 AC_PREREQ([2.64]) 13 14 dnl Note: AM_ICONV is documented in the GNU gettext manual 15 dnl <https://www.gnu.org/software/gettext/manual/html_node/AM_005fICONV.html>. 16 dnl Don't make changes that are incompatible with that documentation! 17 18 AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], 19 [ 20 dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. 21 AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) 22 AC_REQUIRE([AC_LIB_RPATH]) 23 24 dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV 25 dnl accordingly. 26 AC_LIB_LINKFLAGS_BODY([iconv]) 27 ]) 28 29 AC_DEFUN([AM_ICONV_LINK], 30 [ 31 dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and 32 dnl those with the standalone portable GNU libiconv installed). 33 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 34 35 dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV 36 dnl accordingly. 37 AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) 38 39 dnl Add $INCICONV to CPPFLAGS before performing the following checks, 40 dnl because if the user has installed libiconv and not disabled its use 41 dnl via --without-libiconv-prefix, he wants to use it. The first 42 dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. 43 gl_saved_CPPFLAGS="$CPPFLAGS" 44 AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) 45 46 AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ 47 am_cv_func_iconv="no, consider installing GNU libiconv" 48 am_cv_lib_iconv=no 49 AC_LINK_IFELSE( 50 [AC_LANG_PROGRAM( 51 [[ 52 #include <stdlib.h> 53 #include <iconv.h> 54 ]], 55 [[iconv_t cd = iconv_open("",""); 56 iconv(cd,NULL,NULL,NULL,NULL); 57 iconv_close(cd);]])], 58 [am_cv_func_iconv=yes]) 59 if test "$am_cv_func_iconv" != yes; then 60 gl_saved_LIBS="$LIBS" 61 LIBS="$LIBS $LIBICONV" 62 AC_LINK_IFELSE( 63 [AC_LANG_PROGRAM( 64 [[ 65 #include <stdlib.h> 66 #include <iconv.h> 67 ]], 68 [[iconv_t cd = iconv_open("",""); 69 iconv(cd,NULL,NULL,NULL,NULL); 70 iconv_close(cd);]])], 71 [am_cv_lib_iconv=yes] 72 [am_cv_func_iconv=yes]) 73 LIBS="$gl_saved_LIBS" 74 fi 75 ]) 76 if test "$am_cv_func_iconv" = yes; then 77 AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ 78 dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, 79 dnl Solaris 10, macOS 14.4. 80 gl_saved_LIBS="$LIBS" 81 if test $am_cv_lib_iconv = yes; then 82 LIBS="$LIBS $LIBICONV" 83 fi 84 am_cv_func_iconv_works=no 85 for ac_iconv_const in '' 'const'; do 86 AC_RUN_IFELSE( 87 [AC_LANG_PROGRAM( 88 [[ 89 #include <iconv.h> 90 #include <string.h> 91 92 #ifndef ICONV_CONST 93 # define ICONV_CONST $ac_iconv_const 94 #endif 95 ]], 96 [[int result = 0; 97 /* Test against AIX 5.1...7.2 bug: Failures are not distinguishable from 98 successful returns. This is even documented in 99 <https://www.ibm.com/support/knowledgecenter/ssw_aix_72/i_bostechref/iconv.html> */ 100 { 101 iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); 102 if (cd_utf8_to_88591 != (iconv_t)(-1)) 103 { 104 static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ 105 char buf[10]; 106 ICONV_CONST char *inptr = input; 107 size_t inbytesleft = strlen (input); 108 char *outptr = buf; 109 size_t outbytesleft = sizeof (buf); 110 size_t res = iconv (cd_utf8_to_88591, 111 &inptr, &inbytesleft, 112 &outptr, &outbytesleft); 113 if (res == 0) 114 result |= 1; 115 iconv_close (cd_utf8_to_88591); 116 } 117 } 118 /* Test against macOS 14.4 bug: Failures are not distinguishable from 119 successful returns. 120 POSIX:2018 says: "The iconv() function shall ... return the number of 121 non-identical conversions performed." 122 But here, the conversion always does transliteration (the suffixes 123 "//TRANSLIT" and "//IGNORE" have no effect, nor does iconvctl()) and 124 does not report when it does a non-identical conversion. */ 125 { 126 iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8"); 127 if (cd_utf8_to_88591 != (iconv_t)(-1)) 128 { 129 static ICONV_CONST char input[] = "\305\202"; /* LATIN SMALL LETTER L WITH STROKE */ 130 char buf[10]; 131 ICONV_CONST char *inptr = input; 132 size_t inbytesleft = strlen (input); 133 char *outptr = buf; 134 size_t outbytesleft = sizeof (buf); 135 size_t res = iconv (cd_utf8_to_88591, 136 &inptr, &inbytesleft, 137 &outptr, &outbytesleft); 138 /* Here: 139 With glibc, GNU libiconv (including macOS up to 13): res == (size_t)-1, errno == EILSEQ. 140 With musl libc, NetBSD 10, Solaris 11: res == 1. 141 With macOS 14.4: res == 0, output is "l". */ 142 if (res == 0) 143 result |= 2; 144 iconv_close (cd_utf8_to_88591); 145 } 146 } 147 /* Test against Solaris 10 bug: Failures are not distinguishable from 148 successful returns. */ 149 { 150 iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); 151 if (cd_ascii_to_88591 != (iconv_t)(-1)) 152 { 153 static ICONV_CONST char input[] = "\263"; 154 char buf[10]; 155 ICONV_CONST char *inptr = input; 156 size_t inbytesleft = strlen (input); 157 char *outptr = buf; 158 size_t outbytesleft = sizeof (buf); 159 size_t res = iconv (cd_ascii_to_88591, 160 &inptr, &inbytesleft, 161 &outptr, &outbytesleft); 162 if (res == 0) 163 result |= 4; 164 iconv_close (cd_ascii_to_88591); 165 } 166 } 167 /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ 168 { 169 iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); 170 if (cd_88591_to_utf8 != (iconv_t)(-1)) 171 { 172 static ICONV_CONST char input[] = "\304"; 173 static char buf[2] = { (char)0xDE, (char)0xAD }; 174 ICONV_CONST char *inptr = input; 175 size_t inbytesleft = 1; 176 char *outptr = buf; 177 size_t outbytesleft = 1; 178 size_t res = iconv (cd_88591_to_utf8, 179 &inptr, &inbytesleft, 180 &outptr, &outbytesleft); 181 if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) 182 result |= 8; 183 iconv_close (cd_88591_to_utf8); 184 } 185 } 186 #if 0 /* This bug could be worked around by the caller. */ 187 /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ 188 { 189 iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); 190 if (cd_88591_to_utf8 != (iconv_t)(-1)) 191 { 192 static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; 193 char buf[50]; 194 ICONV_CONST char *inptr = input; 195 size_t inbytesleft = strlen (input); 196 char *outptr = buf; 197 size_t outbytesleft = sizeof (buf); 198 size_t res = iconv (cd_88591_to_utf8, 199 &inptr, &inbytesleft, 200 &outptr, &outbytesleft); 201 if ((int)res > 0) 202 result |= 16; 203 iconv_close (cd_88591_to_utf8); 204 } 205 } 206 #endif 207 /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is 208 provided. */ 209 { 210 /* Try standardized names. */ 211 iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP"); 212 /* Try IRIX, OSF/1 names. */ 213 iconv_t cd2 = iconv_open ("UTF-8", "eucJP"); 214 /* Try AIX names. */ 215 iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP"); 216 /* Try HP-UX names. */ 217 iconv_t cd4 = iconv_open ("utf8", "eucJP"); 218 if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) 219 && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) 220 result |= 32; 221 if (cd1 != (iconv_t)(-1)) 222 iconv_close (cd1); 223 if (cd2 != (iconv_t)(-1)) 224 iconv_close (cd2); 225 if (cd3 != (iconv_t)(-1)) 226 iconv_close (cd3); 227 if (cd4 != (iconv_t)(-1)) 228 iconv_close (cd4); 229 } 230 return result; 231 ]])], 232 [am_cv_func_iconv_works=yes], , 233 [case "$host_os" in 234 aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; 235 *) am_cv_func_iconv_works="guessing yes" ;; 236 esac]) 237 test "$am_cv_func_iconv_works" = no || break 238 done 239 LIBS="$gl_saved_LIBS" 240 ]) 241 case "$am_cv_func_iconv_works" in 242 *no) am_func_iconv=no am_cv_lib_iconv=no ;; 243 *) am_func_iconv=yes ;; 244 esac 245 else 246 am_func_iconv=no am_cv_lib_iconv=no 247 fi 248 if test "$am_func_iconv" = yes; then 249 AC_DEFINE([HAVE_ICONV], [1], 250 [Define if you have the iconv() function and it works.]) 251 fi 252 if test "$am_cv_lib_iconv" = yes; then 253 AC_MSG_CHECKING([how to link with libiconv]) 254 AC_MSG_RESULT([$LIBICONV]) 255 else 256 dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV 257 dnl either. 258 CPPFLAGS="$gl_saved_CPPFLAGS" 259 LIBICONV= 260 LTLIBICONV= 261 fi 262 AC_SUBST([LIBICONV]) 263 AC_SUBST([LTLIBICONV]) 264 ]) 265 266 dnl Define AM_ICONV using AC_DEFUN_ONCE, in order to avoid warnings like 267 dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". 268 AC_DEFUN_ONCE([AM_ICONV], 269 [ 270 AM_ICONV_LINK 271 if test "$am_cv_func_iconv" = yes; then 272 AC_CACHE_CHECK([whether iconv is compatible with its POSIX signature], 273 [gl_cv_iconv_nonconst], 274 [AC_COMPILE_IFELSE( 275 [AC_LANG_PROGRAM( 276 [[ 277 #include <stdlib.h> 278 #include <iconv.h> 279 extern 280 #ifdef __cplusplus 281 "C" 282 #endif 283 size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); 284 ]], 285 [[]])], 286 [gl_cv_iconv_nonconst=yes], 287 [gl_cv_iconv_nonconst=no]) 288 ]) 289 else 290 dnl When compiling GNU libiconv on a system that does not have iconv yet, 291 dnl pick the POSIX compliant declaration without 'const'. 292 gl_cv_iconv_nonconst=yes 293 fi 294 if test $gl_cv_iconv_nonconst = yes; then 295 iconv_arg1="" 296 else 297 iconv_arg1="const" 298 fi 299 AC_DEFINE_UNQUOTED([ICONV_CONST], [$iconv_arg1], 300 [Define as const if the declaration of iconv() needs const.]) 301 dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>. 302 m4_ifdef([gl_ICONV_H_DEFAULTS], 303 [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) 304 if test $gl_cv_iconv_nonconst != yes; then 305 ICONV_CONST="const" 306 fi 307 ]) 308 309 dnl A summary result, for those packages which want to print a summary at the 310 dnl end of the configuration. 311 if test "$am_func_iconv" = yes; then 312 if test -n "$LIBICONV"; then 313 am_cv_func_iconv_summary='yes, in libiconv' 314 else 315 am_cv_func_iconv_summary='yes, in libc' 316 fi 317 else 318 if test "$am_cv_func_iconv" = yes; then 319 am_cv_func_iconv_summary='not working, consider installing GNU libiconv' 320 else 321 am_cv_func_iconv_summary='no, consider installing GNU libiconv' 322 fi 323 fi 324 ])