From 67c13e2e5256433627bc730868b4e550f5a4b5f9 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Thu, 11 Mar 2021 12:31:33 -0700 Subject: [PATCH] locale.c: Create new convenience macro glibc doesn't have the querylocale() function, available on some other platforms, such as Darwin and *BSD. However, it instead has the equivalent functionality available through an undocumented feature. This commit allows someone in the know to compile perl to use that feature, and wraps its API with a macro so that the calling code doesn't have to be aware of the different APIs of the two methods. That macro's definition is now done in perl.h, as future commits will use it in other files. Since this is an undocumented feature, I am not currently documenting this wrapper availability. However, it has been used in the field without complaint for a couple of releases, as follows: A more cumbersome substitute method continues to be used to get what it does. But in the past both methods were tried and the program died if they yielded different results. Since no one has complained, I'm fairly confident it works. But sill I'm deferring its more general use. --- locale.c | 22 ++++++++++++++-------- perl.h | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/locale.c b/locale.c index 55290f84129d..ef7aadecb091 100644 --- a/locale.c +++ b/locale.c @@ -493,13 +493,19 @@ S_category_name(const int category) # define querylocale_c(cat) querylocale_i(cat##_INDEX_) # define querylocale_r(cat) querylocale_i(get_category_index(cat,NULL)) -# ifndef HAS_QUERYLOCALE +# ifndef USE_QUERYLOCALE # define USE_PL_CURLOCALES +# else +# if ! defined(HAS_QUERYLOCALE) && defined(_NL_LOCALE_NAME) +# define querylocale_l(index, locale_obj) \ + nl_langinfo_l(_NL_LOCALE_NAME(categories[index]), locale_obj) +# else +# define querylocale_l(index, locale_obj) \ + querylocale(category_masks[index], locale_obj) +# endif # endif # if ! defined(__GLIBC__) || ! defined(USE_LOCALE_MESSAGES) - # define FIX_GLIBC_LC_MESSAGES_BUG(i) - # else /* Invalidate glibc cache of loaded translations, see [perl #134264] */ # include @@ -600,9 +606,9 @@ S_my_querylocale_i(pTHX_ const unsigned int index) return porcelain_setlocale(category, NULL); } -# ifdef HAS_QUERYLOCALE +# ifdef USE_QUERYLOCALE - return (char *) querylocale(category_masks[index], cur_obj); + return (char *) querylocale_l(index, cur_obj); # else @@ -729,7 +735,7 @@ S_emulate_setlocale_i(pTHX_ const unsigned int index, const char * locale) return my_querylocale_i(index); } -# ifndef HAS_QUERYLOCALE +# ifndef USE_QUERYLOCALE if (strEQ(locale, "")) { @@ -1060,10 +1066,10 @@ S_emulate_setlocale_i(pTHX_ const unsigned int index, const char * locale) * locale that got switched to is, as it came from the environment. So * have to find it */ -# ifdef HAS_QUERYLOCALE +# ifdef USE_QUERYLOCALE if (strEQ(locale, "")) { - locale = querylocale(mask, new_obj); + locale = querylocale_l(index, new_obj); } # else diff --git a/perl.h b/perl.h index 94ef54f211dd..602a33a63d35 100644 --- a/perl.h +++ b/perl.h @@ -1318,6 +1318,25 @@ violations are fatal. # endif # endif +/* Allow use of glib's undocumented querylocale() equivalent if asked for, and + * appropriate */ +# ifdef USE_POSIX_2008_LOCALE +# if defined(HAS_QUERYLOCALE) \ + /* Has this internal undocumented item for nl_langinfo() */ \ + || ( defined(_NL_LOCALE_NAME) \ + /* And asked for */ \ + && defined(USE_NL_LOCALE_NAME) \ + /* We need the below because we will be calling it within a \ + * macro, can't have it get messed up by another thread. */ \ + && defined(HAS_THREAD_SAFE_NL_LANGINFO_L) \ + /* On systems that accept any locale name, the real \ + * underlying locale is often returned by this internal \ + * item, so we can't use it */ \ + && ! defined(SETLOCALE_ACCEPTS_ANY_LOCALE_NAME)) +# define USE_QUERYLOCALE +# endif +# endif + /* Microsoft documentation reads in the change log for VS 2015: * "The localeconv function declared in locale.h now works correctly when * per-thread locale is enabled. In previous versions of the library, this