diff --git a/ext/POSIX/lib/POSIX.pm b/ext/POSIX/lib/POSIX.pm index fce6b272949a..d2f0978c14c6 100644 --- a/ext/POSIX/lib/POSIX.pm +++ b/ext/POSIX/lib/POSIX.pm @@ -4,7 +4,7 @@ use warnings; our ($AUTOLOAD, %SIGRT); -our $VERSION = '2.09'; +our $VERSION = '2.10'; require XSLoader; diff --git a/ext/POSIX/lib/POSIX.pod b/ext/POSIX/lib/POSIX.pod index 6ef6dc66d5c2..a87cd1ce7c40 100644 --- a/ext/POSIX/lib/POSIX.pod +++ b/ext/POSIX/lib/POSIX.pod @@ -1015,6 +1015,18 @@ Here is how to query the database for the B (Deutsch or German) locale. The members whose names begin with C and C were added by POSIX.1-2008 and are only available on systems that support them. +A value of -1 returned for numeric entries indicates that the field is +not applicable to the locale. This is rare except in the C and related +locales, which don't have most monetary values defined. It can also +happen, quirkily, in fields that are otherwise boolean to indicate that +the value is kind of neither true nor false. This happens in C +and C when the currency symbol neither precedes nor +succeeds a positive value but is infixed, by replacing the radix +character. + +Prior to Perl v5.37.7, empty string fields and numeric fields with value +-1 were omittted from the returned hash. + =item C This is identical to Perl's builtin C function for diff --git a/locale.c b/locale.c index 5417e67c7509..4c7645253654 100644 --- a/locale.c +++ b/locale.c @@ -3520,15 +3520,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 */ @@ -3589,6 +3595,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; } @@ -4336,14 +4364,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 */ diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 1e1ac00cc1d5..845a1fb138ce 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -198,6 +198,13 @@ L has been upgraded to version 2.39. L has been upgraded to version 5.00. +=item * + +L has been upgraded from version 2.09 to 2.10. All fields known +to the platform in L are now returned by +L. Previously, empty string fields and numeric fields +that aren't applicable to the current locale were omitted. + =back =head2 Removed Modules and Pragmata