summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Williamson <public@khwilliamson.com>2014-03-12 12:54:45 -0600
committerKarl Williamson <public@khwilliamson.com>2014-03-13 16:38:44 -0600
commitd458c02c88acd3b20dabe5e2c98fa6a9668beee8 (patch)
tree685d8dbda4a92f433f56f836997b12f9c88b4a4e
parent66e937f51e083cc757df2a7c292e70ae7ed574bc (diff)
downloadperl-d458c02c88acd3b20dabe5e2c98fa6a9668beee8.tar.gz
lib/locale.t: Fix broken test
The test that [:digit:] is a subset of [:xdigit:] failed in locales where [:digit:] matches 2 blocks of 10 digits, but the second block isn't considered part of [:xdigit:]. This happens in Thai on Windows. The POSIX standard http://pubs.opengroup.org/onlinepubs/9699919799/ does not use very clear language, but I'm taking it as meaning it is ok for this to happen, so this revises the test to accept it.
-rw-r--r--lib/locale.t55
1 files changed, 45 insertions, 10 deletions
diff --git a/lib/locale.t b/lib/locale.t
index 2b1724c467..ab24558356 100644
--- a/lib/locale.t
+++ b/lib/locale.t
@@ -1107,16 +1107,46 @@ foreach my $Locale (@Locale) {
++$locales_test_number;
undef @f;
- $test_names{$locales_test_number} = 'Verify that [:digit:] is a subset of [:xdigit:]';
+ my @xdigit_digits; # :digit: & :xdigit:
+ $test_names{$locales_test_number} = 'Verify that [:xdigit:] contains one or two blocks of 10 consecutive [:digit:] chars';
for (map { chr } 0..255) {
if ($is_utf8_locale) {
use locale ':not_characters';
- push @f, $_ if /[[:digit:]]/ and ! /[[:xdigit:]]/;
+ # For utf8 locales, we actually use a stricter test: that :digit:
+ # is a subset of :xdigit:, as we know that only 0-9 should match
+ push @f, $_ if /[[:digit:]]/ and ! /[[:xdigit:]]/;
}
else {
- push @f, $_ if /[[:digit:]]/ and ! /[[:xdigit:]]/;
+ push @xdigit_digits, $_ if /[[:digit:]]/ and /[[:xdigit:]]/;
}
}
+ if (! $is_utf8_locale) {
+
+ # For non-utf8 locales, @xdigit_digits is a list of the characters
+ # that are both :xdigit: and :digit:. Because :digit: is stored in
+ # increasing code point order (unless the tests above failed),
+ # @xdigit_digits is as well. There should be exactly 10 or
+ # 20 of these.
+ if (@xdigit_digits != 10 && @xdigit_digits != 20) {
+ @f = @xdigit_digits;
+ }
+ else {
+
+ # Look for contiguity in the series, adding any wrong ones to @f
+ my @temp = @xdigit_digits;
+ while (@temp > 1) {
+ push @f, $temp[1] if ($temp[0] != $temp[1] - 1)
+
+ # Skip this test for the 0th character of
+ # the second block of 10, as it won't be
+ # contiguous with the previous block
+ && (! defined $xdigit_digits[10]
+ || $temp[1] != $xdigit_digits[10]);
+ shift @temp;
+ }
+ }
+ }
+
report_multi_result($Locale, $locales_test_number, \@f);
++$locales_test_number;
@@ -1138,17 +1168,22 @@ foreach my $Locale (@Locale) {
$test_names{$locales_test_number} = 'Verify that any additional members of [:xdigit:], are in groups of 6 consecutive code points';
my $previous_ord;
my $count = 0;
- for (map { chr } 0..255) {
- next unless /[[:xdigit:]]/;
- next if /[[:digit:]]/;
- next if /[A-Fa-f]/;
+ for my $chr (map { chr } 0..255) {
+ next unless $chr =~ /[[:xdigit:]]/;
+ if ($is_utf8_locale) {
+ next if $chr =~ /[[:digit:]]/;
+ }
+ else {
+ next if grep { $chr eq $_ } @xdigit_digits;
+ }
+ next if $chr =~ /[A-Fa-f]/;
if (defined $previous_ord) {
if ($is_utf8_locale) {
use locale ':not_characters';
- push @f, $_ if ord $_ != $previous_ord + 1;
+ push @f, $chr if ord $chr != $previous_ord + 1;
}
else {
- push @f, $_ if ord $_ != $previous_ord + 1;
+ push @f, $chr if ord $chr != $previous_ord + 1;
}
}
$count++;
@@ -1156,7 +1191,7 @@ foreach my $Locale (@Locale) {
undef $previous_ord;
}
else {
- $previous_ord = ord $_;
+ $previous_ord = ord $chr;
}
}
report_multi_result($Locale, $locales_test_number, \@f);