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