acl-permissions: Fix test-file-has-acl-2.sh failure on Cygwin.
[gnulib.git] / m4 / wcrtomb.m4
blob35dff6f03796f473ddfa21434a1ec96f0666449b
1 # wcrtomb.m4
2 # serial 19
3 dnl Copyright (C) 2008-2024 Free Software Foundation, 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_WCRTOMB],
10   AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
12   AC_REQUIRE([AC_TYPE_MBSTATE_T])
13   gl_MBSTATE_T_BROKEN
15   AC_CHECK_FUNCS_ONCE([wcrtomb])
16   if test $ac_cv_func_wcrtomb = no; then
17     HAVE_WCRTOMB=0
18     AC_CHECK_DECLS([wcrtomb],,, [[
19       #include <wchar.h>
20     ]])
21     if test $ac_cv_have_decl_wcrtomb = yes; then
22       dnl On Minix 3.1.8, the system's <wchar.h> declares wcrtomb() although
23       dnl it does not have the function. Avoid a collision with gnulib's
24       dnl replacement.
25       REPLACE_WCRTOMB=1
26     fi
27   else
28     dnl We don't actually need to override wcrtomb when redefining the semantics
29     dnl of the mbstate_t type. Tested on 32-bit AIX.
30     dnl if test $REPLACE_MBSTATE_T = 1; then
31     dnl   REPLACE_WCRTOMB=1
32     dnl fi
33     if test $REPLACE_WCRTOMB = 0; then
34       dnl On Android 4.3, wcrtomb produces wrong characters in the C locale.
35       dnl On AIX 4.3, OSF/1 5.1 and Solaris <= 11.3, wcrtomb (NULL, 0, NULL)
36       dnl sometimes returns 0 instead of 1.
37       AC_REQUIRE([AC_PROG_CC])
38       AC_REQUIRE([gt_LOCALE_FR])
39       AC_REQUIRE([gt_LOCALE_FR_UTF8])
40       AC_REQUIRE([gt_LOCALE_JA])
41       AC_REQUIRE([gt_LOCALE_ZH_CN])
42       AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
43       AC_CACHE_CHECK([whether wcrtomb works in the C locale],
44         [gl_cv_func_wcrtomb_works],
45         [AC_RUN_IFELSE(
46            [AC_LANG_SOURCE([[
47 #include <string.h>
48 #include <stdlib.h>
49 #include <wchar.h>
50 int main ()
52   mbstate_t state;
53   char out[64];
54   int count;
55   memset (&state, 0, sizeof (state));
56   out[0] = 'x';
57   count = wcrtomb (out, L'a', &state);
58   return !(count == 1 && out[0] == 'a');
59 }]])],
60            [gl_cv_func_wcrtomb_works=yes],
61            [gl_cv_func_wcrtomb_works=no],
62            [case "$host_os" in
63                                # Guess no on Android.
64               linux*-android*) gl_cv_func_wcrtomb_works="guessing no";;
65                                # Guess yes otherwise.
66               *)               gl_cv_func_wcrtomb_works="guessing yes";;
67             esac
68            ])
69         ])
70       case "$gl_cv_func_wcrtomb_works" in
71         *yes) ;;
72         *) AC_DEFINE([WCRTOMB_C_LOCALE_BUG], [1],
73              [Define if the wcrtomb function does not work in the C locale.])
74            REPLACE_WCRTOMB=1 ;;
75       esac
76     fi
77     if test $REPLACE_WCRTOMB = 0; then
78       AC_CACHE_CHECK([whether wcrtomb return value is correct],
79         [gl_cv_func_wcrtomb_retval],
80         [
81           dnl Initial guess, used when cross-compiling or when no suitable locale
82           dnl is present.
83 changequote(,)dnl
84           case "$host_os" in
85             # Guess no on AIX 4, OSF/1, Solaris, native Windows.
86             aix4* | osf* | solaris* | mingw* | windows*)
87               gl_cv_func_wcrtomb_retval="guessing no" ;;
88             # Guess yes otherwise.
89             *)
90               gl_cv_func_wcrtomb_retval="guessing yes" ;;
91           esac
92 changequote([,])dnl
93           if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then
94             AC_RUN_IFELSE(
95               [AC_LANG_SOURCE([[
96 #include <locale.h>
97 #include <string.h>
98 #include <wchar.h>
99 #include <stdlib.h>
100 int main ()
102   int result = 0;
103   if (strcmp ("$LOCALE_FR", "none") != 0
104       && setlocale (LC_ALL, "$LOCALE_FR") != NULL)
105     {
106       if (wcrtomb (NULL, 0, NULL) != 1)
107         result |= 1;
108     }
109   if (strcmp ("$LOCALE_FR_UTF8", "none") != 0
110       && setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
111     {
112       if (wcrtomb (NULL, 0, NULL) != 1)
113         result |= 2;
114       {
115         wchar_t wc = (wchar_t) 0xBADFACE;
116         if (mbtowc (&wc, "\303\274", 2) == 2)
117           if (wcrtomb (NULL, wc, NULL) != 1)
118             result |= 2;
119       }
120     }
121   if (strcmp ("$LOCALE_JA", "none") != 0
122       && setlocale (LC_ALL, "$LOCALE_JA") != NULL)
123     {
124       if (wcrtomb (NULL, 0, NULL) != 1)
125         result |= 4;
126     }
127   if (strcmp ("$LOCALE_ZH_CN", "none") != 0
128       && setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
129     {
130       if (wcrtomb (NULL, 0, NULL) != 1)
131         result |= 8;
132     }
133   return result;
134 }]])],
135               [gl_cv_func_wcrtomb_retval=yes],
136               [gl_cv_func_wcrtomb_retval=no],
137               [:])
138           fi
139         ])
140       case "$gl_cv_func_wcrtomb_retval" in
141         *yes) ;;
142         *) AC_DEFINE([WCRTOMB_RETVAL_BUG], [1],
143              [Define if the wcrtomb function has an incorrect return value.])
144            REPLACE_WCRTOMB=1 ;;
145       esac
146     fi
147   fi
150 # Prerequisites of lib/wcrtomb.c.
151 AC_DEFUN([gl_PREREQ_WCRTOMB], [
152   :