mbrtowc.m4 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. # mbrtowc.m4 serial 27 -*- coding: utf-8 -*-
  2. dnl Copyright (C) 2001-2002, 2004-2005, 2008-2017 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. AC_DEFUN([gl_FUNC_MBRTOWC],
  8. [
  9. AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
  10. AC_REQUIRE([AC_TYPE_MBSTATE_T])
  11. gl_MBSTATE_T_BROKEN
  12. AC_CHECK_FUNCS_ONCE([mbrtowc])
  13. if test $ac_cv_func_mbrtowc = no; then
  14. HAVE_MBRTOWC=0
  15. AC_CHECK_DECLS([mbrtowc],,, [[
  16. /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
  17. <wchar.h>.
  18. BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
  19. included before <wchar.h>. */
  20. #include <stddef.h>
  21. #include <stdio.h>
  22. #include <time.h>
  23. #include <wchar.h>
  24. ]])
  25. if test $ac_cv_have_decl_mbrtowc = yes; then
  26. dnl On Minix 3.1.8, the system's <wchar.h> declares mbrtowc() although
  27. dnl it does not have the function. Avoid a collision with gnulib's
  28. dnl replacement.
  29. REPLACE_MBRTOWC=1
  30. fi
  31. else
  32. if test $REPLACE_MBSTATE_T = 1; then
  33. REPLACE_MBRTOWC=1
  34. else
  35. gl_MBRTOWC_NULL_ARG1
  36. gl_MBRTOWC_NULL_ARG2
  37. gl_MBRTOWC_RETVAL
  38. gl_MBRTOWC_NUL_RETVAL
  39. gl_MBRTOWC_EMPTY_INPUT
  40. gl_MBRTOWC_C_LOCALE
  41. case "$gl_cv_func_mbrtowc_null_arg1" in
  42. *yes) ;;
  43. *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1],
  44. [Define if the mbrtowc function has the NULL pwc argument bug.])
  45. REPLACE_MBRTOWC=1
  46. ;;
  47. esac
  48. case "$gl_cv_func_mbrtowc_null_arg2" in
  49. *yes) ;;
  50. *) AC_DEFINE([MBRTOWC_NULL_ARG2_BUG], [1],
  51. [Define if the mbrtowc function has the NULL string argument bug.])
  52. REPLACE_MBRTOWC=1
  53. ;;
  54. esac
  55. case "$gl_cv_func_mbrtowc_retval" in
  56. *yes) ;;
  57. *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1],
  58. [Define if the mbrtowc function returns a wrong return value.])
  59. REPLACE_MBRTOWC=1
  60. ;;
  61. esac
  62. case "$gl_cv_func_mbrtowc_nul_retval" in
  63. *yes) ;;
  64. *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1],
  65. [Define if the mbrtowc function does not return 0 for a NUL character.])
  66. REPLACE_MBRTOWC=1
  67. ;;
  68. esac
  69. case "$gl_cv_func_mbrtowc_empty_input" in
  70. *yes) ;;
  71. *) AC_DEFINE([MBRTOWC_EMPTY_INPUT_BUG], [1],
  72. [Define if the mbrtowc function does not return (size_t) -2
  73. for empty input.])
  74. REPLACE_MBRTOWC=1
  75. ;;
  76. esac
  77. case $gl_cv_C_locale_sans_EILSEQ in
  78. *yes) ;;
  79. *) AC_DEFINE([C_LOCALE_MAYBE_EILSEQ], [1],
  80. [Define to 1 if the C locale may have encoding errors.])
  81. REPLACE_MBRTOWC=1
  82. ;;
  83. esac
  84. fi
  85. fi
  86. ])
  87. dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that
  88. dnl redefines the semantics of the given mbstate_t type.
  89. dnl Result is REPLACE_MBSTATE_T.
  90. dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to
  91. dnl avoid inconsistencies.
  92. AC_DEFUN([gl_MBSTATE_T_BROKEN],
  93. [
  94. AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
  95. AC_REQUIRE([AC_TYPE_MBSTATE_T])
  96. AC_CHECK_FUNCS_ONCE([mbsinit])
  97. AC_CHECK_FUNCS_ONCE([mbrtowc])
  98. if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
  99. gl_MBRTOWC_INCOMPLETE_STATE
  100. gl_MBRTOWC_SANITYCHECK
  101. REPLACE_MBSTATE_T=0
  102. case "$gl_cv_func_mbrtowc_incomplete_state" in
  103. *yes) ;;
  104. *) REPLACE_MBSTATE_T=1 ;;
  105. esac
  106. case "$gl_cv_func_mbrtowc_sanitycheck" in
  107. *yes) ;;
  108. *) REPLACE_MBSTATE_T=1 ;;
  109. esac
  110. else
  111. REPLACE_MBSTATE_T=1
  112. fi
  113. ])
  114. dnl Test whether mbrtowc puts the state into non-initial state when parsing an
  115. dnl incomplete multibyte character.
  116. dnl Result is gl_cv_func_mbrtowc_incomplete_state.
  117. AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE],
  118. [
  119. AC_REQUIRE([AC_PROG_CC])
  120. AC_REQUIRE([gt_LOCALE_JA])
  121. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  122. AC_CACHE_CHECK([whether mbrtowc handles incomplete characters],
  123. [gl_cv_func_mbrtowc_incomplete_state],
  124. [
  125. dnl Initial guess, used when cross-compiling or when no suitable locale
  126. dnl is present.
  127. changequote(,)dnl
  128. case "$host_os" in
  129. # Guess no on AIX and OSF/1.
  130. aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
  131. # Guess yes otherwise.
  132. *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
  133. esac
  134. changequote([,])dnl
  135. if test $LOCALE_JA != none; then
  136. AC_RUN_IFELSE(
  137. [AC_LANG_SOURCE([[
  138. #include <locale.h>
  139. #include <string.h>
  140. /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
  141. <wchar.h>.
  142. BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
  143. included before <wchar.h>. */
  144. #include <stddef.h>
  145. #include <stdio.h>
  146. #include <time.h>
  147. #include <wchar.h>
  148. int main ()
  149. {
  150. if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
  151. {
  152. const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
  153. mbstate_t state;
  154. wchar_t wc;
  155. memset (&state, '\0', sizeof (mbstate_t));
  156. if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
  157. if (mbsinit (&state))
  158. return 2;
  159. }
  160. return 0;
  161. }]])],
  162. [gl_cv_func_mbrtowc_incomplete_state=yes],
  163. [gl_cv_func_mbrtowc_incomplete_state=no],
  164. [:])
  165. fi
  166. ])
  167. ])
  168. dnl Test whether mbrtowc works not worse than mbtowc.
  169. dnl Result is gl_cv_func_mbrtowc_sanitycheck.
  170. AC_DEFUN([gl_MBRTOWC_SANITYCHECK],
  171. [
  172. AC_REQUIRE([AC_PROG_CC])
  173. AC_REQUIRE([gt_LOCALE_ZH_CN])
  174. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  175. AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc],
  176. [gl_cv_func_mbrtowc_sanitycheck],
  177. [
  178. dnl Initial guess, used when cross-compiling or when no suitable locale
  179. dnl is present.
  180. changequote(,)dnl
  181. case "$host_os" in
  182. # Guess no on Solaris 8.
  183. solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
  184. # Guess yes otherwise.
  185. *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;;
  186. esac
  187. changequote([,])dnl
  188. if test $LOCALE_ZH_CN != none; then
  189. AC_RUN_IFELSE(
  190. [AC_LANG_SOURCE([[
  191. #include <locale.h>
  192. #include <stdlib.h>
  193. #include <string.h>
  194. /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
  195. <wchar.h>.
  196. BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
  197. included before <wchar.h>. */
  198. #include <stddef.h>
  199. #include <stdio.h>
  200. #include <time.h>
  201. #include <wchar.h>
  202. int main ()
  203. {
  204. /* This fails on Solaris 8:
  205. mbrtowc returns 2, and sets wc to 0x00F0.
  206. mbtowc returns 4 (correct) and sets wc to 0x5EDC. */
  207. if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
  208. {
  209. char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
  210. mbstate_t state;
  211. wchar_t wc;
  212. memset (&state, '\0', sizeof (mbstate_t));
  213. if (mbrtowc (&wc, input + 3, 6, &state) != 4
  214. && mbtowc (&wc, input + 3, 6) == 4)
  215. return 2;
  216. }
  217. return 0;
  218. }]])],
  219. [gl_cv_func_mbrtowc_sanitycheck=yes],
  220. [gl_cv_func_mbrtowc_sanitycheck=no],
  221. [:])
  222. fi
  223. ])
  224. ])
  225. dnl Test whether mbrtowc supports a NULL pwc argument correctly.
  226. dnl Result is gl_cv_func_mbrtowc_null_arg1.
  227. AC_DEFUN([gl_MBRTOWC_NULL_ARG1],
  228. [
  229. AC_REQUIRE([AC_PROG_CC])
  230. AC_REQUIRE([gt_LOCALE_FR_UTF8])
  231. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  232. AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument],
  233. [gl_cv_func_mbrtowc_null_arg1],
  234. [
  235. dnl Initial guess, used when cross-compiling or when no suitable locale
  236. dnl is present.
  237. changequote(,)dnl
  238. case "$host_os" in
  239. # Guess no on Solaris.
  240. solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;;
  241. # Guess yes otherwise.
  242. *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;;
  243. esac
  244. changequote([,])dnl
  245. if test $LOCALE_FR_UTF8 != none; then
  246. AC_RUN_IFELSE(
  247. [AC_LANG_SOURCE([[
  248. #include <locale.h>
  249. #include <stdlib.h>
  250. #include <string.h>
  251. /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
  252. <wchar.h>.
  253. BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
  254. included before <wchar.h>. */
  255. #include <stddef.h>
  256. #include <stdio.h>
  257. #include <time.h>
  258. #include <wchar.h>
  259. int main ()
  260. {
  261. int result = 0;
  262. if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
  263. {
  264. char input[] = "\303\237er";
  265. mbstate_t state;
  266. wchar_t wc;
  267. size_t ret;
  268. memset (&state, '\0', sizeof (mbstate_t));
  269. wc = (wchar_t) 0xBADFACE;
  270. ret = mbrtowc (&wc, input, 5, &state);
  271. if (ret != 2)
  272. result |= 1;
  273. if (!mbsinit (&state))
  274. result |= 2;
  275. memset (&state, '\0', sizeof (mbstate_t));
  276. ret = mbrtowc (NULL, input, 5, &state);
  277. if (ret != 2) /* Solaris 7 fails here: ret is -1. */
  278. result |= 4;
  279. if (!mbsinit (&state))
  280. result |= 8;
  281. }
  282. return result;
  283. }]])],
  284. [gl_cv_func_mbrtowc_null_arg1=yes],
  285. [gl_cv_func_mbrtowc_null_arg1=no],
  286. [:])
  287. fi
  288. ])
  289. ])
  290. dnl Test whether mbrtowc supports a NULL string argument correctly.
  291. dnl Result is gl_cv_func_mbrtowc_null_arg2.
  292. AC_DEFUN([gl_MBRTOWC_NULL_ARG2],
  293. [
  294. AC_REQUIRE([AC_PROG_CC])
  295. AC_REQUIRE([gt_LOCALE_FR_UTF8])
  296. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  297. AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument],
  298. [gl_cv_func_mbrtowc_null_arg2],
  299. [
  300. dnl Initial guess, used when cross-compiling or when no suitable locale
  301. dnl is present.
  302. changequote(,)dnl
  303. case "$host_os" in
  304. # Guess no on OSF/1.
  305. osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;;
  306. # Guess yes otherwise.
  307. *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;;
  308. esac
  309. changequote([,])dnl
  310. if test $LOCALE_FR_UTF8 != none; then
  311. AC_RUN_IFELSE(
  312. [AC_LANG_SOURCE([[
  313. #include <locale.h>
  314. #include <string.h>
  315. /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
  316. <wchar.h>.
  317. BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
  318. included before <wchar.h>. */
  319. #include <stddef.h>
  320. #include <stdio.h>
  321. #include <time.h>
  322. #include <wchar.h>
  323. int main ()
  324. {
  325. if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
  326. {
  327. mbstate_t state;
  328. wchar_t wc;
  329. int ret;
  330. memset (&state, '\0', sizeof (mbstate_t));
  331. wc = (wchar_t) 0xBADFACE;
  332. mbrtowc (&wc, NULL, 5, &state);
  333. /* Check that wc was not modified. */
  334. if (wc != (wchar_t) 0xBADFACE)
  335. return 2;
  336. }
  337. return 0;
  338. }]])],
  339. [gl_cv_func_mbrtowc_null_arg2=yes],
  340. [gl_cv_func_mbrtowc_null_arg2=no],
  341. [:])
  342. fi
  343. ])
  344. ])
  345. dnl Test whether mbrtowc, when parsing the end of a multibyte character,
  346. dnl correctly returns the number of bytes that were needed to complete the
  347. dnl character (not the total number of bytes of the multibyte character).
  348. dnl Result is gl_cv_func_mbrtowc_retval.
  349. AC_DEFUN([gl_MBRTOWC_RETVAL],
  350. [
  351. AC_REQUIRE([AC_PROG_CC])
  352. AC_REQUIRE([gt_LOCALE_FR_UTF8])
  353. AC_REQUIRE([gt_LOCALE_JA])
  354. AC_REQUIRE([AC_CANONICAL_HOST])
  355. AC_CACHE_CHECK([whether mbrtowc has a correct return value],
  356. [gl_cv_func_mbrtowc_retval],
  357. [
  358. dnl Initial guess, used when cross-compiling or when no suitable locale
  359. dnl is present.
  360. changequote(,)dnl
  361. case "$host_os" in
  362. # Guess no on HP-UX, Solaris, native Windows.
  363. hpux* | solaris* | mingw*) gl_cv_func_mbrtowc_retval="guessing no" ;;
  364. # Guess yes otherwise.
  365. *) gl_cv_func_mbrtowc_retval="guessing yes" ;;
  366. esac
  367. changequote([,])dnl
  368. if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \
  369. || { case "$host_os" in mingw*) true;; *) false;; esac; }; then
  370. AC_RUN_IFELSE(
  371. [AC_LANG_SOURCE([[
  372. #include <locale.h>
  373. #include <string.h>
  374. /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
  375. <wchar.h>.
  376. BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
  377. included before <wchar.h>. */
  378. #include <stddef.h>
  379. #include <stdio.h>
  380. #include <time.h>
  381. #include <wchar.h>
  382. int main ()
  383. {
  384. int result = 0;
  385. int found_some_locale = 0;
  386. /* This fails on Solaris. */
  387. if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
  388. {
  389. char input[] = "B\303\274\303\237er"; /* "Büßer" */
  390. mbstate_t state;
  391. wchar_t wc;
  392. memset (&state, '\0', sizeof (mbstate_t));
  393. if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
  394. {
  395. input[1] = '\0';
  396. if (mbrtowc (&wc, input + 2, 5, &state) != 1)
  397. result |= 1;
  398. }
  399. found_some_locale = 1;
  400. }
  401. /* This fails on HP-UX 11.11. */
  402. if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
  403. {
  404. char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
  405. mbstate_t state;
  406. wchar_t wc;
  407. memset (&state, '\0', sizeof (mbstate_t));
  408. if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
  409. {
  410. input[1] = '\0';
  411. if (mbrtowc (&wc, input + 2, 5, &state) != 2)
  412. result |= 2;
  413. }
  414. found_some_locale = 1;
  415. }
  416. /* This fails on native Windows. */
  417. if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL)
  418. {
  419. char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */
  420. mbstate_t state;
  421. wchar_t wc;
  422. memset (&state, '\0', sizeof (mbstate_t));
  423. if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
  424. {
  425. input[3] = '\0';
  426. if (mbrtowc (&wc, input + 4, 4, &state) != 1)
  427. result |= 4;
  428. }
  429. found_some_locale = 1;
  430. }
  431. if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL)
  432. {
  433. char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */
  434. mbstate_t state;
  435. wchar_t wc;
  436. memset (&state, '\0', sizeof (mbstate_t));
  437. if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
  438. {
  439. input[3] = '\0';
  440. if (mbrtowc (&wc, input + 4, 4, &state) != 1)
  441. result |= 8;
  442. }
  443. found_some_locale = 1;
  444. }
  445. if (setlocale (LC_ALL, "Chinese_China.936") != NULL)
  446. {
  447. char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */
  448. mbstate_t state;
  449. wchar_t wc;
  450. memset (&state, '\0', sizeof (mbstate_t));
  451. if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))
  452. {
  453. input[3] = '\0';
  454. if (mbrtowc (&wc, input + 4, 4, &state) != 1)
  455. result |= 16;
  456. }
  457. found_some_locale = 1;
  458. }
  459. return (found_some_locale ? result : 77);
  460. }]])],
  461. [gl_cv_func_mbrtowc_retval=yes],
  462. [if test $? != 77; then
  463. gl_cv_func_mbrtowc_retval=no
  464. fi
  465. ],
  466. [:])
  467. fi
  468. ])
  469. ])
  470. dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0.
  471. dnl Result is gl_cv_func_mbrtowc_nul_retval.
  472. AC_DEFUN([gl_MBRTOWC_NUL_RETVAL],
  473. [
  474. AC_REQUIRE([AC_PROG_CC])
  475. AC_REQUIRE([gt_LOCALE_ZH_CN])
  476. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  477. AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character],
  478. [gl_cv_func_mbrtowc_nul_retval],
  479. [
  480. dnl Initial guess, used when cross-compiling or when no suitable locale
  481. dnl is present.
  482. changequote(,)dnl
  483. case "$host_os" in
  484. # Guess no on Solaris 8 and 9.
  485. solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;;
  486. # Guess yes otherwise.
  487. *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;;
  488. esac
  489. changequote([,])dnl
  490. if test $LOCALE_ZH_CN != none; then
  491. AC_RUN_IFELSE(
  492. [AC_LANG_SOURCE([[
  493. #include <locale.h>
  494. #include <string.h>
  495. /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
  496. <wchar.h>.
  497. BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
  498. included before <wchar.h>. */
  499. #include <stddef.h>
  500. #include <stdio.h>
  501. #include <time.h>
  502. #include <wchar.h>
  503. int main ()
  504. {
  505. /* This fails on Solaris 8 and 9. */
  506. if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
  507. {
  508. mbstate_t state;
  509. wchar_t wc;
  510. memset (&state, '\0', sizeof (mbstate_t));
  511. if (mbrtowc (&wc, "", 1, &state) != 0)
  512. return 2;
  513. }
  514. return 0;
  515. }]])],
  516. [gl_cv_func_mbrtowc_nul_retval=yes],
  517. [gl_cv_func_mbrtowc_nul_retval=no],
  518. [:])
  519. fi
  520. ])
  521. ])
  522. dnl Test whether mbrtowc returns the correct value on empty input.
  523. AC_DEFUN([gl_MBRTOWC_EMPTY_INPUT],
  524. [
  525. AC_REQUIRE([AC_PROG_CC])
  526. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  527. AC_CACHE_CHECK([whether mbrtowc works on empty input],
  528. [gl_cv_func_mbrtowc_empty_input],
  529. [
  530. dnl Initial guess, used when cross-compiling or when no suitable locale
  531. dnl is present.
  532. changequote(,)dnl
  533. case "$host_os" in
  534. # Guess no on AIX and glibc systems.
  535. aix* | *-gnu*)
  536. gl_cv_func_mbrtowc_empty_input="guessing no" ;;
  537. *) gl_cv_func_mbrtowc_empty_input="guessing yes" ;;
  538. esac
  539. changequote([,])dnl
  540. AC_RUN_IFELSE(
  541. [AC_LANG_SOURCE([[
  542. #include <wchar.h>
  543. static wchar_t wc;
  544. static mbstate_t mbs;
  545. int
  546. main (void)
  547. {
  548. return mbrtowc (&wc, "", 0, &mbs) != (size_t) -2;
  549. }]])],
  550. [gl_cv_func_mbrtowc_empty_input=yes],
  551. [gl_cv_func_mbrtowc_empty_input=no],
  552. [:])
  553. ])
  554. ])
  555. dnl Test whether mbrtowc reports encoding errors in the C locale.
  556. dnl Although POSIX was never intended to allow this, the GNU C Library
  557. dnl and other implementations do it. See:
  558. dnl https://sourceware.org/bugzilla/show_bug.cgi?id=19932
  559. AC_DEFUN([gl_MBRTOWC_C_LOCALE],
  560. [
  561. AC_CACHE_CHECK([whether the C locale is free of encoding errors],
  562. [gl_cv_C_locale_sans_EILSEQ],
  563. [
  564. dnl Initial guess, used when cross-compiling or when no suitable locale
  565. dnl is present.
  566. gl_cv_C_locale_sans_EILSEQ="guessing no"
  567. AC_RUN_IFELSE(
  568. [AC_LANG_PROGRAM(
  569. [[#include <limits.h>
  570. #include <locale.h>
  571. #include <wchar.h>
  572. ]], [[
  573. int i;
  574. char *locale = setlocale (LC_ALL, "C");
  575. if (! locale)
  576. return 2;
  577. for (i = CHAR_MIN; i <= CHAR_MAX; i++)
  578. {
  579. char c = i;
  580. wchar_t wc;
  581. mbstate_t mbs = { 0, };
  582. size_t ss = mbrtowc (&wc, &c, 1, &mbs);
  583. if (1 < ss)
  584. return 3;
  585. }
  586. return 0;
  587. ]])],
  588. [gl_cv_C_locale_sans_EILSEQ=yes],
  589. [gl_cv_C_locale_sans_EILSEQ=no],
  590. [:])])
  591. ])
  592. # Prerequisites of lib/mbrtowc.c.
  593. AC_DEFUN([gl_PREREQ_MBRTOWC], [
  594. :
  595. ])
  596. dnl From Paul Eggert
  597. dnl This is an override of an autoconf macro.
  598. AC_DEFUN([AC_FUNC_MBRTOWC],
  599. [
  600. dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60.
  601. AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared],
  602. gl_cv_func_mbrtowc,
  603. [AC_LINK_IFELSE(
  604. [AC_LANG_PROGRAM(
  605. [[/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be
  606. included before <wchar.h>.
  607. BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h>
  608. must be included before <wchar.h>. */
  609. #include <stddef.h>
  610. #include <stdio.h>
  611. #include <time.h>
  612. #include <wchar.h>]],
  613. [[wchar_t wc;
  614. char const s[] = "";
  615. size_t n = 1;
  616. mbstate_t state;
  617. return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])],
  618. gl_cv_func_mbrtowc=yes,
  619. gl_cv_func_mbrtowc=no)])
  620. if test $gl_cv_func_mbrtowc = yes; then
  621. AC_DEFINE([HAVE_MBRTOWC], [1],
  622. [Define to 1 if mbrtowc and mbstate_t are properly declared.])
  623. fi
  624. ])