5 require './test.pl'; # for fresh_perl_is() etc
6 require './loc_tools.pl'; # to find locales
12 # These tests are here instead of lib/locale.t because
13 # some bugs depend on in the internal state of the locale
14 # settings and pragma/locale messes up that state pretty badly.
15 # We need "fresh runs".
17 eval { require POSIX; POSIX->import("locale_h") };
19 skip_all("could not load the POSIX module"); # running minitest?
23 my $have_strtod = $Config{d_strtod} eq 'define';
24 my @locales = eval { find_locales( [ &LC_ALL, &LC_CTYPE, &LC_NUMERIC ] ) };
25 skip_all("no locales available") unless @locales;
28 fresh_perl_is("for (qw(@locales)) {\n" . <<'EOF',
29 use POSIX qw(locale_h);
31 setlocale(LC_NUMERIC, "$_") or next;
32 my $s = sprintf "%g %g", 3.1, 3.1;
33 next if $s eq '3.1 3.1' || $s =~ /^(3.+1) \1$/;
37 "", {}, "no locales where LC_NUMERIC breaks");
40 local $ENV{LC_NUMERIC}; # So not taken as a default
41 local $ENV{LC_ALL}; # so it never overrides LC_NUMERIC
42 local $ENV{LANG}; # So not taken as a default
43 fresh_perl_is("for (qw(@locales)) {\n" . <<'EOF',
44 use POSIX qw(locale_h);
47 my $s = sprintf "%g", $in; # avoid any constant folding bugs
52 "", {}, "LC_NUMERIC without environment nor setlocale() has no effect in any locale");
55 # try to find out a locale where LC_NUMERIC makes a difference
56 my $original_locale = setlocale(LC_NUMERIC);
58 my ($base, $different, $comma, $difference);
59 for ("C", @locales) { # prefer C for the base if available
61 if($Config{d_setlocale}) {
62 require locale; import locale;
65 setlocale(LC_NUMERIC, $_) or next;
66 my $in = 4.2; # avoid any constant folding bugs
67 if ((my $s = sprintf("%g", $in)) eq "4.2") {
72 $comma ||= $_ if localeconv()->{decimal_point} eq ',';
75 last if $base && $different && $comma;
77 setlocale(LC_NUMERIC, $original_locale);
80 skip("no locale available where LC_NUMERIC makes a difference", &last - 4 )
81 if !$different; # -4 is 2 tests before this block; 2 after
82 note("using the '$different' locale for LC_NUMERIC tests");
84 local $ENV{LC_NUMERIC} = $different;
85 local $ENV{LC_ALL}; # so it never overrides LC_NUMERIC
87 fresh_perl_is(<<'EOF', "4.2", {},
94 "format() does not look at LC_NUMERIC without 'use locale'");
97 fresh_perl_is(<<'EOF', $difference, {},
105 "format() looks at LC_NUMERIC with 'use locale'");
109 fresh_perl_is(<<'EOF', ",,", {},
110 print localeconv()->{decimal_point};
113 print localeconv()->{decimal_point};
115 "localeconv() looks at LC_NUMERIC with and without 'use locale'");
119 fresh_perl_is(<<'EOF', $difference, {},
120 use locale ":not_characters";
127 "format() looks at LC_NUMERIC with 'use locale \":not_characters\"'");
131 fresh_perl_is(<<'EOF', "4.2", {},
136 { require locale; import locale; write; }
138 "too late to look at the locale at write() time");
142 fresh_perl_is(<<'EOF', $difference, {},
148 { no locale; write; }
150 "too late to ignore the locale at write() time");
155 # do not let "use 5.000" affect the locale!
156 # this test is to prevent regression of [rt.perl.org #105784]
157 fresh_perl_is(<<"EOF",
159 if("$Config{d_setlocale}") {
160 require locale; import locale;
165 POSIX::setlocale(POSIX::LC_NUMERIC(),"$different");
166 \$a = sprintf("%.2f", \$i);
168 \$b = sprintf("%.2f", \$i);
169 print ".\$a \$b" unless \$a eq \$b
171 "", {}, "version does not clobber version");
173 fresh_perl_is(<<"EOF",
177 POSIX::setlocale(POSIX::LC_NUMERIC(),"$different");
178 \$a = sprintf("%.2f", \$i);
180 \$b = sprintf("%.2f", \$i);
181 print "\$a \$b" unless \$a eq \$b
183 "", {}, "version does not clobber version (via eval)");
187 local $ENV{LC_NUMERIC} = $different;
188 local $ENV{LC_ALL}; # so it never overrides LC_NUMERIC
189 fresh_perl_is(<<'EOF', "$difference "x4, {},
191 use POSIX qw(locale_h);
192 setlocale(LC_NUMERIC, "");
194 printf("%g %g %s %s ", $in, 4.2, sprintf("%g", $in), sprintf("%g", 4.2));
196 "sprintf() and printf() look at LC_NUMERIC regardless of constant folding");
200 local $ENV{LC_NUMERIC} = $different;
201 local $ENV{LC_ALL}; # so it never overrides LC_NUMERIC
202 local $ENV{LANG}; # so on Windows gets sys default locale
203 fresh_perl_is(<<'EOF', "$difference "x4, {},
205 use POSIX qw(locale_h);
206 setlocale(LC_NUMERIC, "");
208 printf("%g %g %s %s ", $in, 4.2, sprintf("%g", $in), sprintf("%g", 4.2));
210 "Uses the above test to verify that on Windows the system default locale has lower priority than LC_NUMERIC");
214 # within this block, STDERR is closed. This is because fresh_perl_is()
215 # forks a shell, and some shells (like bash) can complain noisily when
216 #LC_ALL or similar is set to an invalid value
219 open my $saved_stderr, ">&STDERR" or die "Can't dup STDERR: $!";
223 local $ENV{LC_ALL} = "invalid";
224 local $ENV{LC_NUMERIC} = "invalid";
225 local $ENV{LANG} = $different;
227 # Can't turn off the warnings, so send them to /dev/null
228 if (! fresh_perl_is(<<"EOF", "$difference", { stderr => "devnull" },
229 if (\$ENV{LC_ALL} ne "invalid") {
230 # Make the test pass if the sh didn't accept the ENV set
231 print "$difference\n";
235 use POSIX qw(locale_h);
236 setlocale(LC_NUMERIC, "");
240 "LANG is used if LC_ALL, LC_NUMERIC are invalid"))
242 note "To see details change this .t to not close STDERR";
247 if ($^O eq 'MSWin32') {
248 skip("Win32 uses system default locale in preference to \"C\"",
252 local $ENV{LC_ALL} = "invalid";
253 local $ENV{LC_NUMERIC} = "invalid";
254 local $ENV{LANG} = "invalid";
256 # Can't turn off the warnings, so send them to /dev/null
257 if (! fresh_perl_is(<<"EOF", 4.2, { stderr => "devnull" },
258 if (\$ENV{LC_ALL} ne "invalid") {
259 print "$difference\n";
263 use POSIX qw(locale_h);
264 setlocale(LC_NUMERIC, "");
268 'C locale is used if LC_ALL, LC_NUMERIC, LANG are invalid'))
270 note "To see details change this .t to not close STDERR";
275 open STDERR, ">&", $saved_stderr or die "Can't dup \$saved_stderr: $!";
279 local $ENV{LC_NUMERIC} = $different;
280 local $ENV{LC_ALL}; # so it never overrides LC_NUMERIC
281 fresh_perl_is(<<"EOF",
282 use POSIX qw(locale_h);
284 BEGIN { setlocale(LC_NUMERIC, \"$different\"); };
285 setlocale(LC_ALL, "C");
287 print setlocale(LC_NUMERIC);
290 "No compile error on v-strings when setting the locale to non-dot radix at compile time when default environment has non-dot radix");
294 skip("no locale available where LC_NUMERIC is a comma", 3);
298 fresh_perl_is(<<"EOF",
303 POSIX::setlocale(POSIX::LC_NUMERIC(),"$comma");
308 "1,5\n1.5", {}, "Radix print properly in locale scope, and without");
310 fresh_perl_is(<<"EOF",
311 my \$i = 1.5; # Should be exactly representable as a base 2
312 # fraction, so can use 'eq' below
315 POSIX::setlocale(POSIX::LC_NUMERIC(),"$comma");
320 "1,5\n2,5", {}, "Can do math when radix is a comma"); # [perl 115800]
322 unless ($have_strtod) {
323 skip("no strtod()", 1);
326 fresh_perl_is(<<"EOF",
328 POSIX::setlocale(POSIX::LC_NUMERIC(),"$comma");
329 my \$one_point_5 = POSIX::strtod("1,5");
330 \$one_point_5 =~ s/0+\$//; # Remove any trailing zeros
331 print \$one_point_5, "\n";
333 "1.5", {}, "POSIX::strtod() uses underlying locale");
339 fresh_perl_is(<<"EOF",
342 POSIX::setlocale(POSIX::LC_CTYPE(),"C");
343 print "h" =~ /[g\\w]/i || 0;
346 1, {}, "/il matching of [bracketed] doesn't skip POSIX class if fails individ char");
350 fresh_perl_is(<<"EOF",
353 POSIX::setlocale(POSIX::LC_CTYPE(),"C");
354 print "0" =~ /[\\d[:punct:]]/l || 0;
357 1, {}, "/l matching of [bracketed] doesn't skip non-first POSIX class");