findprog, relocatable-prog: Ignore directories during PATH search.
[gnulib.git] / m4 / mbrtowc.m4
blob755f8c905079327b056c659dde80866436a9003a
1 # mbrtowc.m4 serial 37  -*- coding: utf-8 -*-
2 dnl Copyright (C) 2001-2002, 2004-2005, 2008-2020 Free Software Foundation,
3 dnl Inc.
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])
11   AC_REQUIRE([gl_PTHREADLIB])
12   AC_CHECK_HEADERS_ONCE([threads.h])
14   AC_REQUIRE([AC_TYPE_MBSTATE_T])
15   gl_MBSTATE_T_BROKEN
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])
118 dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that
119 dnl redefines the semantics of the given mbstate_t type.
120 dnl Result is REPLACE_MBSTATE_T.
121 dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to
122 dnl avoid inconsistencies.
124 AC_DEFUN([gl_MBSTATE_T_BROKEN],
126   AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
127   AC_REQUIRE([AC_CANONICAL_HOST])
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
156 dnl Test whether mbrtowc puts the state into non-initial state when parsing an
157 dnl incomplete multibyte character.
158 dnl Result is gl_cv_func_mbrtowc_incomplete_state.
160 AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE],
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.
171 changequote(,)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
178 changequote([,])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>
192 int main ()
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;
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>
224 int main ()
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;
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     ])
247 dnl Test whether mbrtowc works not worse than mbtowc.
248 dnl Result is gl_cv_func_mbrtowc_sanitycheck.
250 AC_DEFUN([gl_MBRTOWC_SANITYCHECK],
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.
260 changequote(,)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
267 changequote([,])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>
282 int main ()
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;
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     ])
307 dnl Test whether mbrtowc supports a NULL pwc argument correctly.
308 dnl Result is gl_cv_func_mbrtowc_null_arg1.
310 AC_DEFUN([gl_MBRTOWC_NULL_ARG1],
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.
320 changequote(,)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
327 changequote([,])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>
342 int main ()
344   int result = 0;
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;
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;
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     ])
377 dnl Test whether mbrtowc supports a NULL string argument correctly.
378 dnl Result is gl_cv_func_mbrtowc_null_arg2.
380 AC_DEFUN([gl_MBRTOWC_NULL_ARG2],
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.
390 changequote(,)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
397 changequote([,])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>
411 int main ()
413   if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
414     {
415       mbstate_t state;
416       wchar_t wc;
417       int ret;
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     ])
435 dnl Test whether mbrtowc, when parsing the end of a multibyte character,
436 dnl correctly returns the number of bytes that were needed to complete the
437 dnl character (not the total number of bytes of the multibyte character).
438 dnl Result is gl_cv_func_mbrtowc_retval.
440 AC_DEFUN([gl_MBRTOWC_RETVAL],
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.
451 changequote(,)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
458 changequote([,])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>
473 int main ()
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;
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;
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;
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;
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;
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     ])
567 dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0.
568 dnl Result is gl_cv_func_mbrtowc_nul_retval.
570 AC_DEFUN([gl_MBRTOWC_NUL_RETVAL],
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.
580 changequote(,)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
587 changequote([,])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>
601 int main ()
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;
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     ])
622 dnl Test whether mbrtowc stores a wide character when reporting incomplete
623 dnl input.
625 AC_DEFUN([gl_MBRTOWC_STORES_INCOMPLETE],
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.
634 changequote(,)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
640 changequote([,])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>
655 int main ()
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;
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;
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;
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;
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>
719 int main ()
721   if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
722     {
723       wchar_t wc = (wchar_t) 0xBADFACE;
724       mbstate_t state;
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     ])
742 dnl Test whether mbrtowc returns the correct value on empty input.
744 AC_DEFUN([gl_MBRTOWC_EMPTY_INPUT],
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.
753 changequote(,)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
761 changequote([,])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     ])
778 dnl Test whether mbrtowc reports encoding errors in the C locale.
779 dnl Although POSIX was never intended to allow this, the GNU C Library
780 dnl and other implementations do it.  See:
781 dnl https://sourceware.org/bugzilla/show_bug.cgi?id=19932
783 AC_DEFUN([gl_MBRTOWC_C_LOCALE],
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"
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     ])
824 # Prerequisites of lib/mbrtowc.c and lib/lc-charset-dispatch.c.
825 AC_DEFUN([gl_PREREQ_MBRTOWC], [
826   AC_REQUIRE([AC_C_INLINE])
827   :
830 # Prerequisites of lib/mbtowc-lock.c.
831 AC_DEFUN([gl_PREREQ_MBTOWC_LOCK],
833   gl_VISIBILITY
837 dnl From Paul Eggert
839 dnl This is an override of an autoconf macro.
841 AC_DEFUN([AC_FUNC_MBRTOWC],
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