| 1 | # intl-thread-locale.m4 serial 9
 | 
|---|
| 2 | dnl Copyright (C) 2015-2021 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 | dnl
 | 
|---|
| 7 | dnl This file can be used in projects which are not available under
 | 
|---|
| 8 | dnl the GNU General Public License or the GNU Lesser General Public
 | 
|---|
| 9 | dnl License but which still want to provide support for the GNU gettext
 | 
|---|
| 10 | dnl functionality.
 | 
|---|
| 11 | dnl Please note that the actual code of the GNU gettext library is covered
 | 
|---|
| 12 | dnl by the GNU Lesser General Public License, and the rest of the GNU
 | 
|---|
| 13 | dnl gettext package is covered by the GNU General Public License.
 | 
|---|
| 14 | dnl They are *not* in the public domain.
 | 
|---|
| 15 | 
 | 
|---|
| 16 | dnl Check how to retrieve the name of a per-thread locale (POSIX locale_t).
 | 
|---|
| 17 | dnl Sets gt_nameless_locales.
 | 
|---|
| 18 | AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME],
 | 
|---|
| 19 | [
 | 
|---|
| 20 |   AC_REQUIRE([AC_CANONICAL_HOST])
 | 
|---|
| 21 | 
 | 
|---|
| 22 |   dnl Persuade Solaris <locale.h> to define 'locale_t'.
 | 
|---|
| 23 |   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
 | 
|---|
| 24 | 
 | 
|---|
| 25 |   dnl Test whether uselocale() exists and works at all.
 | 
|---|
| 26 |   gt_FUNC_USELOCALE
 | 
|---|
| 27 | 
 | 
|---|
| 28 |   dnl On OpenBSD >= 6.2, the locale_t type and the uselocale(), newlocale(),
 | 
|---|
| 29 |   dnl duplocale(), freelocale() functions exist but are effectively useless,
 | 
|---|
| 30 |   dnl because the locale_t value depends only on the LC_CTYPE category of the
 | 
|---|
| 31 |   dnl locale and furthermore contains only one bit of information (it
 | 
|---|
| 32 |   dnl distinguishes the "C" locale from the *.UTF-8 locales). See
 | 
|---|
| 33 |   dnl <https://cvsweb.openbsd.org/src/lib/libc/locale/newlocale.c?rev=1.1&content-type=text/x-cvsweb-markup>.
 | 
|---|
| 34 |   dnl In the setlocale() implementation they have thought about the programs
 | 
|---|
| 35 |   dnl that use the API ("Even though only LC_CTYPE has any effect in the
 | 
|---|
| 36 |   dnl OpenBSD base system, store complete information about the global locale,
 | 
|---|
| 37 |   dnl such that third-party software can access it"), but for uselocale()
 | 
|---|
| 38 |   dnl they did not think about the programs.
 | 
|---|
| 39 |   dnl In this situation, even the HAVE_NAMELESS_LOCALES support does not work.
 | 
|---|
| 40 |   dnl So, define HAVE_FAKE_LOCALES and disable all locale_t support.
 | 
|---|
| 41 |   case "$gt_cv_func_uselocale_works" in
 | 
|---|
| 42 |     *yes)
 | 
|---|
| 43 |       AC_CHECK_HEADERS_ONCE([xlocale.h])
 | 
|---|
| 44 |       AC_CACHE_CHECK([for fake locale system (OpenBSD)],
 | 
|---|
| 45 |         [gt_cv_locale_fake],
 | 
|---|
| 46 |         [AC_RUN_IFELSE(
 | 
|---|
| 47 |            [AC_LANG_SOURCE([[
 | 
|---|
| 48 | #include <locale.h>
 | 
|---|
| 49 | #if HAVE_XLOCALE_H
 | 
|---|
| 50 | # include <xlocale.h>
 | 
|---|
| 51 | #endif
 | 
|---|
| 52 | int main ()
 | 
|---|
| 53 | {
 | 
|---|
| 54 |   locale_t loc1, loc2;
 | 
|---|
| 55 |   if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) return 1;
 | 
|---|
| 56 |   if (setlocale (LC_ALL, "fr_FR.UTF-8") == NULL) return 1;
 | 
|---|
| 57 |   loc1 = newlocale (LC_ALL_MASK, "de_DE.UTF-8", (locale_t)0);
 | 
|---|
| 58 |   loc2 = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", (locale_t)0);
 | 
|---|
| 59 |   return !(loc1 == loc2);
 | 
|---|
| 60 | }]])],
 | 
|---|
| 61 |            [gt_cv_locale_fake=yes],
 | 
|---|
| 62 |            [gt_cv_locale_fake=no],
 | 
|---|
| 63 |            [dnl Guess the locale system is fake only on OpenBSD.
 | 
|---|
| 64 |             case "$host_os" in
 | 
|---|
| 65 |               openbsd*) gt_cv_locale_fake="guessing yes" ;;
 | 
|---|
| 66 |               *)        gt_cv_locale_fake="guessing no" ;;
 | 
|---|
| 67 |             esac
 | 
|---|
| 68 |            ])
 | 
