string-buffer tests: Avoid test failure on native Windows.
[gnulib.git] / m4 / iconv_open-utf.m4
blob9e0996246bf594eaa0ba616de778df345ba03a78
1 # iconv_open-utf.m4
2 # serial 6
3 dnl Copyright (C) 2007-2024 Free Software Foundation, 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.
8 # A placeholder to ensure that this m4 file gets included by aclocal.
9 AC_DEFUN([gl_FUNC_ICONV_OPEN_UTF], [])
11 AC_DEFUN([gl_FUNC_ICONV_OPEN_UTF_SUPPORT],
13   dnl This macro relies on am_cv_func_iconv and gl_func_iconv_gnu from
14   dnl gl_FUNC_ICONV_OPEN, but is called from within gl_FUNC_ICONV_OPEN.
15   dnl *Not* AC_REQUIRE([gl_FUNC_ICONV_OPEN]).
16   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
17   AC_REQUIRE([gl_ICONV_H_DEFAULTS])
18   if test "$am_cv_func_iconv" = yes; then
19     AC_CACHE_CHECK([whether iconv supports conversion between UTF-8 and UTF-{16,32}{BE,LE}],
20       [gl_cv_func_iconv_supports_utf],
21       [
22         saved_LIBS="$LIBS"
23         LIBS="$LIBS $LIBICONV"
24         AC_RUN_IFELSE(
25           [AC_LANG_SOURCE([[
26 #include <iconv.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 int main ()
33   int result = 0;
34   /* Test conversion from UTF-8 to UTF-16BE with no errors.  */
35   {
36     static const char input[] =
37       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
38     static const char expected[] =
39       "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
40     iconv_t cd;
41     cd = iconv_open ("UTF-16BE", "UTF-8");
42     if (cd == (iconv_t)(-1))
43       result |= 1;
44     else
45       {
46         char buf[100];
47         const char *inptr;
48         size_t inbytesleft;
49         char *outptr;
50         size_t outbytesleft;
51         size_t res;
52         inptr = input;
53         inbytesleft = sizeof (input) - 1;
54         outptr = buf;
55         outbytesleft = sizeof (buf);
56         res = iconv (cd,
57                      (ICONV_CONST char **) &inptr, &inbytesleft,
58                      &outptr, &outbytesleft);
59         if (!(res == 0 && inbytesleft == 0))
60           result |= 1;
61         else if (!(outptr == buf + (sizeof (expected) - 1)))
62           result |= 1;
63         else if (!(memcmp (buf, expected, sizeof (expected) - 1) == 0))
64           result |= 1;
65         else if (!(iconv_close (cd) == 0))
66           result |= 1;
67       }
68   }
69   /* Test conversion from UTF-8 to UTF-16LE with no errors.  */
70   {
71     static const char input[] =
72       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
73     static const char expected[] =
74       "J\000a\000p\000a\000n\000e\000s\000e\000 \000(\000\345\145\054\147\236\212)\000 \000[\000\065\330\015\335\065\330\036\335\065\330\055\335]\000";
75     iconv_t cd;
76     cd = iconv_open ("UTF-16LE", "UTF-8");
77     if (cd == (iconv_t)(-1))
78       result |= 2;
79     else
80       {
81         char buf[100];
82         const char *inptr;
83         size_t inbytesleft;
84         char *outptr;
85         size_t outbytesleft;
86         size_t res;
87         inptr = input;
88         inbytesleft = sizeof (input) - 1;
89         outptr = buf;
90         outbytesleft = sizeof (buf);
91         res = iconv (cd,
92                      (ICONV_CONST char **) &inptr, &inbytesleft,
93                      &outptr, &outbytesleft);
94         if (!(res == 0 && inbytesleft == 0))
95           result |= 2;
96         else if (!(outptr == buf + (sizeof (expected) - 1)))
97           result |= 2;
98         else if (!(memcmp (buf, expected, sizeof (expected) - 1) == 0))
99           result |= 2;
100         else if (!(iconv_close (cd) == 0))
101           result |= 2;
102       }
103   }
104   /* Test conversion from UTF-8 to UTF-32BE with no errors.  */
105   {
106     static const char input[] =
107       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
108     static const char expected[] =
109       "\000\000\000J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\145\345\000\000\147\054\000\000\212\236\000\000\000)\000\000\000 \000\000\000[\000\001\325\015\000\001\325\036\000\001\325\055\000\000\000]";
110     iconv_t cd;
111     cd = iconv_open ("UTF-32BE", "UTF-8");
112     if (cd == (iconv_t)(-1))
113       result |= 4;
114     else
115       {
116         char buf[100];
117         const char *inptr;
118         size_t inbytesleft;
119         char *outptr;
120         size_t outbytesleft;
121         size_t res;
122         inptr = input;
123         inbytesleft = sizeof (input) - 1;
124         outptr = buf;
125         outbytesleft = sizeof (buf);
126         res = iconv (cd,
127                      (ICONV_CONST char **) &inptr, &inbytesleft,
128                      &outptr, &outbytesleft);
129         if (!(res == 0 && inbytesleft == 0))
130           result |= 4;
131         else if (!(outptr == buf + (sizeof (expected) - 1)))
132           result |= 4;
133         else if (!(memcmp (buf, expected, sizeof (expected) - 1) == 0))
134           result |= 4;
135         else if (!(iconv_close (cd) == 0))
136           result |= 4;
137       }
138   }
139   /* Test conversion from UTF-8 to UTF-32LE with no errors.  */
140   {
141     static const char input[] =
142       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
143     static const char expected[] =
144       "J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\000\345\145\000\000\054\147\000\000\236\212\000\000)\000\000\000 \000\000\000[\000\000\000\015\325\001\000\036\325\001\000\055\325\001\000]\000\000\000";
145     iconv_t cd;
146     cd = iconv_open ("UTF-32LE", "UTF-8");
147     if (cd == (iconv_t)(-1))
148       result |= 8;
149     else
150       {
151         char buf[100];
152         const char *inptr;
153         size_t inbytesleft;
154         char *outptr;
155         size_t outbytesleft;
156         size_t res;
157         inptr = input;
158         inbytesleft = sizeof (input) - 1;
159         outptr = buf;
160         outbytesleft = sizeof (buf);
161         res = iconv (cd,
162                      (ICONV_CONST char **) &inptr, &inbytesleft,
163                      &outptr, &outbytesleft);
164         if (!(res == 0 && inbytesleft == 0))
165           result |= 8;
166         else if (!(outptr == buf + (sizeof (expected) - 1)))
167           result |= 8;
168         else if (!(memcmp (buf, expected, sizeof (expected) - 1) == 0))
169           result |= 8;
170         else if (!(iconv_close (cd) == 0))
171           result |= 8;
172       }
173   }
174   /* Test conversion from UTF-16BE to UTF-8 with no errors.
175      This test fails on NetBSD 3.0.  */
176   {
177     static const char input[] =
178       "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
179     static const char expected[] =
180       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
181     iconv_t cd;
182     cd = iconv_open ("UTF-8", "UTF-16BE");
183     if (cd == (iconv_t)(-1))
184       result |= 16;
185     else
186       {
187         char buf[100];
188         const char *inptr;
189         size_t inbytesleft;
190         char *outptr;
191         size_t outbytesleft;
192         size_t res;
193         inptr = input;
194         inbytesleft = sizeof (input) - 1;
195         outptr = buf;
196         outbytesleft = sizeof (buf);
197         res = iconv (cd,
198                      (ICONV_CONST char **) &inptr, &inbytesleft,
199                      &outptr, &outbytesleft);
200         if (!(res == 0 && inbytesleft == 0))
201           result |= 16;
202         else if (!(outptr == buf + (sizeof (expected) - 1)))
203           result |= 16;
204         else if (!(memcmp (buf, expected, sizeof (expected) - 1) == 0))
205           result |= 16;
206         else if (!(iconv_close (cd) == 0))
207           result |= 16;
208       }
209   }
210   return result;
211 }]])],
212           [gl_cv_func_iconv_supports_utf=yes],
213           [gl_cv_func_iconv_supports_utf=no],
214           [
215            dnl We know that GNU libiconv, GNU libc, musl libc, and Solaris >= 9 do.
216            dnl OSF/1 5.1 has these encodings, but inserts a BOM in the "to"
217            dnl direction.
218            gl_cv_func_iconv_supports_utf="$gl_cross_guess_normal"
219            if test $gl_func_iconv_gnu = yes; then
220              gl_cv_func_iconv_supports_utf="guessing yes"
221            else
222 changequote(,)dnl
223              case "$host_os" in
224                *-musl* | midipix*)           gl_cv_func_iconv_supports_utf="guessing yes" ;;
225                solaris2.9 | solaris2.1[0-9]) gl_cv_func_iconv_supports_utf="guessing yes" ;;
226              esac
227 changequote([,])dnl
228            fi
229           ])
230         LIBS="$saved_LIBS"
231       ])
232   fi