]> git.cworth.org Git - tar/blob - m4/mbrtowc.m4
9ec93f561575d64d89959130279d6f90154bf0f3
[tar] / 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 ])