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