iconv_open-utf.m4 8.4 KB

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