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