Merge branch 'upstream' into stable
[gnulib.git] / m4 / mbrlen.m4
1 # mbrlen.m4 serial 5
2 dnl Copyright (C) 2008, 2010-2011 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.
6
7 AC_DEFUN([gl_FUNC_MBRLEN],
8 [
9   AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
10
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   else
17     dnl Most bugs affecting the system's mbrtowc function also affect the
18     dnl mbrlen function. So override mbrlen whenever mbrtowc is overridden.
19     dnl We could also run the individual tests below; the results would be
20     dnl the same.
21     if test $REPLACE_MBRTOWC = 1; then
22       REPLACE_MBRLEN=1
23     fi
24   fi
25   if test $HAVE_MBRLEN = 0 || test $REPLACE_MBRLEN = 1; then
26     gl_REPLACE_WCHAR_H
27     AC_LIBOBJ([mbrlen])
28     gl_PREREQ_MBRLEN
29   fi
30 ])
31
32 dnl Test whether mbrlen puts the state into non-initial state when parsing an
33 dnl incomplete multibyte character.
34 dnl Result is gl_cv_func_mbrlen_incomplete_state.
35
36 AC_DEFUN([gl_MBRLEN_INCOMPLETE_STATE],
37 [
38   AC_REQUIRE([AC_PROG_CC])
39   AC_REQUIRE([gt_LOCALE_JA])
40   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
41   AC_CACHE_CHECK([whether mbrlen handles incomplete characters],
42     [gl_cv_func_mbrlen_incomplete_state],
43     [
44       dnl Initial guess, used when cross-compiling or when no suitable locale
45       dnl is present.
46 changequote(,)dnl
47       case "$host_os" in
48                      # Guess no on AIX and OSF/1.
49         aix* | osf*) gl_cv_func_mbrlen_incomplete_state="guessing no" ;;
50                      # Guess yes otherwise.
51         *)           gl_cv_func_mbrlen_incomplete_state="guessing yes" ;;
52       esac
53 changequote([,])dnl
54       if test $LOCALE_JA != none; then
55         AC_RUN_IFELSE(
56           [AC_LANG_SOURCE([[
57 #include <locale.h>
58 #include <string.h>
59 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
60    <wchar.h>.
61    BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
62    included before <wchar.h>.  */
63 #include <stddef.h>
64 #include <stdio.h>
65 #include <time.h>
66 #include <wchar.h>
67 int main ()
68 {
69   if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
70     {
71       const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
72       mbstate_t state;
73
74       memset (&state, '\0', sizeof (mbstate_t));
75       if (mbrlen (input + 1, 1, &state) == (size_t)(-2))
76         if (mbsinit (&state))
77           return 1;
78     }
79   return 0;
80 }]])],
81           [gl_cv_func_mbrlen_incomplete_state=yes],
82           [gl_cv_func_mbrlen_incomplete_state=no],
83           [])
84       fi
85     ])
86 ])
87
88 dnl Test whether mbrlen, when parsing the end of a multibyte character,
89 dnl correctly returns the number of bytes that were needed to complete the
90 dnl character (not the total number of bytes of the multibyte character).
91 dnl Result is gl_cv_func_mbrlen_retval.
92
93 AC_DEFUN([gl_MBRLEN_RETVAL],
94 [
95   AC_REQUIRE([AC_PROG_CC])
96   AC_REQUIRE([gt_LOCALE_FR_UTF8])
97   AC_REQUIRE([gt_LOCALE_JA])
98   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
99   AC_CACHE_CHECK([whether mbrlen has a correct return value],
100     [gl_cv_func_mbrlen_retval],
101     [
102       dnl Initial guess, used when cross-compiling or when no suitable locale
103       dnl is present.
104 changequote(,)dnl
105       case "$host_os" in
106                           # Guess no on HP-UX and Solaris.
107         hpux* | solaris*) gl_cv_func_mbrlen_retval="guessing no" ;;
108                           # Guess yes otherwise.
109         *)                gl_cv_func_mbrlen_retval="guessing yes" ;;
110       esac
111 changequote([,])dnl
112       if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then
113         AC_RUN_IFELSE(
114           [AC_LANG_SOURCE([[
115 #include <locale.h>
116 #include <string.h>
117 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
118    <wchar.h>.
119    BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
120    included before <wchar.h>.  */
121 #include <stddef.h>
122 #include <stdio.h>
123 #include <time.h>
124 #include <wchar.h>
125 int main ()
126 {
127   int result = 0;
128   /* This fails on Solaris.  */
129   if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
130     {
131       char input[] = "B\303\274\303\237er"; /* "Büßer" */
132       mbstate_t state;
133
134       memset (&state, '\0', sizeof (mbstate_t));
135       if (mbrlen (input + 1, 1, &state) == (size_t)(-2))
136         {
137           input[1] = '\0';
138           if (mbrlen (input + 2, 5, &state) != 1)
139             result |= 1;
140         }
141     }
142   /* This fails on HP-UX 11.11.  */
143   if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
144     {
145       char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
146       mbstate_t state;
147
148       memset (&state, '\0', sizeof (mbstate_t));
149       if (mbrlen (input + 1, 1, &state) == (size_t)(-2))
150         {
151           input[1] = '\0';
152           if (mbrlen (input + 2, 5, &state) != 2)
153             result |= 2;
154         }
155     }
156   return result;
157 }]])],
158           [gl_cv_func_mbrlen_retval=yes],
159           [gl_cv_func_mbrlen_retval=no],
160           [])
161       fi
162     ])
163 ])
164
165 dnl Test whether mbrlen, when parsing a NUL character, correctly returns 0.
166 dnl Result is gl_cv_func_mbrlen_nul_retval.
167
168 AC_DEFUN([gl_MBRLEN_NUL_RETVAL],
169 [
170   AC_REQUIRE([AC_PROG_CC])
171   AC_REQUIRE([gt_LOCALE_ZH_CN])
172   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
173   AC_CACHE_CHECK([whether mbrlen returns 0 when parsing a NUL character],
174     [gl_cv_func_mbrlen_nul_retval],
175     [
176       dnl Initial guess, used when cross-compiling or when no suitable locale
177       dnl is present.
178 changequote(,)dnl
179       case "$host_os" in
180                     # Guess no on Solaris 9.
181         solaris2.9) gl_cv_func_mbrlen_nul_retval="guessing no" ;;
182                     # Guess yes otherwise.
183         *)          gl_cv_func_mbrlen_nul_retval="guessing yes" ;;
184       esac
185 changequote([,])dnl
186       if test $LOCALE_ZH_CN != none; then
187         AC_RUN_IFELSE(
188           [AC_LANG_SOURCE([[
189 #include <locale.h>
190 #include <string.h>
191 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
192    <wchar.h>.
193    BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
194    included before <wchar.h>.  */
195 #include <stddef.h>
196 #include <stdio.h>
197 #include <time.h>
198 #include <wchar.h>
199 int main ()
200 {
201   /* This crashes on Solaris 9 inside __mbrtowc_dense_gb18030.  */
202   if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
203     {
204       mbstate_t state;
205
206       memset (&state, '\0', sizeof (mbstate_t));
207       if (mbrlen ("", 1, &state) != 0)
208         return 1;
209     }
210   return 0;
211 }]])],
212           [gl_cv_func_mbrlen_nul_retval=yes],
213           [gl_cv_func_mbrlen_nul_retval=no],
214           [])
215       fi
216     ])
217 ])
218
219 # Prerequisites of lib/mbrlen.c.
220 AC_DEFUN([gl_PREREQ_MBRLEN], [
221   :
222 ])