9ec93f561575d64d89959130279d6f90154bf0f3
[bpt/guile.git] / m4 / mbrtowc.m4
1 # mbrtowc.m4 serial 16
2 dnl Copyright (C) 2001-2002, 2004-2005, 2008-2010 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.
7
8 AC_DEFUN([gl_FUNC_MBRTOWC],
9 [
10 AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
11
12 AC_REQUIRE([AC_TYPE_MBSTATE_T])
13 gl_MBSTATE_T_BROKEN
14 if test $REPLACE_MBSTATE_T = 1; then
15 REPLACE_MBRTOWC=1
16 fi
17 AC_CHECK_FUNCS_ONCE([mbrtowc])
18 if test $ac_cv_func_mbrtowc = no; then
19 HAVE_MBRTOWC=0
20 fi
21 if test $HAVE_MBRTOWC != 0 && test $REPLACE_MBRTOWC != 1; then
22 gl_MBRTOWC_NULL_ARG
23 gl_MBRTOWC_RETVAL
24 gl_MBRTOWC_NUL_RETVAL
25 case "$gl_cv_func_mbrtowc_null_arg" in
26 *yes) ;;
27 *) AC_DEFINE([MBRTOWC_NULL_ARG_BUG], [1],
28 [Define if the mbrtowc function has the NULL string argument bug.])
29 REPLACE_MBRTOWC=1
30 ;;
31 esac
32 case "$gl_cv_func_mbrtowc_retval" in
33 *yes) ;;
34 *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1],
35 [Define if the mbrtowc function returns a wrong return value.])
36 REPLACE_MBRTOWC=1
37 ;;
38 esac
39 case "$gl_cv_func_mbrtowc_nul_retval" in
40 *yes) ;;
41 *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1],
42 [Define if the mbrtowc function does not return 0 for a NUL character.])
43 REPLACE_MBRTOWC=1
44 ;;
45 esac
46 fi
47 if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
48 gl_REPLACE_WCHAR_H
49 AC_LIBOBJ([mbrtowc])
50 gl_PREREQ_MBRTOWC
51 fi
52 ])
53
54 dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that
55 dnl redefines the semantics of the given mbstate_t type.
56 dnl Result is REPLACE_MBSTATE_T.
57 dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to
58 dnl avoid inconsistencies.
59
60 AC_DEFUN([gl_MBSTATE_T_BROKEN],
61 [
62 AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
63
64 AC_REQUIRE([AC_TYPE_MBSTATE_T])
65 AC_CHECK_FUNCS_ONCE([mbsinit])
66 AC_CHECK_FUNCS_ONCE([mbrtowc])
67 if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
68 gl_MBRTOWC_INCOMPLETE_STATE
69 gl_MBRTOWC_SANITYCHECK
70 REPLACE_MBSTATE_T=0
71 case "$gl_cv_func_mbrtowc_incomplete_state" in
72 *yes) ;;
73 *) REPLACE_MBSTATE_T=1 ;;
74 esac
75 case "$gl_cv_func_mbrtowc_sanitycheck" in
76 *yes) ;;
77 *) REPLACE_MBSTATE_T=1 ;;
78 esac
79 else
80 REPLACE_MBSTATE_T=1
81 fi
82 if test $REPLACE_MBSTATE_T = 1; then
83 gl_REPLACE_WCHAR_H
84 fi
85 ])
86
87 dnl Test whether mbrtowc puts the state into non-initial state when parsing an
88 dnl incomplete multibyte character.
89 dnl Result is gl_cv_func_mbrtowc_incomplete_state.
90
91 AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE],
92 [
93 AC_REQUIRE([AC_PROG_CC])
94 AC_REQUIRE([gt_LOCALE_JA])
95 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
96 AC_CACHE_CHECK([whether mbrtowc handles incomplete characters],
97 [gl_cv_func_mbrtowc_incomplete_state],
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 AIX and OSF/1.
104 osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
105 # Guess yes otherwise.
106 *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
107 esac
108 changequote([,])dnl
109 if test $LOCALE_JA != none; then
110 AC_TRY_RUN([
111 #include <locale.h>
112 #include <string.h>
113 #include <wchar.h>
114 int main ()
115 {
116 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
117 {
118 const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
119 mbstate_t state;
120 wchar_t wc;
121
122 memset (&state, '\0', sizeof (mbstate_t));
123 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
124 if (mbsinit (&state))
125 return 1;
126 }
127 return 0;
128 }],
129 [gl_cv_func_mbrtowc_incomplete_state=yes],
130 [gl_cv_func_mbrtowc_incomplete_state=no],
131 [:])
132 fi
133 ])
134 ])
135
136 dnl Test whether mbrtowc works not worse than mbtowc.
137 dnl Result is gl_cv_func_mbrtowc_sanitycheck.
138
139 AC_DEFUN([gl_MBRTOWC_SANITYCHECK],
140 [
141 AC_REQUIRE([AC_PROG_CC])
142 AC_REQUIRE([gt_LOCALE_ZH_CN])
143 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
144 AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc],
145 [gl_cv_func_mbrtowc_sanitycheck],
146 [
147 dnl Initial guess, used when cross-compiling or when no suitable locale
148 dnl is present.
149 changequote(,)dnl
150 case "$host_os" in
151 # Guess no on Solaris 8.
152 solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
153 # Guess yes otherwise.
154 *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;;
155 esac
156 changequote([,])dnl
157 if test $LOCALE_ZH_CN != none; then
158 AC_TRY_RUN([
159 #include <locale.h>
160 #include <stdlib.h>
161 #include <string.h>
162 #include <wchar.h>
163 int main ()
164 {
165 /* This fails on Solaris 8:
166 mbrtowc returns 2, and sets wc to 0x00F0.
167 mbtowc returns 4 (correct) and sets wc to 0x5EDC. */
168 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
169 {
170 char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
171 mbstate_t state;
172 wchar_t wc;
173
174 memset (&state, '\0', sizeof (mbstate_t));
175 if (mbrtowc (&wc, input + 3, 6, &state) != 4
176 && mbtowc (&wc, input + 3, 6) == 4)
177 return 1;
178 }
179 return 0;
180 }],
181 [gl_cv_func_mbrtowc_sanitycheck=yes],
182 [gl_cv_func_mbrtowc_sanitycheck=no],
183 [:])
184 fi
185 ])
186 ])
187
188 dnl Test whether mbrtowc supports a NULL string argument correctly.
189 dnl Result is gl_cv_func_mbrtowc_null_arg.
190
191 AC_DEFUN([gl_MBRTOWC_NULL_ARG],
192 [
193 AC_REQUIRE([AC_PROG_CC])
194 AC_REQUIRE([gt_LOCALE_FR_UTF8])
195 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
196 AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument],
197 [gl_cv_func_mbrtowc_null_arg],
198 [
199 dnl Initial guess, used when cross-compiling or when no suitable locale
200 dnl is present.
201 changequote(,)dnl
202 case "$host_os" in
203 # Guess no on OSF/1.
204 osf*) gl_cv_func_mbrtowc_null_arg="guessing no" ;;
205 # Guess yes otherwise.
206 *) gl_cv_func_mbrtowc_null_arg="guessing yes" ;;
207 esac
208 changequote([,])dnl
209 if test $LOCALE_FR_UTF8 != none; then
210 AC_TRY_RUN([
211 #include <locale.h>
212 #include <string.h>
213 #include <wchar.h>
214 int main ()
215 {
216 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
217 {
218 mbstate_t state;
219 wchar_t wc;
220 int ret;
221
222 memset (&state, '\0', sizeof (mbstate_t));
223 wc = (wchar_t) 0xBADFACE;
224 mbrtowc (&wc, NULL, 5, &state);
225 /* Check that wc was not modified. */
226 if (wc != (wchar_t) 0xBADFACE)
227 return 1;
228 }
229 return 0;
230 }], [gl_cv_func_mbrtowc_null_arg=yes], [gl_cv_func_mbrtowc_null_arg=no], [:])
231 fi
232 ])
233 ])
234
235 dnl Test whether mbrtowc, when parsing the end of a multibyte character,
236 dnl correctly returns the number of bytes that were needed to complete the
237 dnl character (not the total number of bytes of the multibyte character).
238 dnl Result is gl_cv_func_mbrtowc_retval.
239
240 AC_DEFUN([gl_MBRTOWC_RETVAL],
241 [
242 AC_REQUIRE([AC_PROG_CC])
243 AC_REQUIRE([gt_LOCALE_FR_UTF8])
244 AC_REQUIRE([gt_LOCALE_JA])
245 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
246 AC_CACHE_CHECK([whether mbrtowc has a correct return value],
247 [gl_cv_func_mbrtowc_retval],
248 [
249 dnl Initial guess, used when cross-compiling or when no suitable locale
250 dnl is present.
251 changequote(,)dnl
252 case "$host_os" in
253 # Guess no on HP-UX and Solaris.
254 hpux* | solaris*) gl_cv_func_mbrtowc_retval="guessing no" ;;
255 # Guess yes otherwise.
256 *) gl_cv_func_mbrtowc_retval="guessing yes" ;;
257 esac
258 changequote([,])dnl
259 if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then
260 AC_TRY_RUN([
261 #include <locale.h>
262 #include <string.h>
263 #include <wchar.h>
264 int main ()
265 {
266 /* This fails on Solaris. */
267 if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
268 {
269 char input[] = "B\303\274\303\237er"; /* "Büßer" */
270 mbstate_t state;
271 wchar_t wc;
272
273 memset (&state, '\0', sizeof (mbstate_t));
274 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
275 {
276 input[1] = '\0';
277 if (mbrtowc (&wc, input + 2, 5, &state) != 1)
278 return 1;
279 }
280 }
281 /* This fails on HP-UX 11.11. */
282 if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
283 {
284 char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
285 mbstate_t state;
286 wchar_t wc;
287
288 memset (&state, '\0', sizeof (mbstate_t));
289 if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
290 {
291 input[1] = '\0';
292 if (mbrtowc (&wc, input + 2, 5, &state) != 2)
293 return 1;
294 }
295 }
296 return 0;
297 }],
298 [gl_cv_func_mbrtowc_retval=yes],
299 [gl_cv_func_mbrtowc_retval=no],
300 [:])
301 fi
302 ])
303 ])
304
305 dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0.
306 dnl Result is gl_cv_func_mbrtowc_nul_retval.
307
308 AC_DEFUN([gl_MBRTOWC_NUL_RETVAL],
309 [
310 AC_REQUIRE([AC_PROG_CC])
311 AC_REQUIRE([gt_LOCALE_ZH_CN])
312 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
313 AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character],
314 [gl_cv_func_mbrtowc_nul_retval],
315 [
316 dnl Initial guess, used when cross-compiling or when no suitable locale
317 dnl is present.
318 changequote(,)dnl
319 case "$host_os" in
320 # Guess no on Solaris 8 and 9.
321 solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;;
322 # Guess yes otherwise.
323 *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;;
324 esac
325 changequote([,])dnl
326 if test $LOCALE_ZH_CN != none; then
327 AC_TRY_RUN([
328 #include <locale.h>
329 #include <string.h>
330 #include <wchar.h>
331 int main ()
332 {
333 /* This fails on Solaris 8 and 9. */
334 if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
335 {
336 mbstate_t state;
337 wchar_t wc;
338
339 memset (&state, '\0', sizeof (mbstate_t));
340 if (mbrtowc (&wc, "", 1, &state) != 0)
341 return 1;
342 }
343 return 0;
344 }],
345 [gl_cv_func_mbrtowc_nul_retval=yes],
346 [gl_cv_func_mbrtowc_nul_retval=no],
347 [:])
348 fi
349 ])
350 ])
351
352 # Prerequisites of lib/mbrtowc.c.
353 AC_DEFUN([gl_PREREQ_MBRTOWC], [
354 :
355 ])
356
357
358 dnl From Paul Eggert
359
360 dnl This override of an autoconf macro can be removed when autoconf 2.60 or
361 dnl newer can be assumed everywhere.
362
363 m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.60]),[-1],[
364 AC_DEFUN([AC_FUNC_MBRTOWC],
365 [
366 dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60.
367 AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared],
368 gl_cv_func_mbrtowc,
369 [AC_LINK_IFELSE(
370 [AC_LANG_PROGRAM(
371 [[#include <wchar.h>]],
372 [[wchar_t wc;
373 char const s[] = "";
374 size_t n = 1;
375 mbstate_t state;
376 return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])],
377 gl_cv_func_mbrtowc=yes,
378 gl_cv_func_mbrtowc=no)])
379 if test $gl_cv_func_mbrtowc = yes; then
380 AC_DEFINE([HAVE_MBRTOWC], [1],
381 [Define to 1 if mbrtowc and mbstate_t are properly declared.])
382 fi
383 ])
384 ])