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