1 # mbrtowc.m4 serial 16 2 dnl Copyright (C) 2001-2002, 2004-2005, 2008, 2009 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 AC_DEFUN([gl_FUNC_MBRTOWC], 8 [ 9 AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) 10 11 AC_REQUIRE([AC_TYPE_MBSTATE_T]) 12 gl_MBSTATE_T_BROKEN 13 if test $REPLACE_MBSTATE_T = 1; then 14 REPLACE_MBRTOWC=1 15 fi 16 AC_CHECK_FUNCS_ONCE([mbrtowc]) 17 if test $ac_cv_func_mbrtowc = no; then 18 HAVE_MBRTOWC=0 19 fi 20 if test $HAVE_MBRTOWC != 0 && test $REPLACE_MBRTOWC != 1; then 21 gl_MBRTOWC_NULL_ARG 22 gl_MBRTOWC_RETVAL 23 gl_MBRTOWC_NUL_RETVAL 24 case "$gl_cv_func_mbrtowc_null_arg" in 25 *yes) ;; 26 *) AC_DEFINE([MBRTOWC_NULL_ARG_BUG], [1], 27 [Define if the mbrtowc function has the NULL string argument bug.]) 28 REPLACE_MBRTOWC=1 29 ;; 30 esac 31 case "$gl_cv_func_mbrtowc_retval" in 32 *yes) ;; 33 *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1], 34 [Define if the mbrtowc function returns a wrong return value.]) 35 REPLACE_MBRTOWC=1 36 ;; 37 esac 38 case "$gl_cv_func_mbrtowc_nul_retval" in 39 *yes) ;; 40 *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1], 41 [Define if the mbrtowc function does not return 0 for a NUL character.]) 42 REPLACE_MBRTOWC=1 43 ;; 44 esac 45 fi 46 if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then 47 gl_REPLACE_WCHAR_H 48 AC_LIBOBJ([mbrtowc]) 49 gl_PREREQ_MBRTOWC 50 fi 51 ]) 52 53 dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that 54 dnl redefines the semantics of the given mbstate_t type. 55 dnl Result is REPLACE_MBSTATE_T. 56 dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to 57 dnl avoid inconsistencies. 58 59 AC_DEFUN([gl_MBSTATE_T_BROKEN], 60 [ 61 AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) 62 63 AC_REQUIRE([AC_TYPE_MBSTATE_T]) 64 AC_CHECK_FUNCS_ONCE([mbsinit]) 65 AC_CHECK_FUNCS_ONCE([mbrtowc]) 66 if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then 67 gl_MBRTOWC_INCOMPLETE_STATE 68 gl_MBRTOWC_SANITYCHECK 69 REPLACE_MBSTATE_T=0 70 case "$gl_cv_func_mbrtowc_incomplete_state" in 71 *yes) ;; 72 *) REPLACE_MBSTATE_T=1 ;; 73 esac 74 case "$gl_cv_func_mbrtowc_sanitycheck" in 75 *yes) ;; 76 *) REPLACE_MBSTATE_T=1 ;; 77 esac 78 else 79 REPLACE_MBSTATE_T=1 80 fi 81 if test $REPLACE_MBSTATE_T = 1; then 82 gl_REPLACE_WCHAR_H 83 fi 84 ]) 85 86 dnl Test whether mbrtowc puts the state into non-initial state when parsing an 87 dnl incomplete multibyte character. 88 dnl Result is gl_cv_func_mbrtowc_incomplete_state. 89 90 AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE], 91 [ 92 AC_REQUIRE([AC_PROG_CC]) 93 AC_REQUIRE([gt_LOCALE_JA]) 94 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 95 AC_CACHE_CHECK([whether mbrtowc handles incomplete characters], 96 [gl_cv_func_mbrtowc_incomplete_state], 97 [ 98 dnl Initial guess, used when cross-compiling or when no suitable locale 99 dnl is present. 100 changequote(,)dnl 101 case "$host_os" in 102 # Guess no on AIX and OSF/1. 103 osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;; 104 # Guess yes otherwise. 105 *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;; 106 esac 107 changequote([,])dnl 108 if test $LOCALE_JA != none; then 109 AC_TRY_RUN([ 110 #include <locale.h> 111 #include <string.h> 112 #include <wchar.h> 113 int main () 114 { 115 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) 116 { 117 const char input[] = "B\217\253\344\217\251\316er"; /* "Ber" */ 118 mbstate_t state; 119 wchar_t wc; 120 121 memset (&state, '\0', sizeof (mbstate_t)); 122 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 123 if (mbsinit (&state)) 124 return 1; 125 } 126 return 0; 127 }], 128 [gl_cv_func_mbrtowc_incomplete_state=yes], 129 [gl_cv_func_mbrtowc_incomplete_state=no], 130 [:]) 131 fi 132 ]) 133 ]) 134 135 dnl Test whether mbrtowc works not worse than mbtowc. 136 dnl Result is gl_cv_func_mbrtowc_sanitycheck. 137 138 AC_DEFUN([gl_MBRTOWC_SANITYCHECK], 139 [ 140 AC_REQUIRE([AC_PROG_CC]) 141 AC_REQUIRE([gt_LOCALE_ZH_CN]) 142 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 143 AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc], 144 [gl_cv_func_mbrtowc_sanitycheck], 145 [ 146 dnl Initial guess, used when cross-compiling or when no suitable locale 147 dnl is present. 148 changequote(,)dnl 149 case "$host_os" in 150 # Guess no on Solaris 8. 151 solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;; 152 # Guess yes otherwise. 153 *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;; 154 esac 155 changequote([,])dnl 156 if test $LOCALE_ZH_CN != none; then 157 AC_TRY_RUN([ 158 #include <locale.h> 159 #include <stdlib.h> 160 #include <string.h> 161 #include <wchar.h> 162 int main () 163 { 164 /* This fails on Solaris 8: 165 mbrtowc returns 2, and sets wc to 0x00F0. 166 mbtowc returns 4 (correct) and sets wc to 0x5EDC. */ 167 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) 168 { 169 char input[] = "B\250\271\201\060\211\070er"; /* "Ber" */ 170 mbstate_t state; 171 wchar_t wc; 172 173 memset (&state, '\0', sizeof (mbstate_t)); 174 if (mbrtowc (&wc, input + 3, 6, &state) != 4 175 && mbtowc (&wc, input + 3, 6) == 4) 176 return 1; 177 } 178 return 0; 179 }], 180 [gl_cv_func_mbrtowc_sanitycheck=yes], 181 [gl_cv_func_mbrtowc_sanitycheck=no], 182 [:]) 183 fi 184 ]) 185 ]) 186 187 dnl Test whether mbrtowc supports a NULL string argument correctly. 188 dnl Result is gl_cv_func_mbrtowc_null_arg. 189 190 AC_DEFUN([gl_MBRTOWC_NULL_ARG], 191 [ 192 AC_REQUIRE([AC_PROG_CC]) 193 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 194 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 195 AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument], 196 [gl_cv_func_mbrtowc_null_arg], 197 [ 198 dnl Initial guess, used when cross-compiling or when no suitable locale 199 dnl is present. 200 changequote(,)dnl 201 case "$host_os" in 202 # Guess no on OSF/1. 203 osf*) gl_cv_func_mbrtowc_null_arg="guessing no" ;; 204 # Guess yes otherwise. 205 *) gl_cv_func_mbrtowc_null_arg="guessing yes" ;; 206 esac 207 changequote([,])dnl 208 if test $LOCALE_FR_UTF8 != none; then 209 AC_TRY_RUN([ 210 #include <locale.h> 211 #include <string.h> 212 #include <wchar.h> 213 int main () 214 { 215 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 216 { 217 mbstate_t state; 218 wchar_t wc; 219 int ret; 220 221 memset (&state, '\0', sizeof (mbstate_t)); 222 wc = (wchar_t) 0xBADFACE; 223 mbrtowc (&wc, NULL, 5, &state); 224 /* Check that wc was not modified. */ 225 if (wc != (wchar_t) 0xBADFACE) 226 return 1; 227 } 228 return 0; 229 }], [gl_cv_func_mbrtowc_null_arg=yes], [gl_cv_func_mbrtowc_null_arg=no], [:]) 230 fi 231 ]) 232 ]) 233 234 dnl Test whether mbrtowc, when parsing the end of a multibyte character, 235 dnl correctly returns the number of bytes that were needed to complete the 236 dnl character (not the total number of bytes of the multibyte character). 237 dnl Result is gl_cv_func_mbrtowc_retval. 238 239 AC_DEFUN([gl_MBRTOWC_RETVAL], 240 [ 241 AC_REQUIRE([AC_PROG_CC]) 242 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 243 AC_REQUIRE([gt_LOCALE_JA]) 244 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 245 AC_CACHE_CHECK([whether mbrtowc has a correct return value], 246 [gl_cv_func_mbrtowc_retval], 247 [ 248 dnl Initial guess, used when cross-compiling or when no suitable locale 249 dnl is present. 250 changequote(,)dnl 251 case "$host_os" in 252 # Guess no on HP-UX and Solaris. 253 hpux* | solaris*) gl_cv_func_mbrtowc_retval="guessing no" ;; 254 # Guess yes otherwise. 255 *) gl_cv_func_mbrtowc_retval="guessing yes" ;; 256 esac 257 changequote([,])dnl 258 if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then 259 AC_TRY_RUN([ 260 #include <locale.h> 261 #include <string.h> 262 #include <wchar.h> 263 int main () 264 { 265 /* This fails on Solaris. */ 266 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 267 { 268 char input[] = "B\303\274\303\237er"; /* "Ber" */ 269 mbstate_t state; 270 wchar_t wc; 271 272 memset (&state, '\0', sizeof (mbstate_t)); 273 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 274 { 275 input[1] = '\0'; 276 if (mbrtowc (&wc, input + 2, 5, &state) != 1) 277 return 1; 278 } 279 } 280 /* This fails on HP-UX 11.11. */ 281 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) 282 { 283 char input[] = "B\217\253\344\217\251\316er"; /* "Ber" */ 284 mbstate_t state; 285 wchar_t wc; 286 287 memset (&state, '\0', sizeof (mbstate_t)); 288 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 289 { 290 input[1] = '\0'; 291 if (mbrtowc (&wc, input + 2, 5, &state) != 2) 292 return 1; 293 } 294 } 295 return 0; 296 }], 297 [gl_cv_func_mbrtowc_retval=yes], 298 [gl_cv_func_mbrtowc_retval=no], 299 [:]) 300 fi 301 ]) 302 ]) 303 304 dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0. 305 dnl Result is gl_cv_func_mbrtowc_nul_retval. 306 307 AC_DEFUN([gl_MBRTOWC_NUL_RETVAL], 308 [ 309 AC_REQUIRE([AC_PROG_CC]) 310 AC_REQUIRE([gt_LOCALE_ZH_CN]) 311 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 312 AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character], 313 [gl_cv_func_mbrtowc_nul_retval], 314 [ 315 dnl Initial guess, used when cross-compiling or when no suitable locale 316 dnl is present. 317 changequote(,)dnl 318 case "$host_os" in 319 # Guess no on Solaris 8 and 9. 320 solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;; 321 # Guess yes otherwise. 322 *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;; 323 esac 324 changequote([,])dnl 325 if test $LOCALE_ZH_CN != none; then 326 AC_TRY_RUN([ 327 #include <locale.h> 328 #include <string.h> 329 #include <wchar.h> 330 int main () 331 { 332 /* This fails on Solaris 8 and 9. */ 333 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) 334 { 335 mbstate_t state; 336 wchar_t wc; 337 338 memset (&state, '\0', sizeof (mbstate_t)); 339 if (mbrtowc (&wc, "", 1, &state) != 0) 340 return 1; 341 } 342 return 0; 343 }], 344 [gl_cv_func_mbrtowc_nul_retval=yes], 345 [gl_cv_func_mbrtowc_nul_retval=no], 346 [:]) 347 fi 348 ]) 349 ]) 350 351 # Prerequisites of lib/mbrtowc.c. 352 AC_DEFUN([gl_PREREQ_MBRTOWC], [ 353 : 354 ]) 355 356 357 dnl From Paul Eggert 358 359 dnl This override of an autoconf macro can be removed when autoconf 2.60 or 360 dnl newer can be assumed everywhere. 361 362 m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.60]),[-1],[ 363 AC_DEFUN([AC_FUNC_MBRTOWC], 364 [ 365 dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60. 366 AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared], 367 gl_cv_func_mbrtowc, 368 [AC_LINK_IFELSE( 369 [AC_LANG_PROGRAM( 370 [[#include <wchar.h>]], 371 [[wchar_t wc; 372 char const s[] = ""; 373 size_t n = 1; 374 mbstate_t state; 375 return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])], 376 gl_cv_func_mbrtowc=yes, 377 gl_cv_func_mbrtowc=no)]) 378 if test $gl_cv_func_mbrtowc = yes; then 379 AC_DEFINE([HAVE_MBRTOWC], [1], 380 [Define to 1 if mbrtowc and mbstate_t are properly declared.]) 381 fi 382 ]) 383 ]) 384