immutable: Add tests.
[gnulib.git] / m4 / mbrlen.m4
blob6abf817f2c40ec6d408fe5c0ef9ed35874192588
1 # mbrlen.m4 serial 11  -*- coding: utf-8 -*-
2 dnl Copyright (C) 2008, 2010-2021 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
7 AC_DEFUN([gl_FUNC_MBRLEN],
9   AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
11   AC_REQUIRE([AC_TYPE_MBSTATE_T])
12   AC_REQUIRE([gl_FUNC_MBRTOWC])
13   AC_CHECK_FUNCS_ONCE([mbrlen])
14   if test $ac_cv_func_mbrlen = no; then
15     HAVE_MBRLEN=0
16     AC_CHECK_DECLS([mbrlen],,, [[
17       #include <wchar.h>
18     ]])
19     if test $ac_cv_have_decl_mbrlen = yes; then
20       dnl On Minix 3.1.8, the system's <wchar.h> declares mbrlen() although
21       dnl it does not have the function. Avoid a collision with gnulib's
22       dnl replacement.
23       REPLACE_MBRLEN=1
24     fi
25   else
26     dnl Most bugs affecting the system's mbrtowc function also affect the
27     dnl mbrlen function. So override mbrlen whenever mbrtowc is overridden.
28     dnl We could also run the individual tests below; the results would be
29     dnl the same.
30     if test $REPLACE_MBRTOWC = 1; then
31       REPLACE_MBRLEN=1
32     fi
33   fi
36 dnl Test whether mbrlen puts the state into non-initial state when parsing an
37 dnl incomplete multibyte character.
38 dnl Result is gl_cv_func_mbrlen_incomplete_state.
40 AC_DEFUN([gl_MBRLEN_INCOMPLETE_STATE],
42   AC_REQUIRE([AC_PROG_CC])
43   AC_REQUIRE([gt_LOCALE_JA])
44   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
45   AC_CACHE_CHECK([whether mbrlen handles incomplete characters],
46     [gl_cv_func_mbrlen_incomplete_state],
47     [
48       dnl Initial guess, used when cross-compiling or when no suitable locale
49       dnl is present.
50 changequote(,)dnl
51       case "$host_os" in
52                      # Guess no on AIX and OSF/1.
53         aix* | osf*) gl_cv_func_mbrlen_incomplete_state="guessing no" ;;
54                      # Guess yes otherwise.
55         *)           gl_cv_func_mbrlen_incomplete_state="guessing yes" ;;
56       esac
57 changequote([,])dnl
58       if test $LOCALE_JA != none; then
59         AC_RUN_IFELSE(
60           [AC_LANG_SOURCE([[
61 #include <locale.h>
62 #include <string.h>
63 #include <wchar.h>
64 int main ()
66   if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
67     {
68       const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
69       mbstate_t state;
71       memset (&state, '\0', sizeof (mbstate_t));
72       if (mbrlen (input + 1, 1, &state) == (size_t)(-2))
73         if (mbsinit (&state))
74           return 1;
75     }
76   return 0;
77 }]])],
78           [gl_cv_func_mbrlen_incomplete_state=yes],
79           [gl_cv_func_mbrlen_incomplete_state=no],
80           [])
81       fi
82     ])
85 dnl Test whether mbrlen, when parsing the end of a multibyte character,
86 dnl correctly returns the number of bytes that were needed to complete the
87 dnl character (not the total number of bytes of the multibyte character).
88 dnl Result is gl_cv_func_mbrlen_retval.
90 AC_DEFUN([gl_MBRLEN_RETVAL],
92   AC_REQUIRE([AC_PROG_CC])
93   AC_REQUIRE([gt_LOCALE_FR_UTF8])
94   AC_REQUIRE([gt_LOCALE_JA])
95   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
96   AC_CACHE_CHECK([whether mbrlen has a correct return value],
97     [gl_cv_func_mbrlen_retval],
98     [
99       dnl Initial guess, used when cross-compiling or when no suitable locale
100       dnl is present.
101 changequote(,)dnl
102       case "$host_os" in
103                           # Guess no on HP-UX and Solaris.
104         hpux* | solaris*) gl_cv_func_mbrlen_retval="guessing no" ;;
105                           # Guess yes otherwise.
106         *)                gl_cv_func_mbrlen_retval="guessing yes" ;;
107       esac
108 changequote([,])dnl
109       if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then
110         AC_RUN_IFELSE(
111           [AC_LANG_SOURCE([[
112 #include <locale.h>
113 #include <string.h>
114 #include <wchar.h>
115 int main ()
117   int result = 0;
118   /* This fails on Solaris.  */
119   if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
120     {
121       char input[] = "B\303\274\303\237er"; /* "Büßer" */
122       mbstate_t state;
124       memset (&state, '\0', sizeof (mbstate_t));
125       if (mbrlen (input + 1, 1, &state) == (size_t)(-2))
126         {
127           input[1] = '\0';
128           if (mbrlen (input + 2, 5, &state) != 1)
129             result |= 1;
130         }
131     }
132   /* This fails on HP-UX 11.11.  */
133   if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
134     {
135       char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
136       mbstate_t state;
138       memset (&state, '\0', sizeof (mbstate_t));
139       if (mbrlen (input + 1, 1, &state) == (size_t)(-2))
140         {
141           input[1] = '\0';
142           if (mbrlen (input + 2, 5, &state) != 2)
143             result |= 2;
144         }
145     }
146   return result;
147 }]])],
148           [gl_cv_func_mbrlen_retval=yes],
149           [gl_cv_func_mbrlen_retval=no],
150           [])
151       fi
152     ])
155 dnl Test whether mbrlen, when parsing a NUL character, correctly returns 0.
156 dnl Result is gl_cv_func_mbrlen_nul_retval.
158 AC_DEFUN([gl_MBRLEN_NUL_RETVAL],
160   AC_REQUIRE([AC_PROG_CC])
161   AC_REQUIRE([gt_LOCALE_ZH_CN])
162   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
163   AC_CACHE_CHECK([whether mbrlen returns 0 when parsing a NUL character],
164     [gl_cv_func_mbrlen_nul_retval],
165     [
166       dnl Initial guess, used when cross-compiling or when no suitable locale
167       dnl is present.
168 changequote(,)dnl
169       case "$host_os" in
170                     # Guess no on Solaris 9.
171         solaris2.9) gl_cv_func_mbrlen_nul_retval="guessing no" ;;
172                     # Guess yes otherwise.
173         *)          gl_cv_func_mbrlen_nul_retval="guessing yes" ;;
174       esac
175 changequote([,])dnl
176       if test $LOCALE_ZH_CN != none; then
177         AC_RUN_IFELSE(
178           [AC_LANG_SOURCE([[
179 #include <locale.h>
180 #include <string.h>
181 #include <wchar.h>
182 int main ()
184   /* This crashes on Solaris 9 inside __mbrtowc_dense_gb18030.  */
185   if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
186     {
187       mbstate_t state;
189       memset (&state, '\0', sizeof (mbstate_t));
190       if (mbrlen ("", 1, &state) != 0)
191         return 1;
192     }
193   return 0;
194 }]])],
195           [gl_cv_func_mbrlen_nul_retval=yes],
196           [gl_cv_func_mbrlen_nul_retval=no],
197           [])
198       fi
199     ])
202 dnl Test whether mbrlen returns the correct value on empty input.
204 AC_DEFUN([gl_MBRLEN_EMPTY_INPUT],
206   AC_REQUIRE([AC_PROG_CC])
207   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
208   AC_CACHE_CHECK([whether mbrlen works on empty input],
209     [gl_cv_func_mbrlen_empty_input],
210     [
211       dnl Initial guess, used when cross-compiling or when no suitable locale
212       dnl is present.
213 changequote(,)dnl
214       case "$host_os" in
215                               # Guess no on AIX and glibc systems.
216         aix* | *-gnu* | gnu*) gl_cv_func_mbrlen_empty_input="guessing no" ;;
217         *)                    gl_cv_func_mbrlen_empty_input="guessing yes" ;;
218       esac
219 changequote([,])dnl
220       AC_RUN_IFELSE(
221         [AC_LANG_SOURCE([[
222            #include <wchar.h>
223            static mbstate_t mbs;
224            int
225            main (void)
226            {
227              return mbrlen ("", 0, &mbs) != (size_t) -2;
228            }]])],
229         [gl_cv_func_mbrlen_empty_input=yes],
230         [gl_cv_func_mbrlen_empty_input=no],
231         [:])
232     ])
235 # Prerequisites of lib/mbrlen.c.
236 AC_DEFUN([gl_PREREQ_MBRLEN], [
237   :