1 # mbrtowc.m4 serial 29 -*- coding: utf-8 -*-
2 dnl Copyright (C) 2001-2002, 2004-2005, 2008-2017 Free Software Foundation,
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.
8 AC_DEFUN([gl_FUNC_MBRTOWC],
10 AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
12 AC_REQUIRE([AC_TYPE_MBSTATE_T])
15 AC_CHECK_FUNCS_ONCE([mbrtowc])
16 if test $ac_cv_func_mbrtowc = no; then
18 AC_CHECK_DECLS([mbrtowc],,, [[
19 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
21 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
22 included before <wchar.h>. */
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
35 if test $REPLACE_MBSTATE_T = 1; then
42 gl_MBRTOWC_EMPTY_INPUT
44 case "$gl_cv_func_mbrtowc_null_arg1" in
46 *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1],
47 [Define if the mbrtowc function has the NULL pwc argument bug.])
51 case "$gl_cv_func_mbrtowc_null_arg2" in
53 *) AC_DEFINE([MBRTOWC_NULL_ARG2_BUG], [1],
54 [Define if the mbrtowc function has the NULL string argument bug.])
58 case "$gl_cv_func_mbrtowc_retval" in
60 *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1],
61 [Define if the mbrtowc function returns a wrong return value.])
65 case "$gl_cv_func_mbrtowc_nul_retval" in
67 *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1],
68 [Define if the mbrtowc function does not return 0 for a NUL character.])
72 case "$gl_cv_func_mbrtowc_empty_input" in
74 *) AC_DEFINE([MBRTOWC_EMPTY_INPUT_BUG], [1],
75 [Define if the mbrtowc function does not return (size_t) -2
80 case $gl_cv_C_locale_sans_EILSEQ in
82 *) AC_DEFINE([C_LOCALE_MAYBE_EILSEQ], [1],
83 [Define to 1 if the C locale may have encoding errors.])
91 dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that
92 dnl redefines the semantics of the given mbstate_t type.
93 dnl Result is REPLACE_MBSTATE_T.
94 dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to
95 dnl avoid inconsistencies.
97 AC_DEFUN([gl_MBSTATE_T_BROKEN],
99 AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
101 AC_REQUIRE([AC_TYPE_MBSTATE_T])
102 AC_CHECK_FUNCS_ONCE([mbsinit])
103 AC_CHECK_FUNCS_ONCE([mbrtowc])
104 if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
105 gl_MBRTOWC_INCOMPLETE_STATE
106 gl_MBRTOWC_SANITYCHECK
108 case "$gl_cv_func_mbrtowc_incomplete_state" in
110 *) REPLACE_MBSTATE_T=1 ;;
112 case "$gl_cv_func_mbrtowc_sanitycheck" in
114 *) REPLACE_MBSTATE_T=1 ;;
121 dnl Test whether mbrtowc puts the state into non-initial state when parsing an
122 dnl incomplete multibyte character.
123 dnl Result is gl_cv_func_mbrtowc_incomplete_state.
125 AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE],
127 AC_REQUIRE([AC_PROG_CC])
128 AC_REQUIRE([gt_LOCALE_JA])
129 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
130 AC_CACHE_CHECK([whether mbrtowc handles incomplete characters],
131 [gl_cv_func_mbrtowc_incomplete_state],
133 dnl Initial guess, used when cross-compiling or when no suitable locale
137 # Guess no on AIX and OSF/1.
138 aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
139 # Guess yes otherwise.
140 *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
143 if test $LOCALE_JA != none; then
148 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
150 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
151 included before <wchar.h>. */
158 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
160 const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
164 memset (&state, '\0', sizeof (mbstate_t));
165 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
166 if (mbsinit (&state))
171 [gl_cv_func_mbrtowc_incomplete_state=yes],
172 [gl_cv_func_mbrtowc_incomplete_state=no],
178 dnl Test whether mbrtowc works not worse than mbtowc.
179 dnl Result is gl_cv_func_mbrtowc_sanitycheck.
181 AC_DEFUN([gl_MBRTOWC_SANITYCHECK],
183 AC_REQUIRE([AC_PROG_CC])
184 AC_REQUIRE([gt_LOCALE_ZH_CN])
185 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
186 AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc],
187 [gl_cv_func_mbrtowc_sanitycheck],
189 dnl Initial guess, used when cross-compiling or when no suitable locale
193 # Guess no on Solaris 8.
194 solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
195 # Guess yes otherwise.
196 *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;;
199 if test $LOCALE_ZH_CN != none; then
205 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
207 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
208 included before <wchar.h>. */
215 /* This fails on Solaris 8:
216 mbrtowc returns 2, and sets wc to 0x00F0.
217 mbtowc returns 4 (correct) and sets wc to 0x5EDC. */
218 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
220 char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
224 memset (&state, '\0', sizeof (mbstate_t));
225 if (mbrtowc (&wc, input + 3, 6, &state) != 4
226 && mbtowc (&wc, input + 3, 6) == 4)
231 [gl_cv_func_mbrtowc_sanitycheck=yes],
232 [gl_cv_func_mbrtowc_sanitycheck=no],
238 dnl Test whether mbrtowc supports a NULL pwc argument correctly.
239 dnl Result is gl_cv_func_mbrtowc_null_arg1.
241 AC_DEFUN([gl_MBRTOWC_NULL_ARG1],
243 AC_REQUIRE([AC_PROG_CC])
244 AC_REQUIRE([gt_LOCALE_FR_UTF8])
245 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
246 AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument],
247 [gl_cv_func_mbrtowc_null_arg1],
249 dnl Initial guess, used when cross-compiling or when no suitable locale
253 # Guess no on Solaris.
254 solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;;
255 # Guess yes otherwise.
256 *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;;
259 if test $LOCALE_FR_UTF8 != none; then
265 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
267 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
268 included before <wchar.h>. */
277 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
279 char input[] = "\303\237er";
284 memset (&state, '\0', sizeof (mbstate_t));
285 wc = (wchar_t) 0xBADFACE;
286 ret = mbrtowc (&wc, input, 5, &state);
289 if (!mbsinit (&state))
292 memset (&state, '\0', sizeof (mbstate_t));
293 ret = mbrtowc (NULL, input, 5, &state);
294 if (ret != 2) /* Solaris 7 fails here: ret is -1. */
296 if (!mbsinit (&state))
301 [gl_cv_func_mbrtowc_null_arg1=yes],
302 [gl_cv_func_mbrtowc_null_arg1=no],
308 dnl Test whether mbrtowc supports a NULL string argument correctly.
309 dnl Result is gl_cv_func_mbrtowc_null_arg2.
311 AC_DEFUN([gl_MBRTOWC_NULL_ARG2],
313 AC_REQUIRE([AC_PROG_CC])
314 AC_REQUIRE([gt_LOCALE_FR_UTF8])
315 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
316 AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument],
317 [gl_cv_func_mbrtowc_null_arg2],
319 dnl Initial guess, used when cross-compiling or when no suitable locale
324 osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;;
325 # Guess yes otherwise.
326 *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;;
329 if test $LOCALE_FR_UTF8 != none; then
334 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
336 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
337 included before <wchar.h>. */
344 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
350 memset (&state, '\0', sizeof (mbstate_t));
351 wc = (wchar_t) 0xBADFACE;
352 mbrtowc (&wc, NULL, 5, &state);
353 /* Check that wc was not modified. */
354 if (wc != (wchar_t) 0xBADFACE)
359 [gl_cv_func_mbrtowc_null_arg2=yes],
360 [gl_cv_func_mbrtowc_null_arg2=no],
366 dnl Test whether mbrtowc, when parsing the end of a multibyte character,
367 dnl correctly returns the number of bytes that were needed to complete the
368 dnl character (not the total number of bytes of the multibyte character).
369 dnl Result is gl_cv_func_mbrtowc_retval.
371 AC_DEFUN([gl_MBRTOWC_RETVAL],
373 AC_REQUIRE([AC_PROG_CC])
374 AC_REQUIRE([gt_LOCALE_FR_UTF8])
375 AC_REQUIRE([gt_LOCALE_JA])
376 AC_REQUIRE([AC_CANONICAL_HOST])
377 AC_CACHE_CHECK([whether mbrtowc has a correct return value],
378 [gl_cv_func_mbrtowc_retval],
380 dnl Initial guess, used when cross-compiling or when no suitable locale
384 # Guess no on HP-UX, Solaris, native Windows.
385 hpux* | solaris* | mingw*) gl_cv_func_mbrtowc_retval="guessing no" ;;
386 # Guess yes otherwise.
387 *) gl_cv_func_mbrtowc_retval="guessing yes" ;;
390 if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \
391 || { case "$host_os" in mingw*) true;; *) false;; esac; }; then
396 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
398 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
399 included before <wchar.h>. */
407 int found_some_locale = 0;
408 /* This fails on Solaris. */
409 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
411 char input[] = "B\303\274\303\237er"; /* "Büßer" */
415 memset (&state, '\0', sizeof (mbstate_t));
416 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
419 if (mbrtowc (&wc, input + 2, 5, &state) != 1)
422 found_some_locale = 1;
424 /* This fails on HP-UX 11.11. */
425 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
427 char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
431 memset (&state, '\0', sizeof (mbstate_t));
432 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
435 if (mbrtowc (&wc, input + 2, 5, &state) != 2)
438 found_some_locale = 1;
440 /* This fails on native Windows. */
441 if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL)
443 char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */
447 memset (&state, '\0', sizeof (mbstate_t));
448 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
451 if (mbrtowc (&wc, input + 4, 4, &state) != 1)
454 found_some_locale = 1;
456 if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL)
458 char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */
462 memset (&state, '\0', sizeof (mbstate_t));
463 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
466 if (mbrtowc (&wc, input + 4, 4, &state) != 1)
469 found_some_locale = 1;
471 if (setlocale (LC_ALL, "Chinese_China.936") != NULL)
473 char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */
477 memset (&state, '\0', sizeof (mbstate_t));
478 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
481 if (mbrtowc (&wc, input + 4, 4, &state) != 1)
484 found_some_locale = 1;
486 return (found_some_locale ? result : 77);
488 [gl_cv_func_mbrtowc_retval=yes],
489 [if test $? != 77; then
490 gl_cv_func_mbrtowc_retval=no
498 dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0.
499 dnl Result is gl_cv_func_mbrtowc_nul_retval.
501 AC_DEFUN([gl_MBRTOWC_NUL_RETVAL],
503 AC_REQUIRE([AC_PROG_CC])
504 AC_REQUIRE([gt_LOCALE_ZH_CN])
505 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
506 AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character],
507 [gl_cv_func_mbrtowc_nul_retval],
509 dnl Initial guess, used when cross-compiling or when no suitable locale
513 # Guess no on Solaris 8 and 9.
514 solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;;
515 # Guess yes otherwise.
516 *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;;
519 if test $LOCALE_ZH_CN != none; then
524 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
526 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
527 included before <wchar.h>. */
534 /* This fails on Solaris 8 and 9. */
535 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
540 memset (&state, '\0', sizeof (mbstate_t));
541 if (mbrtowc (&wc, "", 1, &state) != 0)
546 [gl_cv_func_mbrtowc_nul_retval=yes],
547 [gl_cv_func_mbrtowc_nul_retval=no],
553 dnl Test whether mbrtowc returns the correct value on empty input.
555 AC_DEFUN([gl_MBRTOWC_EMPTY_INPUT],
557 AC_REQUIRE([AC_PROG_CC])
558 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
559 AC_CACHE_CHECK([whether mbrtowc works on empty input],
560 [gl_cv_func_mbrtowc_empty_input],
562 dnl Initial guess, used when cross-compiling or when no suitable locale
566 # Guess no on AIX and glibc systems.
568 gl_cv_func_mbrtowc_empty_input="guessing no" ;;
569 # Guess yes on native Windows.
570 mingw*) gl_cv_func_mbrtowc_empty_input="guessing yes" ;;
571 *) gl_cv_func_mbrtowc_empty_input="guessing yes" ;;
578 static mbstate_t mbs;
582 return mbrtowc (&wc, "", 0, &mbs) != (size_t) -2;
584 [gl_cv_func_mbrtowc_empty_input=yes],
585 [gl_cv_func_mbrtowc_empty_input=no],
590 dnl Test whether mbrtowc reports encoding errors in the C locale.
591 dnl Although POSIX was never intended to allow this, the GNU C Library
592 dnl and other implementations do it. See:
593 dnl https://sourceware.org/bugzilla/show_bug.cgi?id=19932
595 AC_DEFUN([gl_MBRTOWC_C_LOCALE],
597 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
598 AC_CACHE_CHECK([whether the C locale is free of encoding errors],
599 [gl_cv_C_locale_sans_EILSEQ],
601 dnl Initial guess, used when cross-compiling or when no suitable locale
603 gl_cv_C_locale_sans_EILSEQ="guessing no"
607 [[#include <limits.h>
612 char *locale = setlocale (LC_ALL, "C");
615 for (i = CHAR_MIN; i <= CHAR_MAX; i++)
619 mbstate_t mbs = { 0, };
620 size_t ss = mbrtowc (&wc, &c, 1, &mbs);
626 [gl_cv_C_locale_sans_EILSEQ=yes],
627 [gl_cv_C_locale_sans_EILSEQ=no],
629 # Guess yes on native Windows.
630 mingw*) gl_cv_C_locale_sans_EILSEQ="guessing yes" ;;
636 # Prerequisites of lib/mbrtowc.c.
637 AC_DEFUN([gl_PREREQ_MBRTOWC], [
644 dnl This is an override of an autoconf macro.
646 AC_DEFUN([AC_FUNC_MBRTOWC],
648 dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60.
649 AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared],
650 [gl_cv_func_mbrtowc],
653 [[/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be
654 included before <wchar.h>.
655 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h>
656 must be included before <wchar.h>. */
660 #include <wchar.h>]],
665 return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])],
666 [gl_cv_func_mbrtowc=yes],
667 [gl_cv_func_mbrtowc=no])])
668 if test $gl_cv_func_mbrtowc = yes; then
669 AC_DEFINE([HAVE_MBRTOWC], [1],
670 [Define to 1 if mbrtowc and mbstate_t are properly declared.])