1# mbrtowc.m4 serial 25 2dnl Copyright (C) 2001-2002, 2004-2005, 2008-2012 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 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 74dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that 75dnl redefines the semantics of the given mbstate_t type. 76dnl Result is REPLACE_MBSTATE_T. 77dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to 78dnl avoid inconsistencies. 79 80AC_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 104dnl Test whether mbrtowc puts the state into non-initial state when parsing an 105dnl incomplete multibyte character. 106dnl Result is gl_cv_func_mbrtowc_incomplete_state. 107 108AC_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. 118changequote(,)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 125changequote([,])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> 139int main () 140{ 141 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) 142 { 143 const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */ 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 161dnl Test whether mbrtowc works not worse than mbtowc. 162dnl Result is gl_cv_func_mbrtowc_sanitycheck. 163 164AC_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. 174changequote(,)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 181changequote([,])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> 196int 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"; /* "Büßer" */ 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 221dnl Test whether mbrtowc supports a NULL pwc argument correctly. 222dnl Result is gl_cv_func_mbrtowc_null_arg1. 223 224AC_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. 234changequote(,)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 241changequote([,])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> 256int 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 291dnl Test whether mbrtowc supports a NULL string argument correctly. 292dnl Result is gl_cv_func_mbrtowc_null_arg2. 293 294AC_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. 304changequote(,)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 311changequote([,])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> 325int 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 349dnl Test whether mbrtowc, when parsing the end of a multibyte character, 350dnl correctly returns the number of bytes that were needed to complete the 351dnl character (not the total number of bytes of the multibyte character). 352dnl Result is gl_cv_func_mbrtowc_retval. 353 354AC_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. 365changequote(,)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 372changequote([,])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> 387int 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"; /* "Büßer" */ 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"; /* "Büßer" */ 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 481dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0. 482dnl Result is gl_cv_func_mbrtowc_nul_retval. 483 484AC_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. 494changequote(,)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 501changequote([,])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> 515int 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. 537AC_DEFUN([gl_PREREQ_MBRTOWC], [ 538 : 539]) 540 541 542dnl From Paul Eggert 543 544dnl This is an override of an autoconf macro. 545 546AC_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