1# mbrtowc.m4 serial 38 -*- coding: utf-8 -*- 2dnl Copyright (C) 2001-2002, 2004-2005, 2008-2021 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 AC_REQUIRE([gl_PTHREADLIB]) 12 AC_CHECK_HEADERS_ONCE([threads.h]) 13 14 AC_REQUIRE([AC_TYPE_MBSTATE_T]) 15 gl_MBSTATE_T_BROKEN 16 17 AC_CHECK_FUNCS_ONCE([mbrtowc]) 18 if test $ac_cv_func_mbrtowc = no; then 19 HAVE_MBRTOWC=0 20 AC_CHECK_DECLS([mbrtowc],,, [[ 21 #include <wchar.h> 22 ]]) 23 if test $ac_cv_have_decl_mbrtowc = yes; then 24 dnl On Minix 3.1.8, the system's <wchar.h> declares mbrtowc() although 25 dnl it does not have the function. Avoid a collision with gnulib's 26 dnl replacement. 27 REPLACE_MBRTOWC=1 28 fi 29 else 30 if test $REPLACE_MBSTATE_T = 1; then 31 REPLACE_MBRTOWC=1 32 else 33 gl_MBRTOWC_NULL_ARG1 34 gl_MBRTOWC_NULL_ARG2 35 gl_MBRTOWC_RETVAL 36 gl_MBRTOWC_NUL_RETVAL 37 gl_MBRTOWC_STORES_INCOMPLETE 38 gl_MBRTOWC_EMPTY_INPUT 39 gl_MBRTOWC_C_LOCALE 40 case "$gl_cv_func_mbrtowc_null_arg1" in 41 *yes) ;; 42 *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1], 43 [Define if the mbrtowc function has the NULL pwc argument bug.]) 44 REPLACE_MBRTOWC=1 45 ;; 46 esac 47 case "$gl_cv_func_mbrtowc_null_arg2" in 48 *yes) ;; 49 *) AC_DEFINE([MBRTOWC_NULL_ARG2_BUG], [1], 50 [Define if the mbrtowc function has the NULL string argument bug.]) 51 REPLACE_MBRTOWC=1 52 ;; 53 esac 54 case "$gl_cv_func_mbrtowc_retval" in 55 *yes) ;; 56 *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1], 57 [Define if the mbrtowc function returns a wrong return value.]) 58 REPLACE_MBRTOWC=1 59 ;; 60 esac 61 case "$gl_cv_func_mbrtowc_nul_retval" in 62 *yes) ;; 63 *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1], 64 [Define if the mbrtowc function does not return 0 for a NUL character.]) 65 REPLACE_MBRTOWC=1 66 ;; 67 esac 68 case "$gl_cv_func_mbrtowc_stores_incomplete" in 69 *no) ;; 70 *) AC_DEFINE([MBRTOWC_STORES_INCOMPLETE_BUG], [1], 71 [Define if the mbrtowc function stores a wide character when reporting incomplete input.]) 72 REPLACE_MBRTOWC=1 73 ;; 74 esac 75 case "$gl_cv_func_mbrtowc_empty_input" in 76 *yes) ;; 77 *) AC_DEFINE([MBRTOWC_EMPTY_INPUT_BUG], [1], 78 [Define if the mbrtowc function does not return (size_t) -2 79 for empty input.]) 80 REPLACE_MBRTOWC=1 81 ;; 82 esac 83 case "$gl_cv_func_mbrtowc_C_locale_sans_EILSEQ" in 84 *yes) ;; 85 *) AC_DEFINE([MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ], [1], 86 [Define if the mbrtowc function may signal encoding errors in the C locale.]) 87 REPLACE_MBRTOWC=1 88 ;; 89 esac 90 fi 91 fi 92 if test $REPLACE_MBSTATE_T = 1; then 93 case "$host_os" in 94 mingw*) LIB_MBRTOWC= ;; 95 *) 96 gl_WEAK_SYMBOLS 97 case "$gl_cv_have_weak" in 98 *yes) LIB_MBRTOWC= ;; 99 *) LIB_MBRTOWC="$LIBPTHREAD" ;; 100 esac 101 ;; 102 esac 103 else 104 LIB_MBRTOWC= 105 fi 106 dnl LIB_MBRTOWC is expected to be '-pthread' or '-lpthread' on AIX 107 dnl with gcc or xlc, and empty otherwise. 108 AC_SUBST([LIB_MBRTOWC]) 109]) 110 111dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that 112dnl redefines the semantics of the given mbstate_t type. 113dnl Result is REPLACE_MBSTATE_T. 114dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to 115dnl avoid inconsistencies. 116 117AC_DEFUN([gl_MBSTATE_T_BROKEN], 118[ 119 AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) 120 AC_REQUIRE([AC_CANONICAL_HOST]) 121 122 AC_REQUIRE([AC_TYPE_MBSTATE_T]) 123 AC_CHECK_FUNCS_ONCE([mbsinit]) 124 AC_CHECK_FUNCS_ONCE([mbrtowc]) 125 dnl On native Windows, we know exactly how mbsinit() behaves and don't need 126 dnl to override it, even if - like on MSVC - mbsinit() is only defined as 127 dnl an inline function, not as a global function. 128 if case "$host_os" in 129 mingw*) true ;; 130 *) test $ac_cv_func_mbsinit = yes ;; 131 esac \ 132 && test $ac_cv_func_mbrtowc = yes; then 133 gl_MBRTOWC_INCOMPLETE_STATE 134 gl_MBRTOWC_SANITYCHECK 135 REPLACE_MBSTATE_T=0 136 case "$gl_cv_func_mbrtowc_incomplete_state" in 137 *yes) ;; 138 *) REPLACE_MBSTATE_T=1 ;; 139 esac 140 case "$gl_cv_func_mbrtowc_sanitycheck" in 141 *yes) ;; 142 *) REPLACE_MBSTATE_T=1 ;; 143 esac 144 else 145 REPLACE_MBSTATE_T=1 146 fi 147]) 148 149dnl Test whether mbrtowc puts the state into non-initial state when parsing an 150dnl incomplete multibyte character. 151dnl Result is gl_cv_func_mbrtowc_incomplete_state. 152 153AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE], 154[ 155 AC_REQUIRE([AC_PROG_CC]) 156 AC_REQUIRE([gt_LOCALE_JA]) 157 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 158 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 159 AC_CACHE_CHECK([whether mbrtowc handles incomplete characters], 160 [gl_cv_func_mbrtowc_incomplete_state], 161 [ 162 dnl Initial guess, used when cross-compiling or when no suitable locale 163 dnl is present. 164changequote(,)dnl 165 case "$host_os" in 166 # Guess no on AIX and OSF/1. 167 aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;; 168 # Guess yes otherwise. 169 *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;; 170 esac 171changequote([,])dnl 172 if test $LOCALE_JA != none; then 173 AC_RUN_IFELSE( 174 [AC_LANG_SOURCE([[ 175#include <locale.h> 176#include <string.h> 177#include <wchar.h> 178int main () 179{ 180 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) 181 { 182 const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */ 183 mbstate_t state; 184 wchar_t wc; 185 186 memset (&state, '\0', sizeof (mbstate_t)); 187 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 188 if (mbsinit (&state)) 189 return 2; 190 } 191 return 0; 192}]])], 193 [gl_cv_func_mbrtowc_incomplete_state=yes], 194 [gl_cv_func_mbrtowc_incomplete_state=no], 195 [:]) 196 else 197 if test $LOCALE_FR_UTF8 != none; then 198 AC_RUN_IFELSE( 199 [AC_LANG_SOURCE([[ 200#include <locale.h> 201#include <string.h> 202#include <wchar.h> 203int main () 204{ 205 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 206 { 207 const char input[] = "B\303\274\303\237er"; /* "Büßer" */ 208 mbstate_t state; 209 wchar_t wc; 210 211 memset (&state, '\0', sizeof (mbstate_t)); 212 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 213 if (mbsinit (&state)) 214 return 2; 215 } 216 return 0; 217}]])], 218 [gl_cv_func_mbrtowc_incomplete_state=yes], 219 [gl_cv_func_mbrtowc_incomplete_state=no], 220 [:]) 221 fi 222 fi 223 ]) 224]) 225 226dnl Test whether mbrtowc works not worse than mbtowc. 227dnl Result is gl_cv_func_mbrtowc_sanitycheck. 228 229AC_DEFUN([gl_MBRTOWC_SANITYCHECK], 230[ 231 AC_REQUIRE([AC_PROG_CC]) 232 AC_REQUIRE([gt_LOCALE_ZH_CN]) 233 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 234 AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc], 235 [gl_cv_func_mbrtowc_sanitycheck], 236 [ 237 dnl Initial guess, used when cross-compiling or when no suitable locale 238 dnl is present. 239changequote(,)dnl 240 case "$host_os" in 241 # Guess no on Solaris 8. 242 solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;; 243 # Guess yes otherwise. 244 *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;; 245 esac 246changequote([,])dnl 247 if test $LOCALE_ZH_CN != none; then 248 AC_RUN_IFELSE( 249 [AC_LANG_SOURCE([[ 250#include <locale.h> 251#include <stdlib.h> 252#include <string.h> 253#include <wchar.h> 254int main () 255{ 256 /* This fails on Solaris 8: 257 mbrtowc returns 2, and sets wc to 0x00F0. 258 mbtowc returns 4 (correct) and sets wc to 0x5EDC. */ 259 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) 260 { 261 char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */ 262 mbstate_t state; 263 wchar_t wc; 264 265 memset (&state, '\0', sizeof (mbstate_t)); 266 if (mbrtowc (&wc, input + 3, 6, &state) != 4 267 && mbtowc (&wc, input + 3, 6) == 4) 268 return 2; 269 } 270 return 0; 271}]])], 272 [gl_cv_func_mbrtowc_sanitycheck=yes], 273 [gl_cv_func_mbrtowc_sanitycheck=no], 274 [:]) 275 fi 276 ]) 277]) 278 279dnl Test whether mbrtowc supports a NULL pwc argument correctly. 280dnl Result is gl_cv_func_mbrtowc_null_arg1. 281 282AC_DEFUN([gl_MBRTOWC_NULL_ARG1], 283[ 284 AC_REQUIRE([AC_PROG_CC]) 285 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 286 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 287 AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument], 288 [gl_cv_func_mbrtowc_null_arg1], 289 [ 290 dnl Initial guess, used when cross-compiling or when no suitable locale 291 dnl is present. 292changequote(,)dnl 293 case "$host_os" in 294 # Guess no on Solaris. 295 solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;; 296 # Guess yes otherwise. 297 *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;; 298 esac 299changequote([,])dnl 300 if test $LOCALE_FR_UTF8 != none; then 301 AC_RUN_IFELSE( 302 [AC_LANG_SOURCE([[ 303#include <locale.h> 304#include <stdlib.h> 305#include <string.h> 306#include <wchar.h> 307int main () 308{ 309 int result = 0; 310 311 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 312 { 313 char input[] = "\303\237er"; 314 mbstate_t state; 315 wchar_t wc; 316 size_t ret; 317 318 memset (&state, '\0', sizeof (mbstate_t)); 319 wc = (wchar_t) 0xBADFACE; 320 ret = mbrtowc (&wc, input, 5, &state); 321 if (ret != 2) 322 result |= 1; 323 if (!mbsinit (&state)) 324 result |= 2; 325 326 memset (&state, '\0', sizeof (mbstate_t)); 327 ret = mbrtowc (NULL, input, 5, &state); 328 if (ret != 2) /* Solaris 7 fails here: ret is -1. */ 329 result |= 4; 330 if (!mbsinit (&state)) 331 result |= 8; 332 } 333 return result; 334}]])], 335 [gl_cv_func_mbrtowc_null_arg1=yes], 336 [gl_cv_func_mbrtowc_null_arg1=no], 337 [:]) 338 fi 339 ]) 340]) 341 342dnl Test whether mbrtowc supports a NULL string argument correctly. 343dnl Result is gl_cv_func_mbrtowc_null_arg2. 344 345AC_DEFUN([gl_MBRTOWC_NULL_ARG2], 346[ 347 AC_REQUIRE([AC_PROG_CC]) 348 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 349 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 350 AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument], 351 [gl_cv_func_mbrtowc_null_arg2], 352 [ 353 dnl Initial guess, used when cross-compiling or when no suitable locale 354 dnl is present. 355changequote(,)dnl 356 case "$host_os" in 357 # Guess no on OSF/1. 358 osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;; 359 # Guess yes otherwise. 360 *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;; 361 esac 362changequote([,])dnl 363 if test $LOCALE_FR_UTF8 != none; then 364 AC_RUN_IFELSE( 365 [AC_LANG_SOURCE([[ 366#include <locale.h> 367#include <string.h> 368#include <wchar.h> 369int main () 370{ 371 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 372 { 373 mbstate_t state; 374 wchar_t wc; 375 int ret; 376 377 memset (&state, '\0', sizeof (mbstate_t)); 378 wc = (wchar_t) 0xBADFACE; 379 mbrtowc (&wc, NULL, 5, &state); 380 /* Check that wc was not modified. */ 381 if (wc != (wchar_t) 0xBADFACE) 382 return 2; 383 } 384 return 0; 385}]])], 386 [gl_cv_func_mbrtowc_null_arg2=yes], 387 [gl_cv_func_mbrtowc_null_arg2=no], 388 [:]) 389 fi 390 ]) 391]) 392 393dnl Test whether mbrtowc, when parsing the end of a multibyte character, 394dnl correctly returns the number of bytes that were needed to complete the 395dnl character (not the total number of bytes of the multibyte character). 396dnl Result is gl_cv_func_mbrtowc_retval. 397 398AC_DEFUN([gl_MBRTOWC_RETVAL], 399[ 400 AC_REQUIRE([AC_PROG_CC]) 401 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 402 AC_REQUIRE([gt_LOCALE_JA]) 403 AC_REQUIRE([AC_CANONICAL_HOST]) 404 AC_CACHE_CHECK([whether mbrtowc has a correct return value], 405 [gl_cv_func_mbrtowc_retval], 406 [ 407 dnl Initial guess, used when cross-compiling or when no suitable locale 408 dnl is present. 409changequote(,)dnl 410 case "$host_os" in 411 # Guess no on HP-UX, Solaris, native Windows. 412 hpux* | solaris* | mingw*) gl_cv_func_mbrtowc_retval="guessing no" ;; 413 # Guess yes otherwise. 414 *) gl_cv_func_mbrtowc_retval="guessing yes" ;; 415 esac 416changequote([,])dnl 417 if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \ 418 || { case "$host_os" in mingw*) true;; *) false;; esac; }; then 419 AC_RUN_IFELSE( 420 [AC_LANG_SOURCE([[ 421#include <locale.h> 422#include <string.h> 423#include <wchar.h> 424int main () 425{ 426 int result = 0; 427 int found_some_locale = 0; 428 /* This fails on Solaris. */ 429 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 430 { 431 char input[] = "B\303\274\303\237er"; /* "Büßer" */ 432 mbstate_t state; 433 wchar_t wc; 434 435 memset (&state, '\0', sizeof (mbstate_t)); 436 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 437 { 438 input[1] = '\0'; 439 if (mbrtowc (&wc, input + 2, 5, &state) != 1) 440 result |= 1; 441 } 442 found_some_locale = 1; 443 } 444 /* This fails on HP-UX 11.11. */ 445 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) 446 { 447 char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */ 448 mbstate_t state; 449 wchar_t wc; 450 451 memset (&state, '\0', sizeof (mbstate_t)); 452 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) 453 { 454 input[1] = '\0'; 455 if (mbrtowc (&wc, input + 2, 5, &state) != 2) 456 result |= 2; 457 } 458 found_some_locale = 1; 459 } 460 /* This fails on native Windows. */ 461 if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL) 462 { 463 char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */ 464 mbstate_t state; 465 wchar_t wc; 466 467 memset (&state, '\0', sizeof (mbstate_t)); 468 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) 469 { 470 input[3] = '\0'; 471 if (mbrtowc (&wc, input + 4, 4, &state) != 1) 472 result |= 4; 473 } 474 found_some_locale = 1; 475 } 476 if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL) 477 { 478 char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */ 479 mbstate_t state; 480 wchar_t wc; 481 482 memset (&state, '\0', sizeof (mbstate_t)); 483 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) 484 { 485 input[3] = '\0'; 486 if (mbrtowc (&wc, input + 4, 4, &state) != 1) 487 result |= 8; 488 } 489 found_some_locale = 1; 490 } 491 if (setlocale (LC_ALL, "Chinese_China.936") != NULL) 492 { 493 char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */ 494 mbstate_t state; 495 wchar_t wc; 496 497 memset (&state, '\0', sizeof (mbstate_t)); 498 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) 499 { 500 input[3] = '\0'; 501 if (mbrtowc (&wc, input + 4, 4, &state) != 1) 502 result |= 16; 503 } 504 found_some_locale = 1; 505 } 506 return (found_some_locale ? result : 77); 507}]])], 508 [gl_cv_func_mbrtowc_retval=yes], 509 [if test $? != 77; then 510 gl_cv_func_mbrtowc_retval=no 511 fi 512 ], 513 [:]) 514 fi 515 ]) 516]) 517 518dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0. 519dnl Result is gl_cv_func_mbrtowc_nul_retval. 520 521AC_DEFUN([gl_MBRTOWC_NUL_RETVAL], 522[ 523 AC_REQUIRE([AC_PROG_CC]) 524 AC_REQUIRE([gt_LOCALE_ZH_CN]) 525 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 526 AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character], 527 [gl_cv_func_mbrtowc_nul_retval], 528 [ 529 dnl Initial guess, used when cross-compiling or when no suitable locale 530 dnl is present. 531changequote(,)dnl 532 case "$host_os" in 533 # Guess no on Solaris 8 and 9. 534 solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;; 535 # Guess yes otherwise. 536 *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;; 537 esac 538changequote([,])dnl 539 if test $LOCALE_ZH_CN != none; then 540 AC_RUN_IFELSE( 541 [AC_LANG_SOURCE([[ 542#include <locale.h> 543#include <string.h> 544#include <wchar.h> 545int main () 546{ 547 /* This fails on Solaris 8 and 9. */ 548 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) 549 { 550 mbstate_t state; 551 wchar_t wc; 552 553 memset (&state, '\0', sizeof (mbstate_t)); 554 if (mbrtowc (&wc, "", 1, &state) != 0) 555 return 2; 556 } 557 return 0; 558}]])], 559 [gl_cv_func_mbrtowc_nul_retval=yes], 560 [gl_cv_func_mbrtowc_nul_retval=no], 561 [:]) 562 fi 563 ]) 564]) 565 566dnl Test whether mbrtowc stores a wide character when reporting incomplete 567dnl input. 568 569AC_DEFUN([gl_MBRTOWC_STORES_INCOMPLETE], 570[ 571 AC_REQUIRE([AC_PROG_CC]) 572 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 573 AC_CACHE_CHECK([whether mbrtowc stores incomplete characters], 574 [gl_cv_func_mbrtowc_stores_incomplete], 575 [ 576 dnl Initial guess, used when cross-compiling or when no suitable locale 577 dnl is present. 578changequote(,)dnl 579 case "$host_os" in 580 # Guess yes on native Windows. 581 mingw*) gl_cv_func_mbrtowc_stores_incomplete="guessing yes" ;; 582 *) gl_cv_func_mbrtowc_stores_incomplete="guessing no" ;; 583 esac 584changequote([,])dnl 585 case "$host_os" in 586 mingw*) 587 AC_RUN_IFELSE( 588 [AC_LANG_SOURCE([[ 589#include <locale.h> 590#include <string.h> 591#include <wchar.h> 592int main () 593{ 594 int result = 0; 595 if (setlocale (LC_ALL, "French_France.65001") != NULL) 596 { 597 wchar_t wc = (wchar_t) 0xBADFACE; 598 mbstate_t state; 599 600 memset (&state, '\0', sizeof (mbstate_t)); 601 if (mbrtowc (&wc, "\303", 1, &state) == (size_t)(-2) 602 && wc != (wchar_t) 0xBADFACE) 603 result |= 1; 604 } 605 if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL) 606 { 607 wchar_t wc = (wchar_t) 0xBADFACE; 608 mbstate_t state; 609 610 memset (&state, '\0', sizeof (mbstate_t)); 611 if (mbrtowc (&wc, "\226", 1, &state) == (size_t)(-2) 612 && wc != (wchar_t) 0xBADFACE) 613 result |= 2; 614 } 615 if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL) 616 { 617 wchar_t wc = (wchar_t) 0xBADFACE; 618 mbstate_t state; 619 620 memset (&state, '\0', sizeof (mbstate_t)); 621 if (mbrtowc (&wc, "\245", 1, &state) == (size_t)(-2) 622 && wc != (wchar_t) 0xBADFACE) 623 result |= 4; 624 } 625 if (setlocale (LC_ALL, "Chinese_China.936") != NULL) 626 { 627 wchar_t wc = (wchar_t) 0xBADFACE; 628 mbstate_t state; 629 630 memset (&state, '\0', sizeof (mbstate_t)); 631 if (mbrtowc (&wc, "\261", 1, &state) == (size_t)(-2) 632 && wc != (wchar_t) 0xBADFACE) 633 result |= 8; 634 } 635 return result; 636}]])], 637 [gl_cv_func_mbrtowc_stores_incomplete=no], 638 [gl_cv_func_mbrtowc_stores_incomplete=yes], 639 [:]) 640 ;; 641 *) 642 AC_REQUIRE([gt_LOCALE_FR_UTF8]) 643 if test $LOCALE_FR_UTF8 != none; then 644 AC_RUN_IFELSE( 645 [AC_LANG_SOURCE([[ 646#include <locale.h> 647#include <string.h> 648#include <wchar.h> 649int main () 650{ 651 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) 652 { 653 wchar_t wc = (wchar_t) 0xBADFACE; 654 mbstate_t state; 655 656 memset (&state, '\0', sizeof (mbstate_t)); 657 if (mbrtowc (&wc, "\303", 1, &state) == (size_t)(-2) 658 && wc != (wchar_t) 0xBADFACE) 659 return 1; 660 } 661 return 0; 662}]])], 663 [gl_cv_func_mbrtowc_stores_incomplete=no], 664 [gl_cv_func_mbrtowc_stores_incomplete=yes], 665 [:]) 666 fi 667 ;; 668 esac 669 ]) 670]) 671 672dnl Test whether mbrtowc returns the correct value on empty input. 673 674AC_DEFUN([gl_MBRTOWC_EMPTY_INPUT], 675[ 676 AC_REQUIRE([AC_PROG_CC]) 677 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 678 AC_CACHE_CHECK([whether mbrtowc works on empty input], 679 [gl_cv_func_mbrtowc_empty_input], 680 [ 681 dnl Initial guess, used when cross-compiling or when no suitable locale 682 dnl is present. 683changequote(,)dnl 684 case "$host_os" in 685 # Guess no on AIX and glibc systems. 686 aix* | *-gnu* | gnu*) gl_cv_func_mbrtowc_empty_input="guessing no" ;; 687 # Guess yes on native Windows. 688 mingw*) gl_cv_func_mbrtowc_empty_input="guessing yes" ;; 689 *) gl_cv_func_mbrtowc_empty_input="guessing yes" ;; 690 esac 691changequote([,])dnl 692 AC_RUN_IFELSE( 693 [AC_LANG_SOURCE([[ 694 #include <wchar.h> 695 static wchar_t wc; 696 static mbstate_t mbs; 697 int 698 main (void) 699 { 700 return mbrtowc (&wc, "", 0, &mbs) != (size_t) -2; 701 }]])], 702 [gl_cv_func_mbrtowc_empty_input=yes], 703 [gl_cv_func_mbrtowc_empty_input=no], 704 [:]) 705 ]) 706]) 707 708dnl Test whether mbrtowc reports encoding errors in the C locale. 709dnl Although POSIX was never intended to allow this, the GNU C Library 710dnl and other implementations do it. See: 711dnl https://sourceware.org/bugzilla/show_bug.cgi?id=19932 712 713AC_DEFUN([gl_MBRTOWC_C_LOCALE], 714[ 715 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 716 AC_CACHE_CHECK([whether the C locale is free of encoding errors], 717 [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ], 718 [ 719 dnl Initial guess, used when cross-compiling or when no suitable locale 720 dnl is present. 721 gl_cv_func_mbrtowc_C_locale_sans_EILSEQ="$gl_cross_guess_normal" 722 723 AC_RUN_IFELSE( 724 [AC_LANG_PROGRAM( 725 [[#include <limits.h> 726 #include <locale.h> 727 #include <wchar.h> 728 ]], [[ 729 int i; 730 char *locale = setlocale (LC_ALL, "C"); 731 if (! locale) 732 return 2; 733 for (i = CHAR_MIN; i <= CHAR_MAX; i++) 734 { 735 char c = i; 736 wchar_t wc; 737 mbstate_t mbs = { 0, }; 738 size_t ss = mbrtowc (&wc, &c, 1, &mbs); 739 if (1 < ss) 740 return 3; 741 } 742 return 0; 743 ]])], 744 [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ=yes], 745 [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ=no], 746 [case "$host_os" in 747 # Guess yes on native Windows. 748 mingw*) gl_cv_func_mbrtowc_C_locale_sans_EILSEQ="guessing yes" ;; 749 esac 750 ]) 751 ]) 752]) 753 754# Prerequisites of lib/mbrtowc.c and lib/lc-charset-dispatch.c. 755AC_DEFUN([gl_PREREQ_MBRTOWC], [ 756 AC_REQUIRE([AC_C_INLINE]) 757 : 758]) 759 760# Prerequisites of lib/mbtowc-lock.c. 761AC_DEFUN([gl_PREREQ_MBTOWC_LOCK], 762[ 763 gl_VISIBILITY 764]) 765 766 767dnl From Paul Eggert 768 769dnl This is an override of an autoconf macro. 770 771AC_DEFUN([AC_FUNC_MBRTOWC], 772[ 773 dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60. 774 AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared], 775 [gl_cv_func_mbrtowc], 776 [AC_LINK_IFELSE( 777 [AC_LANG_PROGRAM( 778 [[#include <wchar.h>]], 779 [[wchar_t wc; 780 char const s[] = ""; 781 size_t n = 1; 782 mbstate_t state; 783 return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])], 784 [gl_cv_func_mbrtowc=yes], 785 [gl_cv_func_mbrtowc=no])]) 786 if test $gl_cv_func_mbrtowc = yes; then 787 AC_DEFINE([HAVE_MBRTOWC], [1], 788 [Define to 1 if mbrtowc and mbstate_t are properly declared.]) 789 fi 790]) 791