|---|
| 69 |         ])
 | 
|---|
| 70 |       ;;
 | 
|---|
| 71 |     *) gt_cv_locale_fake=no ;;
 | 
|---|
| 72 |   esac
 | 
|---|
| 73 |   case "$gt_cv_locale_fake" in
 | 
|---|
| 74 |     *yes)
 | 
|---|
| 75 |       gt_fake_locales=yes
 | 
|---|
| 76 |       AC_DEFINE([HAVE_FAKE_LOCALES], [1],
 | 
|---|
| 77 |         [Define if the locale_t type contains insufficient information, as on OpenBSD.])
 | 
|---|
| 78 |       ;;
 | 
|---|
| 79 |     *)
 | 
|---|
| 80 |       gt_fake_locales=no
 | 
|---|
| 81 |       ;;
 | 
|---|
| 82 |   esac
 | 
|---|
| 83 | 
 | 
|---|
| 84 |   case "$gt_cv_func_uselocale_works" in
 | 
|---|
| 85 |     *yes)
 | 
|---|
| 86 |       AC_CACHE_CHECK([for Solaris 11.4 locale system],
 | 
|---|
| 87 |         [gt_cv_locale_solaris114],
 | 
|---|
| 88 |         [case "$host_os" in
 | 
|---|
| 89 |            solaris*)
 | 
|---|
| 90 |              dnl Test whether <locale.h> defines locale_t as a typedef of
 | 
|---|
| 91 |              dnl 'struct _LC_locale_t **' (whereas Illumos defines it as a
 | 
|---|
| 92 |              dnl typedef of 'struct _locale *').
 | 
|---|
| 93 |              dnl Another possible test would be to include <sys/localedef.h>
 | 
|---|
| 94 |              dnl and test whether it defines the _LC_core_data_locale_t type.
 | 
|---|
| 95 |              dnl This type was added in Solaris 11.4.
 | 
|---|
| 96 |              AC_COMPILE_IFELSE(
 | 
|---|
| 97 |                [AC_LANG_PROGRAM([[
 | 
|---|
| 98 |                   #include <locale.h>
 | 
|---|
| 99 |                   struct _LC_locale_t *x;
 | 
|---|
| 100 |                   locale_t y;
 | 
|---|
| 101 |                 ]],
 | 
|---|
| 102 |                 [[*y = x;]])],
 | 
|---|
| 103 |                [gt_cv_locale_solaris114=yes],
 | 
|---|
| 104 |                [gt_cv_locale_solaris114=no])
 | 
|---|
| 105 |              ;;
 | 
|---|
| 106 |            *) gt_cv_locale_solaris114=no ;;
 | 
|---|
| 107 |          esac
 | 
|---|
| 108 |         ])
 | 
|---|
| 109 |       ;;
 | 
|---|
| 110 |     *) gt_cv_locale_solaris114=no ;;
 | 
