diff options
author | Karl Williamson <khw@cpan.org> | 2022-12-17 15:35:04 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2022-12-20 06:16:33 -0700 |
commit | 88da24e71cc8524d6f16ac2a0f44e6d9ff87e0e5 (patch) | |
tree | ce920d7cb8bf74a54cd26384f91519f358b1b3ae /locale.c | |
parent | cb777d7125776d73756033f32e5e2040a8826cc1 (diff) | |
download | perl-88da24e71cc8524d6f16ac2a0f44e6d9ff87e0e5.tar.gz |
Address GH #20571
The blamed commit, 04de022, exposed a bug in the module itself. I will
submit a PR to fix it.
But this ticket did tell me that there was a problem with that commit.
It returned a C language value, CHAR_MAX, which doesn't really have a
corresponding concept in Perl. Instead we use -1 to indicate that a
positive-valued variable is in some abnormal state. This commit changes
to do that, and documents the changes, which should have been done in
04de022.
Diffstat (limited to 'locale.c')
-rw-r--r-- | locale.c | 54 |
1 files changed, 41 insertions, 13 deletions
@@ -3523,15 +3523,21 @@ S_my_localeconv(pTHX_ const int item) /* Here, the hash has been completely populated. * - * Now go through all the string items and see if they should be marked as - * UTF-8 or not. This would have been more convenient and faster to do - * while populating the hash in the first place, but that operation has to - * be done within a critical section, keeping other threads from executing, - * so only the minimal amount of work necessary is done at that time. + * Now go through all the items and: + * a) For string items, see if they should be marked as UTF-8 or not. + * This would have been more convenient and faster to do while + * populating the hash in the first place, but that operation has to be + * done within a critical section, keeping other threads from + * executing, so only the minimal amount of work necessary is done at + * that time. + * b) For integer items, convert the C CHAR_MAX value into -1. Again, + * this could have been done in the critical section, but was deferred + * to here to keep to the bare minimum amount the time spent owning the + * processor. CHAR_MAX is a C concept for an 8-bit character type. + * Perl has no such type; the closest fit is a -1. * - * XXX On unthreaded perls, and on platforms where localeconv (or - * localeconv_l if present) this code could be #ifdef'd out, and the - * UTF8ness determined at hash population time, at an extra maintenance + * XXX On unthreaded perls, this code could be #ifdef'd out, and the + * corrections determined at hash population time, at an extra maintenance * cost which khw doesn't think is worth it */ for (unsigned int i = 0; i < 2; i++) { /* Try both types of strings */ @@ -3592,6 +3598,28 @@ S_my_localeconv(pTHX_ const int item) } } /* End of fixing up UTF8ness */ + + /* Examine each integer */ + if (integers) while (1) { + const char * name = integers->name; + + if (! name) { /* Reached the end */ + break; + } + + SV ** value = hv_fetch(hv, name, strlen(name), true); + if (! value) { + continue; + } + + /* Change CHAR_MAX to -1 */ + if (SvIV(*value) == CHAR_MAX) { + sv_setiv(*value, -1); + } + + integers++; /* Iterate */ + } + return hv; } @@ -4339,14 +4367,14 @@ S_my_langinfo_i(pTHX_ /* The modification is to prefix the localeconv() return with a * single byte, calculated as follows: */ - char prefix = (LIKELY(SvIV(precedes) != CHAR_MAX)) + char prefix = (LIKELY(SvIV(precedes) != -1)) ? ((precedes != 0) ? '-' : '+') /* khw couldn't find any documentation that - * CHAR_MAX is the signal, but cygwin uses it - * thusly, and it makes sense given that CHAR_MAX - * indicates the value isn't used, so it neither - * precedes nor succeeds */ + * CHAR_MAX (which we modify to -1) is the signal, + * but cygwin uses it thusly, and it makes sense + * given that CHAR_MAX indicates the value isn't + * used, so it neither precedes nor succeeds */ : '.'; /* Now get CRNCYSTR */ |