From 983657832c6512640b8b4c8072e7ec39ab48fa60 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Tue, 4 Apr 2023 19:01:16 -0600 Subject: [PATCH] locale.c: Create is_disparate_LC_ALL() This macro uses the results of the new Configure probe that tells us how the platform represents disparate LC_ALL strings. --- locale.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/locale.c b/locale.c index 580160b55838..e3b6eae5631e 100644 --- a/locale.c +++ b/locale.c @@ -247,6 +247,23 @@ static int debug_initialization = 0; #ifdef USE_LOCALE +/* Not all categories need be set to the same locale. This macro determines if + * 'name' which represents LC_ALL is uniform or disparate. There are two + * situations: 1) the platform uses unordered name=value pairs; 2) the platform + * uses ordered positional values, with a separator string between them */ +# ifdef LC_ALL_SEPARATOR /* positional */ +# define is_disparate_LC_ALL(name) cBOOL(instr(name, LC_ALL_SEPARATOR)) +# else /* name=value */ + + /* In the, hopefully never occurring, event that the platform doesn't use + * either mechanism for disparate LC_ALL's, assume the name=value pairs + * form, rather than taking the extreme step of refusing to compile. Many + * programs won't have disparate locales, so will generally work */ +# define LC_ALL_SEPARATOR ";" +# define is_disparate_LC_ALL(name) cBOOL( strchr(name, ';') \ + && strchr(name, '=')) +# endif + PERL_STATIC_INLINE const char * S_mortalized_pv_copy(pTHX_ const char * const pv) { @@ -1835,10 +1852,7 @@ S_bool_setlocale_2008_i(pTHX_ # endif - /* So far, it has worked that a semi-colon in the locale name means that - * the category is LC_ALL and it subsumes categories which don't all have - * the same locale. This is the glibc syntax. */ - if (strchr(new_locale, ';')) { + if (is_disparate_LC_ALL(new_locale)) { assert(index == LC_ALL_INDEX_); if (setlocale_from_aggregate_LC_ALL(new_locale, line)) {