|---|
| 111 |   esac
 | 
|---|
| 112 |   if test $gt_cv_locale_solaris114 = yes; then
 | 
|---|
| 113 |     AC_DEFINE([HAVE_SOLARIS114_LOCALES], [1],
 | 
|---|
| 114 |       [Define if the locale_t type is as on Solaris 11.4.])
 | 
|---|
| 115 |   fi
 | 
|---|
| 116 | 
 | 
|---|
| 117 |   dnl Solaris 12 will maybe provide getlocalename_l.  If it does, it will
 | 
|---|
| 118 |   dnl improve the implementation of gl_locale_name_thread(), by removing
 | 
|---|
| 119 |   dnl the use of undocumented structures.
 | 
|---|
| 120 |   case "$gt_cv_func_uselocale_works" in
 | 
|---|
| 121 |     *yes)
 | 
|---|
| 122 |       AC_CHECK_FUNCS([getlocalename_l])
 | 
|---|
| 123 |       ;;
 | 
|---|
| 124 |   esac
 | 
|---|
| 125 | 
 | 
|---|
| 126 |   dnl This code is for platforms where the locale_t type does not provide access
 | 
|---|
| 127 |   dnl to the name of each locale category.  This code has the drawback that it
 | 
|---|
| 128 |   dnl requires the gnulib overrides of 'newlocale', 'duplocale', 'freelocale',
 | 
|---|
| 129 |   dnl which is a problem for GNU libunistring.  Therefore try hard to avoid
 | 
|---|
| 130 |   dnl enabling this code!
 | 
|---|
| 131 |   gt_nameless_locales=no
 | 
|---|
| 132 |   case "$host_os" in
 | 
|---|
| 133 |     dnl It's needed on AIX 7.2.
 | 
|---|
| 134 |     aix*)
 | 
|---|
| 135 |       gt_nameless_locales=yes
 | 
|---|
| 136 |       AC_DEFINE([HAVE_NAMELESS_LOCALES], [1],
 | 
|---|
| 137 |         [Define if the locale_t type does not contain the name of each locale category.])
 | 
|---|
| 138 |       ;;
 | 
|---|
| 139 |   esac
 | 
|---|
| 140 | 
 | 
|---|
| 141 |   dnl We cannot support uselocale() on platforms where the locale_t type is
 | 
|---|
| 142 |   dnl fake.  So, set
 | 
|---|
| 143 |   dnl   gt_good_uselocale = gt_working_uselocale && !gt_fake_locales.
 | 
|---|
| 144 |   if test $gt_working_uselocale = yes && test $gt_fake_locales = no; then
 | 
|---|
| 145 |     gt_good_uselocale=yes
 | 
|---|
| 146 |     AC_DEFINE([HAVE_GOOD_USELOCALE], [1],
 | 
|---|
| 147 |       [Define if the uselocale exists, may be safely called, and returns sufficient information.])
 | 
|---|
| 148 |   else
 | 
|---|
| 149 |     gt_good_uselocale=no
 | 
|---|
| 150 |   fi
 | 
|---|
| 151 | 
 | 
|---|
| 152 |   dnl Set gt_localename_enhances_locale_funcs to indicate whether localename.c
 | 
|---|
| 153 |   dnl overrides newlocale(), duplocale(), freelocale() to keep track of locale
 | 
|---|
| 154 |   dnl names.
 | 
|---|
| 155 |   if test $gt_good_uselocale = yes && test $gt_nameless_locales = yes; then
 | 
|---|
| 156 |     gt_localename_enhances_locale_funcs=yes
 | 
|---|
| 157 |     LOCALENAME_ENHANCE_LOCALE_FUNCS=1
 | 
|---|
| 158 |     AC_DEFINE([LOCALENAME_ENHANCE_LOCALE_FUNCS], [1],
 | 
|---|
| 159 |       [Define if localename.c overrides newlocale(), duplocale(), freelocale().])
 | 
|---|
| 160 |   else
 | 
