1 # mbrtowc.m4 serial 33 -*- coding: utf-8 -*-
2 dnl Copyright (C) 2001-2002, 2004-2005, 2008-2019 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([gt_LOCALE_FR_UTF8])
130 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
131 AC_CACHE_CHECK([whether mbrtowc handles incomplete characters],
132 [gl_cv_func_mbrtowc_incomplete_state],
134 dnl Initial guess, used when cross-compiling or when no suitable locale
138 # Guess no on AIX and OSF/1.
139 aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
140 # Guess yes otherwise.
141 *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
144 if test $LOCALE_JA != none; then
149 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
151 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
152 included before <wchar.h>. */
159 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
161 const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
165 memset (&state, '\0', sizeof (mbstate_t));
166 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
167 if (mbsinit (&state))
172 [gl_cv_func_mbrtowc_incomplete_state=yes],
173 [gl_cv_func_mbrtowc_incomplete_state=no],
176 if test $LOCALE_FR_UTF8 != none; then
181 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
183 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
184 included before <wchar.h>. */
191 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
193 const char input[] = "B\303\274\303\237er"; /* "Büßer" */
197 memset (&state, '\0', sizeof (mbstate_t));
198 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
199 if (mbsinit (&state))
204 [gl_cv_func_mbrtowc_incomplete_state=yes],
205 [gl_cv_func_mbrtowc_incomplete_state=no],
212 dnl Test whether mbrtowc works not worse than mbtowc.
213 dnl Result is gl_cv_func_mbrtowc_sanitycheck.
215 AC_DEFUN([gl_MBRTOWC_SANITYCHECK],
217 AC_REQUIRE([AC_PROG_CC])
218 AC_REQUIRE([gt_LOCALE_ZH_CN])
219 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
220 AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc],
221 [gl_cv_func_mbrtowc_sanitycheck],
223 dnl Initial guess, used when cross-compiling or when no suitable locale
227 # Guess no on Solaris 8.
228 solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
229 # Guess yes otherwise.
230 *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;;
233 if test $LOCALE_ZH_CN != none; then
239 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
241 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
242 included before <wchar.h>. */
249 /* This fails on Solaris 8:
250 mbrtowc returns 2, and sets wc to 0x00F0.
251 mbtowc returns 4 (correct) and sets wc to 0x5EDC. */
252 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
254 char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
258 memset (&state, '\0', sizeof (mbstate_t));
259 if (mbrtowc (&wc, input + 3, 6, &state) != 4
260 && mbtowc (&wc, input + 3, 6) == 4)
265 [gl_cv_func_mbrtowc_sanitycheck=yes],
266 [gl_cv_func_mbrtowc_sanitycheck=no],
272 dnl Test whether mbrtowc supports a NULL pwc argument correctly.
273 dnl Result is gl_cv_func_mbrtowc_null_arg1.
275 AC_DEFUN([gl_MBRTOWC_NULL_ARG1],
277 AC_REQUIRE([AC_PROG_CC])
278 AC_REQUIRE([gt_LOCALE_FR_UTF8])
279 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
280 AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument],
281 [gl_cv_func_mbrtowc_null_arg1],
283 dnl Initial guess, used when cross-compiling or when no suitable locale
287 # Guess no on Solaris.
288 solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;;
289 # Guess yes otherwise.
290 *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;;
293 if test $LOCALE_FR_UTF8 != none; then
299 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
301 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
302 included before <wchar.h>. */
311 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
313 char input[] = "\303\237er";
318 memset (&state, '\0', sizeof (mbstate_t));
319 wc = (wchar_t) 0xBADFACE;
320 ret = mbrtowc (&wc, input, 5, &state);
323 if (!mbsinit (&state))
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. */
330 if (!mbsinit (&state))
335 [gl_cv_func_mbrtowc_null_arg1=yes],
336 [gl_cv_func_mbrtowc_null_arg1=no],
342 dnl Test whether mbrtowc supports a NULL string argument correctly.
343 dnl Result is gl_cv_func_mbrtowc_null_arg2.
345 AC_DEFUN([gl_MBRTOWC_NULL_ARG2],
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],
353 dnl Initial guess, used when cross-compiling or when no suitable locale
358 osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;;
359 # Guess yes otherwise.
360 *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;;
363 if test $LOCALE_FR_UTF8 != none; then
368 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
370 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
371 included before <wchar.h>. */
378 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
384 memset (&state, '\0', sizeof (mbstate_t));
385 wc = (wchar_t) 0xBADFACE;
386 mbrtowc (&wc, NULL, 5, &state);
387 /* Check that wc was not modified. */
388 if (wc != (wchar_t) 0xBADFACE)
393 [gl_cv_func_mbrtowc_null_arg2=yes],
394 [gl_cv_func_mbrtowc_null_arg2=no],
400 dnl Test whether mbrtowc, when parsing the end of a multibyte character,
401 dnl correctly returns the number of bytes that were needed to complete the
402 dnl character (not the total number of bytes of the multibyte character).
403 dnl Result is gl_cv_func_mbrtowc_retval.
405 AC_DEFUN([gl_MBRTOWC_RETVAL],
407 AC_REQUIRE([AC_PROG_CC])
408 AC_REQUIRE([gt_LOCALE_FR_UTF8])
409 AC_REQUIRE([gt_LOCALE_JA])
410 AC_REQUIRE([AC_CANONICAL_HOST])
411 AC_CACHE_CHECK([whether mbrtowc has a correct return value],
412 [gl_cv_func_mbrtowc_retval],
414 dnl Initial guess, used when cross-compiling or when no suitable locale
418 # Guess no on HP-UX, Solaris, native Windows.
419 hpux* | solaris* | mingw*) gl_cv_func_mbrtowc_retval="guessing no" ;;
420 # Guess yes otherwise.
421 *) gl_cv_func_mbrtowc_retval="guessing yes" ;;
424 if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \
425 || { case "$host_os" in mingw*) true;; *) false;; esac; }; then
430 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
432 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
433 included before <wchar.h>. */
441 int found_some_locale = 0;
442 /* This fails on Solaris. */
443 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
445 char input[] = "B\303\274\303\237er"; /* "Büßer" */
449 memset (&state, '\0', sizeof (mbstate_t));
450 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
453 if (mbrtowc (&wc, input + 2, 5, &state) != 1)
456 found_some_locale = 1;
458 /* This fails on HP-UX 11.11. */
459 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
461 char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
465 memset (&state, '\0', sizeof (mbstate_t));
466 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
469 if (mbrtowc (&wc, input + 2, 5, &state) != 2)
472 found_some_locale = 1;
474 /* This fails on native Windows. */
475 if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL)
477 char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */
481 memset (&state, '\0', sizeof (mbstate_t));
482 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
485 if (mbrtowc (&wc, input + 4, 4, &state) != 1)
488 found_some_locale = 1;
490 if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL)
492 char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */
496 memset (&state, '\0', sizeof (mbstate_t));
497 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
500 if (mbrtowc (&wc, input + 4, 4, &state) != 1)
503 found_some_locale = 1;
505 if (setlocale (LC_ALL, "Chinese_China.936") != NULL)
507 char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */
511 memset (&state, '\0', sizeof (mbstate_t));
512 if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
515 if (mbrtowc (&wc, input + 4, 4, &state) != 1)
518 found_some_locale = 1;
520 return (found_some_locale ? result : 77);
522 [gl_cv_func_mbrtowc_retval=yes],
523 [if test $? != 77; then
524 gl_cv_func_mbrtowc_retval=no
532 dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0.
533 dnl Result is gl_cv_func_mbrtowc_nul_retval.
535 AC_DEFUN([gl_MBRTOWC_NUL_RETVAL],
537 AC_REQUIRE([AC_PROG_CC])
538 AC_REQUIRE([gt_LOCALE_ZH_CN])
539 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
540 AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character],
541 [gl_cv_func_mbrtowc_nul_retval],
543 dnl Initial guess, used when cross-compiling or when no suitable locale
547 # Guess no on Solaris 8 and 9.
548 solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;;
549 # Guess yes otherwise.
550 *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;;
553 if test $LOCALE_ZH_CN != none; then
558 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
560 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
561 included before <wchar.h>. */
568 /* This fails on Solaris 8 and 9. */
569 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
574 memset (&state, '\0', sizeof (mbstate_t));
575 if (mbrtowc (&wc, "", 1, &state) != 0)
580 [gl_cv_func_mbrtowc_nul_retval=yes],
581 [gl_cv_func_mbrtowc_nul_retval=no],
587 dnl Test whether mbrtowc returns the correct value on empty input.
589 AC_DEFUN([gl_MBRTOWC_EMPTY_INPUT],
591 AC_REQUIRE([AC_PROG_CC])
592 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
593 AC_CACHE_CHECK([whether mbrtowc works on empty input],
594 [gl_cv_func_mbrtowc_empty_input],
596 dnl Initial guess, used when cross-compiling or when no suitable locale
600 # Guess no on AIX and glibc systems.
601 aix* | *-gnu* | gnu*) gl_cv_func_mbrtowc_empty_input="guessing no" ;;
602 # Guess yes on native Windows.
603 mingw*) gl_cv_func_mbrtowc_empty_input="guessing yes" ;;
604 *) gl_cv_func_mbrtowc_empty_input="guessing yes" ;;
611 static mbstate_t mbs;
615 return mbrtowc (&wc, "", 0, &mbs) != (size_t) -2;
617 [gl_cv_func_mbrtowc_empty_input=yes],
618 [gl_cv_func_mbrtowc_empty_input=no],
623 dnl Test whether mbrtowc reports encoding errors in the C locale.
624 dnl Although POSIX was never intended to allow this, the GNU C Library
625 dnl and other implementations do it. See:
626 dnl https://sourceware.org/bugzilla/show_bug.cgi?id=19932
628 AC_DEFUN([gl_MBRTOWC_C_LOCALE],
630 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
631 AC_CACHE_CHECK([whether the C locale is free of encoding errors],
632 [gl_cv_C_locale_sans_EILSEQ],
634 dnl Initial guess, used when cross-compiling or when no suitable locale
636 gl_cv_C_locale_sans_EILSEQ="$gl_cross_guess_normal"
640 [[#include <limits.h>
645 char *locale = setlocale (LC_ALL, "C");
648 for (i = CHAR_MIN; i <= CHAR_MAX; i++)
652 mbstate_t mbs = { 0, };
653 size_t ss = mbrtowc (&wc, &c, 1, &mbs);
659 [gl_cv_C_locale_sans_EILSEQ=yes],
660 [gl_cv_C_locale_sans_EILSEQ=no],
662 # Guess yes on native Windows.
663 mingw*) gl_cv_C_locale_sans_EILSEQ="guessing yes" ;;
669 # Prerequisites of lib/mbrtowc.c.
670 AC_DEFUN([gl_PREREQ_MBRTOWC], [
671 AC_REQUIRE([AC_C_INLINE])
678 dnl This is an override of an autoconf macro.
680 AC_DEFUN([AC_FUNC_MBRTOWC],
682 dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60.
683 AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared],
684 [gl_cv_func_mbrtowc],
687 [[/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be
688 included before <wchar.h>.
689 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h>
690 must be included before <wchar.h>. */
694 #include <wchar.h>]],
699 return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])],
700 [gl_cv_func_mbrtowc=yes],
701 [gl_cv_func_mbrtowc=no])])
702 if test $gl_cv_func_mbrtowc = yes; then
703 AC_DEFINE([HAVE_MBRTOWC], [1],
704 [Define to 1 if mbrtowc and mbstate_t are properly declared.])