From d27af4d8010f1710c26a39a5479b4ec5ed429228 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Mon, 30 Jan 2023 12:25:59 -0700 Subject: [PATCH 1/2] Fix to work with perls since 5.37.7 This fixes https://github.com/Perl/perl5/issues/20571 The commit blamed in that tickect caused POSIX::localeconv() to return all the defined fields in the lconv structure. Number::Format had been relying on it to suppress empty fields. The solution is simply for Number::Format to instead ignore empty fields itself. This is entirely backwards compatible, as previously those fields were never delivered to Number::Format. There is a slight complication in that the POSIX standard allows for the monetary decimal point and the monetary thousands separator to both be empty. There is a check in Number::Format against both being empty that must be relaxed to allow this legal combination. The check previously was effectively useless as Number::Format would never see those fields if they were empty, as POSIX::localeconv() would suppress them. --- Format.pm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Format.pm b/Format.pm index d49665f..2081ebf 100755 --- a/Format.pm +++ b/Format.pm @@ -379,7 +379,11 @@ sub _check_seps croak("${prefix}thousands_sep and ". "${prefix}decimal_point may not be equal") if $self->{"${prefix}decimal_point"} eq - $self->{"${prefix}thousands_sep"}; + $self->{"${prefix}thousands_sep"} + + # There are legal locales where 'mon_decimal_point' and + # 'mon_thousands_sep' are both "" (the empty string) + && ($prefix eq "" || $self->{"mon_decimal_point"} ne ""); } } @@ -475,9 +479,11 @@ sub new while(my($arg, $default) = each %$DEFAULT_LOCALE) { - $me->{$arg} = (exists $locale_values->{$arg} + $me->{$arg} = (( exists $locale_values->{$arg}) + && $locale_values->{$arg} ne "") ? $locale_values->{$arg} - : $default); + : $default; + foreach ($arg, uc $arg, "-$arg", uc "-$arg") { From 41b9e2cbbb0b8c991f70241fa30ffa94d618e07c Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Mon, 30 Jan 2023 13:21:49 -0700 Subject: [PATCH 2/2] Fix some comments about "broken" behavior The comments wrongly claimed that certain platform behaviors were broken, whereas they are legal, and the module just needed to handle them. This commit updates the text to better describe the situation. --- Format.pm | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Format.pm b/Format.pm index 2081ebf..871d7f1 100755 --- a/Format.pm +++ b/Format.pm @@ -321,11 +321,13 @@ our $DEFAULT_LOCALE = { ( ) }; # -# On Windows, the POSIX localeconv() call returns illegal negative -# numbers for some values, seemingly attempting to indicate null. The -# following list indicates the values for which this has been -# observed, and for which the values should be stripped out of -# localeconv(). +# POSIX::localeconv() returns -1 for numeric values that are not applicable to +# the current locale. This module ignores them. @IGNORE_NEGATIVE lists the +# ones that this module otherwise handles (there are some fields that this +# module always ignores, so don't need to be in the list). (Prior to v5.37.7, +# only the Windows version of POSIX::localeconv() returned -1; other versions +# simply didn't return any values at all for not-applicable fields. But the +# end result is the same regardless of version.) # our @IGNORE_NEGATIVE = qw( frac_digits int_frac_digits n_cs_precedes n_sep_by_space n_sign_posn @@ -495,10 +497,10 @@ sub new } # - # Some broken locales define the decimal_point but not the - # thousands_sep. If decimal_point is set to "," the default - # thousands_sep will be a conflict. In that case, set - # thousands_sep to empty string. Suggested by Moritz Onken. + # Some locales set the decimal_point to "," and the thousands_sep to "". + # This module generally defaults an empty thousands_sep to ",", creating a + # conflict in such a locale. Instead, leave the thousands_sep as the + # empty string. Suggested by Moritz Onken. # foreach my $prefix ("", "mon_") {