|---|
| 161 |     gt_localename_enhances_locale_funcs=no
 | 
|---|
| 162 |   fi
 | 
|---|
| 163 | ])
 | 
|---|
| 164 | 
 | 
|---|
| 165 | dnl Tests whether uselocale() exists and is usable.
 | 
|---|
| 166 | dnl Sets gt_working_uselocale and defines HAVE_WORKING_USELOCALE.
 | 
|---|
| 167 | AC_DEFUN([gt_FUNC_USELOCALE],
 | 
|---|
| 168 | [
 | 
|---|
| 169 |   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
 | 
|---|
| 170 | 
 | 
|---|
| 171 |   dnl Persuade glibc and Solaris <locale.h> to define 'locale_t'.
 | 
|---|
| 172 |   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
 | 
|---|
| 173 | 
 | 
|---|
| 174 |   AC_CHECK_FUNCS_ONCE([uselocale])
 | 
|---|
| 175 | 
 | 
|---|
| 176 |   dnl On AIX 7.2, the uselocale() function is not documented and leads to
 | 
|---|
| 177 |   dnl crashes in subsequent setlocale() invocations.
 | 
|---|
| 178 |   dnl In 2019, some versions of z/OS lack the locale_t type and have a broken
 | 
|---|
| 179 |   dnl uselocale function.
 | 
|---|
| 180 |   if test $ac_cv_func_uselocale = yes; then
 | 
|---|
| 181 |     AC_CHECK_HEADERS_ONCE([xlocale.h])
 | 
|---|
| 182 |     AC_CACHE_CHECK([whether uselocale works],
 | 
|---|
| 183 |       [gt_cv_func_uselocale_works],
 | 
|---|
| 184 |       [AC_RUN_IFELSE(
 | 
|---|
| 185 |          [AC_LANG_SOURCE([[
 | 
|---|
| 186 | #include <locale.h>
 | 
|---|
| 187 | #if HAVE_XLOCALE_H
 | 
|---|
| 188 | # include <xlocale.h>
 | 
|---|
| 189 | #endif
 | 
|---|
| 190 | locale_t loc1;
 | 
|---|
| 191 | int main ()
 | 
|---|
| 192 | {
 | 
|---|
| 193 |   uselocale (NULL);
 | 
|---|
| 194 |   setlocale (LC_ALL, "en_US.UTF-8");
 | 
|---|
| 195 |   return 0;
 | 
|---|
| 196 | }]])],
 | 
|---|
| 197 |          [gt_cv_func_uselocale_works=yes],
 | 
|---|
| 198 |          [gt_cv_func_uselocale_works=no],
 | 
|---|
| 199 |          [# Guess no on AIX and z/OS, yes otherwise.
 | 
|---|
| 200 |           case "$host_os" in
 | 
|---|
| 201 |             aix* | openedition*) gt_cv_func_uselocale_works="guessing no" ;;
 | 
|---|
| 202 |             *)                   gt_cv_func_uselocale_works="guessing yes" ;;
 | 
|---|
| 203 |           esac
 | 
|---|
| 204 |          ])
 | 
|---|
| 205 |       ])
 | 
|---|
| 206 |   else
 | 
|---|
| 207 |     gt_cv_func_uselocale_works=no
 | 
|---|
| 208 |   fi
 | 
|---|
| 209 |   case "$gt_cv_func_uselocale_works" in
 | 
|---|
| 210 |     *yes)
 | 
|---|
| 211 |       gt_working_uselocale=yes
 | 
|---|
| 212 |       AC_DEFINE([HAVE_WORKING_USELOCALE], [1],
 | 
|---|
| 213 |         [Define if the uselocale function exists and may safely be called.])
 | 
|---|
| 214 |       ;;
 | 
|---|
| 215 |     *)
 | 
|---|
| 216 |       gt_working_uselocale=no
 | 
|---|
| 217 |       ;;
 | 
|---|
| 218 |   esac
 | 
|---|
| 219 | ])
 | 
|---|