1 # mbrtowc.m4 serial 25 2 dnl Copyright (C) 2001-2002, 2004-2005, 2008-2012 Free Software Foundation, 3 dnl Inc. 4 dnl This file is free software; the Free Software Foundation 5 dnl gives unlimited permission to copy and/or distribute it, 6 dnl with or without modifications, as long as this notice is preserved. 7 8 AC_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 AC_CHECK_DECLS([mbrtowc],,, [[ 19 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 20 <wchar.h>. 21 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be 22 included before <wchar.h>. */ 23 #include <stddef.h> 24 #include <stdio.h> 25 #include <time.h> 26 #include <wchar.h> 27 ]]) 28 if test $ac_cv_have_decl_mbrtowc = yes; then 29 dnl On Minix 3.1.8, the system's <wchar.h> declares mbrtowc() although 30 dnl it does not have the function. Avoid a collision with gnulib's 31 dnl replacement. 32 REPLACE_MBRTOWC=1 33 fi 34 else 35 if test $REPLACE_MBSTATE_T = 1; then 36 REPLACE_MBRTOWC=1 37 else 38 gl_MBRTOWC_NULL_ARG1 39 gl_MBRTOWC_NULL_ARG2 40 gl_MBRTOWC_RETVAL 41 gl_MBRTOWC_NUL_RETVAL 42 case "$gl_cv_func_mbrtowc_null_arg1" in 43 *yes) ;; 44 *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1], 45 [Define if the mbrtowc function has the NULL pwc argument bug.]) 46 REPLACE_MBRTOWC=1 47 ;; 48 esac 49 case "$gl_cv_func_mbrtowc_null_arg2" in 50 *yes) ;; 51 *) AC_DEFINE([MBRTOWC_NULL_ARG2_BUG], [1], 52 [Define if the mbrtowc function has the NULL string argument bug.]) 53 REPLACE_MBRTOWC=1 54 ;; 55 esac 56 case "$gl_cv_func_mbrtowc_retval" in 57 *yes) ;; 58 *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1], 59 [Define if the mbrtowc function returns a wrong return value.]) 60 REPLACE_MBRTOWC=1 61 ;; 62 esac 63 case "$gl_cv_func_mbrtowc_nul_retval" in 64 *yes) ;; 65 *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1], 66 [Define if the mbrtowc function does not return 0 for a NUL character.]) 67 REPLACE_MBRTOWC=1 68 ;; 69 esac 70 fi 71 fi 72 ]) 73 74 dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that 75 dnl redefines the semantics of the given mbstate_t type. 76 dnl Result is REPLACE_MBSTATE_T. 77 dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to 78 dnl avoid inconsistencies. 79 80 AC_DEFUN([gl_MBSTATE_T_BROKEN], 81 [ 82 AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) 83 84 AC_REQUIRE([AC_TYPE_MBSTATE_T]) 85 AC_CHECK_FUNCS_ONCE([mbsinit]) 86 AC_CHECK_FUNCS_ONCE([mbrtowc]) 87 if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then 88 gl_MBRTOWC_INCOMPLETE_STATE 89 gl_MBRTOWC_SANITYCHECK 90 REPLACE_MBSTATE_T=0 91 case "$gl_cv_func_mbrtowc_incomplete_state" in 92 *yes) ;; 93 *) REPLACE_MBSTATE_T=1 ;; 94 esac 95 case "$gl_cv_func_mbrtowc_sanitycheck" in 96 *yes) ;; 97 *) REPLACE_MBSTATE_T=1 ;; 98 esac 99 else 100 REPLACE_MBSTATE_T=1 101 fi 102 ]) 103 104 dnl Test whether mbrtowc puts the state into non-initial state when parsing an 105 dnl incomplete multibyte character. 106 dnl Result is gl_cv_func_mbrtowc_incomplete_state. 107 108 AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE], 109 [ 110 AC_REQUIRE([AC_PROG_CC]) 111 AC_REQUIRE([gt_LOCALE_JA]) 112 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 113 AC_CACHE_CHECK([whether mbrtowc handles incomplete characters], 114 [gl_cv_func_mbrtowc_incomplete_state], 115 [ 116 dnl Initial guess, used when cross-compiling or when no suitable locale 117 dnl is present. 118 changequote(,)dnl 119 case "$host_os" in 120 # Guess no on AIX and OSF/1. 121 aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;; 122 # Guess yes otherwise. 123 *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;; 124 esac 125 changequote([,])dnl 126 if test $LOCALE_JA != none; then 127 AC_RUN_IFELSE( 128 [AC_LANG_SOURCE([[ 129 #include <locale.h> 130 #include <string.h> 131 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 132 <wchar.h>. 133 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be 134 included before <wchar.h>. */ 135 #include <stddef.h> 136 #include <stdio.h> 137 #include <time.h> 138 #include <wchar.h> 139 int main () 140 { 141 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) 142 { 143 const char input[] = "B\217\253\344\217\251\316er"; /* "Ber" */ 144 mbstate_t state; 145 wchar_t wc; 146 147 memset (&state, '\0', sizeof (mbstate_t)); 148 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 149 if (mbsinit (&state)) 150 return 1; 151 } 152 return 0; 153 }]])], 154 [gl_cv_func_mbrtowc_incomplete_state=yes], 155 [gl_cv_func_mbrtowc_incomplete_state=no], 156 [:]) 157 fi 158 ]) 159 ]) 160 161 dnl Test whether mbrtowc works not worse than mbtowc. 162 dnl Result is gl_cv_func_mbrtowc_sanitycheck. 163 164 AC_DEFUN([gl_MBRTOWC_SANITYCHECK], 165 [ 166 AC_REQUIRE([AC_PROG_CC]) 167 AC_REQUIRE([gt_LOCALE_ZH_CN]) 168 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 169 AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc], 170 [gl_cv_func_mbrtowc_sanitycheck], 171 [ 172 dnl Initial guess, used when cross-compiling or when no suitable locale 173 dnl is present. 174 changequote(,)dnl 175 case "$host_os" in 176 # Guess no on Solaris 8. 177 solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;; 178 # Guess yes otherwise. 179 *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;; 180 esac 181 changequote([,])dnl 182 if test $LOCALE_ZH_CN != none; then 183 AC_RUN_IFELSE( 184 [AC_LANG_SOURCE([[ 185 #include <locale.h> 186 #include <stdlib.h> 187 #include <string.h> 188 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 189 <wchar.h>. 190 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be 191 included before <wchar.h>. */ 192 #include <stddef.h> 193 #include <stdio.h> 194 #include <time.h> 195 #include <wchar.h> 196 int main () 197 { 198 /* This fails on Solaris 8: 199 mbrtowc returns 2, and sets wc to 0x00F0. 200 mbtowc returns 4 (correct) and sets wc to 0x5EDC. */ 201 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) 202 { 203 char input[] = "B\250\271\201\060\211\070er"; /* "Ber" */ 204 mbstate_t state; 205 wchar_t wc; 206 207 memset (&state, '\0', sizeof (mbstate_t)); 208 if (mbrtowc (&wc, input + 3, 6, &state) != 4 209 && mbtowc (&wc, input + 3, 6) == 4) 210 return 1; 211 } 212 return 0; 213 }]])], 214 [gl_cv_func_mbrtowc_sanitycheck=yes], 215 [gl_cv_func_mbrtowc_sanitycheck=no], 216 [:]) 217 fi 218 ]) 219 ]) 220 221 dnl Test whether mbrtowc supports a NULL pwc argument correctly. 222 dnl Result is gl_cv_func_mbrtowc_null_arg1. 223 224 AC_DEFUN([gl_MBRTOWC_NULL_ARG1], 225 [ 226 AC_REQUIRE([AC_PROG_CC]) 227 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 228 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 229 AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument], 230 [gl_cv_func_mbrtowc_null_arg1], 231 [ 232 dnl Initial guess, used when cross-compiling or when no suitable locale 233 dnl is present. 234 changequote(,)dnl 235 case "$host_os" in 236 # Guess no on Solaris. 237 solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;; 238 # Guess yes otherwise. 239 *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;; 240 esac 241 changequote([,])dnl 242 if test $LOCALE_FR_UTF8 != none; then 243 AC_RUN_IFELSE( 244 [AC_LANG_SOURCE([[ 245 #include <locale.h> 246 #include <stdlib.h> 247 #include <string.h> 248 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 249 <wchar.h>. 250 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be 251 included before <wchar.h>. */ 252 #include <stddef.h> 253 #include <stdio.h> 254 #include <time.h> 255 #include <wchar.h> 256 int main () 257 { 258 int result = 0; 259 260 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 261 { 262 char input[] = "\303\237er"; 263 mbstate_t state; 264 wchar_t wc; 265 size_t ret; 266 267 memset (&state, '\0', sizeof (mbstate_t)); 268 wc = (wchar_t) 0xBADFACE; 269 ret = mbrtowc (&wc, input, 5, &state); 270 if (ret != 2) 271 result |= 1; 272 if (!mbsinit (&state)) 273 result |= 2; 274 275 memset (&state, '\0', sizeof (mbstate_t)); 276 ret = mbrtowc (NULL, input, 5, &state); 277 if (ret != 2) /* Solaris 7 fails here: ret is -1. */ 278 result |= 4; 279 if (!mbsinit (&state)) 280 result |= 8; 281 } 282 return result; 283 }]])], 284 [gl_cv_func_mbrtowc_null_arg1=yes], 285 [gl_cv_func_mbrtowc_null_arg1=no], 286 [:]) 287 fi 288 ]) 289 ]) 290 291 dnl Test whether mbrtowc supports a NULL string argument correctly. 292 dnl Result is gl_cv_func_mbrtowc_null_arg2. 293 294 AC_DEFUN([gl_MBRTOWC_NULL_ARG2], 295 [ 296 AC_REQUIRE([AC_PROG_CC]) 297 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 298 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 299 AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument], 300 [gl_cv_func_mbrtowc_null_arg2], 301 [ 302 dnl Initial guess, used when cross-compiling or when no suitable locale 303 dnl is present. 304 changequote(,)dnl 305 case "$host_os" in 306 # Guess no on OSF/1. 307 osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;; 308 # Guess yes otherwise. 309 *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;; 310 esac 311 changequote([,])dnl 312 if test $LOCALE_FR_UTF8 != none; then 313 AC_RUN_IFELSE( 314 [AC_LANG_SOURCE([[ 315 #include <locale.h> 316 #include <string.h> 317 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 318 <wchar.h>. 319 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be 320 included before <wchar.h>. */ 321 #include <stddef.h> 322 #include <stdio.h> 323 #include <time.h> 324 #include <wchar.h> 325 int main () 326 { 327 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 328 { 329 mbstate_t state; 330 wchar_t wc; 331 int ret; 332 333 memset (&state, '\0', sizeof (mbstate_t)); 334 wc = (wchar_t) 0xBADFACE; 335 mbrtowc (&wc, NULL, 5, &state); 336 /* Check that wc was not modified. */ 337 if (wc != (wchar_t) 0xBADFACE) 338 return 1; 339 } 340 return 0; 341 }]])], 342 [gl_cv_func_mbrtowc_null_arg2=yes], 343 [gl_cv_func_mbrtowc_null_arg2=no], 344 [:]) 345 fi 346 ]) 347 ]) 348 349 dnl Test whether mbrtowc, when parsing the end of a multibyte character, 350 dnl correctly returns the number of bytes that were needed to complete the 351 dnl character (not the total number of bytes of the multibyte character). 352 dnl Result is gl_cv_func_mbrtowc_retval. 353 354 AC_DEFUN([gl_MBRTOWC_RETVAL], 355 [ 356 AC_REQUIRE([AC_PROG_CC]) 357 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 358 AC_REQUIRE([gt_LOCALE_JA]) 359 AC_REQUIRE([AC_CANONICAL_HOST]) 360 AC_CACHE_CHECK([whether mbrtowc has a correct return value], 361 [gl_cv_func_mbrtowc_retval], 362 [ 363 dnl Initial guess, used when cross-compiling or when no suitable locale 364 dnl is present. 365 changequote(,)dnl 366 case "$host_os" in 367 # Guess no on HP-UX, Solaris, native Windows. 368 hpux* | solaris* | mingw*) gl_cv_func_mbrtowc_retval="guessing no" ;; 369 # Guess yes otherwise. 370 *) gl_cv_func_mbrtowc_retval="guessing yes" ;; 371 esac 372 changequote([,])dnl 373 if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \ 374 || { case "$host_os" in mingw*) true;; *) false;; esac; }; then 375 AC_RUN_IFELSE( 376 [AC_LANG_SOURCE([[ 377 #include <locale.h> 378 #include <string.h> 379 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 380 <wchar.h>. 381 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be 382 included before <wchar.h>. */ 383 #include <stddef.h> 384 #include <stdio.h> 385 #include <time.h> 386 #include <wchar.h> 387 int main () 388 { 389 int result = 0; 390 int found_some_locale = 0; 391 /* This fails on Solaris. */ 392 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 393 { 394 char input[] = "B\303\274\303\237er"; /* "Ber" */ 395 mbstate_t state; 396 wchar_t wc; 397 398 memset (&state, '\0', sizeof (mbstate_t)); 399 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 400 { 401 input[1] = '\0'; 402 if (mbrtowc (&wc, input + 2, 5, &state) != 1) 403 result |= 1; 404 } 405 found_some_locale = 1; 406 } 407 /* This fails on HP-UX 11.11. */ 408 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) 409 { 410 char input[] = "B\217\253\344\217\251\316er"; /* "Ber" */ 411 mbstate_t state; 412 wchar_t wc; 413 414 memset (&state, '\0', sizeof (mbstate_t)); 415 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 416 { 417 input[1] = '\0'; 418 if (mbrtowc (&wc, input + 2, 5, &state) != 2) 419 result |= 2; 420 } 421 found_some_locale = 1; 422 } 423 /* This fails on native Windows. */ 424 if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL) 425 { 426 char input[] = "<\223\372\226\173\214\352>"; /* "<>" */ 427 mbstate_t state; 428 wchar_t wc; 429 430 memset (&state, '\0', sizeof (mbstate_t)); 431 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) 432 { 433 input[3] = '\0'; 434 if (mbrtowc (&wc, input + 4, 4, &state) != 1) 435 result |= 4; 436 } 437 found_some_locale = 1; 438 } 439 if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL) 440 { 441 char input[] = "<\244\351\245\273\273\171>"; /* "<>" */ 442 mbstate_t state; 443 wchar_t wc; 444 445 memset (&state, '\0', sizeof (mbstate_t)); 446 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) 447 { 448 input[3] = '\0'; 449 if (mbrtowc (&wc, input + 4, 4, &state) != 1) 450 result |= 8; 451 } 452 found_some_locale = 1; 453 } 454 if (setlocale (LC_ALL, "Chinese_China.936") != NULL) 455 { 456 char input[] = "<\310\325\261\276\325\132>"; /* "<>" */ 457 mbstate_t state; 458 wchar_t wc; 459 460 memset (&state, '\0', sizeof (mbstate_t)); 461 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) 462 { 463 input[3] = '\0'; 464 if (mbrtowc (&wc, input + 4, 4, &state) != 1) 465 result |= 16; 466 } 467 found_some_locale = 1; 468 } 469 return (found_some_locale ? result : 77); 470 }]])], 471 [gl_cv_func_mbrtowc_retval=yes], 472 [if test $? != 77; then 473 gl_cv_func_mbrtowc_retval=no 474 fi 475 ], 476 [:]) 477 fi 478 ]) 479 ]) 480 481 dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0. 482 dnl Result is gl_cv_func_mbrtowc_nul_retval. 483 484 AC_DEFUN([gl_MBRTOWC_NUL_RETVAL], 485 [ 486 AC_REQUIRE([AC_PROG_CC]) 487 AC_REQUIRE([gt_LOCALE_ZH_CN]) 488 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 489 AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character], 490 [gl_cv_func_mbrtowc_nul_retval], 491 [ 492 dnl Initial guess, used when cross-compiling or when no suitable locale 493 dnl is present. 494 changequote(,)dnl 495 case "$host_os" in 496 # Guess no on Solaris 8 and 9. 497 solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;; 498 # Guess yes otherwise. 499 *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;; 500 esac 501 changequote([,])dnl 502 if test $LOCALE_ZH_CN != none; then 503 AC_RUN_IFELSE( 504 [AC_LANG_SOURCE([[ 505 #include <locale.h> 506 #include <string.h> 507 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before 508 <wchar.h>. 509 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be 510 included before <wchar.h>. */ 511 #include <stddef.h> 512 #include <stdio.h> 513 #include <time.h> 514 #include <wchar.h> 515 int main () 516 { 517 /* This fails on Solaris 8 and 9. */ 518 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) 519 { 520 mbstate_t state; 521 wchar_t wc; 522 523 memset (&state, '\0', sizeof (mbstate_t)); 524 if (mbrtowc (&wc, "", 1, &state) != 0) 525 return 1; 526 } 527 return 0; 528 }]])], 529 [gl_cv_func_mbrtowc_nul_retval=yes], 530 [gl_cv_func_mbrtowc_nul_retval=no], 531 [:]) 532 fi 533 ]) 534 ]) 535 536 # Prerequisites of lib/mbrtowc.c. 537 AC_DEFUN([gl_PREREQ_MBRTOWC], [ 538 : 539 ]) 540 541 542 dnl From Paul Eggert 543 544 dnl This is an override of an autoconf macro. 545 546 AC_DEFUN([AC_FUNC_MBRTOWC], 547 [ 548 dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60. 549 AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared], 550 gl_cv_func_mbrtowc, 551 [AC_LINK_IFELSE( 552 [AC_LANG_PROGRAM( 553 [[/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be 554 included before <wchar.h>. 555 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> 556 must be included before <wchar.h>. */ 557 #include <stddef.h> 558 #include <stdio.h> 559 #include <time.h> 560 #include <wchar.h>]], 561 [[wchar_t wc; 562 char const s[] = ""; 563 size_t n = 1; 564 mbstate_t state; 565 return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])], 566 gl_cv_func_mbrtowc=yes, 567 gl_cv_func_mbrtowc=no)]) 568 if test $gl_cv_func_mbrtowc = yes; then 569 AC_DEFINE([HAVE_MBRTOWC], [1], 570 [Define to 1 if mbrtowc and mbstate_t are properly declared.]) 571 fi 572 ]) 573