[ '%a', '0.25', '0x1p-2' ],
[ '%a', '0.75', '0x1.8p-1' ],
[ '%a', '3.14', '0x1.91eb851eb851eb851eb851eb85p+1' ],
- [ '%a', '-1', '-0x0p+0' ],
+ [ '%a', '-1', '-0x1p+0' ],
[ '%a', '-3.14', '-0x1.91eb851eb851eb851eb851eb85p+1' ],
[ '%a', '0.1', '0x1.999999999999999999999999998p-4' ],
[ '%a', '1/7', '0x1.249249249249249249249249248p-3' ],
"width & precision interplay with utf8 strings, length=$i");
}
-# Used to mangle PL_sv_undef
-fresh_perl_like(
- 'print sprintf "xxx%n\n"; print undef',
- qr/Modification of a read-only value attempted at\b/,
- { switches => [ '-w' ] },
- q(%n should not be able to modify read-only constants),
-);
-
# check overflows
for (int(~0/2+1), ~0, "9999999999999999999") {
is(eval {sprintf "%${_}d", 0}, undef, "no sprintf result expected %${_}d");
}
}
-my $vax_float = (pack("d", 1) =~ /^[\x80\x10]\x40/);
-
SKIP: {
- if ($vax_float) { skip "VAX float has no Inf or NaN", 3 }
+ unless ($Config{d_double_has_inf} && $Config{d_double_has_nan}) { skip "no Inf or NaN in doublekind $Config{doublekind}", 3 }
# test that %f doesn't panic with +Inf, -Inf, NaN [perl #45383]
foreach my $n ('2**1e100', '-2**1e100', '2**1e100/2**1e100') { # +Inf, -Inf, NaN
eval { my $f = sprintf("%f", eval $n); };
is $o::numcount, 1, 'sprintf %d number overload count is 1';
SKIP: { # hexfp
- if ($vax_float) { skip "VAX float no hexfp", scalar @hexfloat }
+ unless ($Config{d_double_style_ieee}) { skip "no IEEE, no hexfp", scalar @hexfloat }
my $ppc_linux = $Config{archname} =~ /^(?:ppc|power(?:pc)?)(?:64)?-linux/;
my $irix_ld = $Config{archname} =~ /^IP\d+-irix-ld$/;
skip("uselongdouble=" . ($Config{uselongdouble} ? 'define' : 'undef')
. " longdblkind=$Config{longdblkind} os=$^O", 6)
unless ($Config{uselongdouble} &&
- ($Config{longdblkind} == 5 ||
- $Config{longdblkind} == 6)
+ ($Config{long_double_style_ieee_doubledouble})
# Gating on 'linux' (ppc) here is due to the differing
# double-double implementations: other (also big-endian)
# double-double platforms (e.g. AIX on ppc or IRIX on mips)
SKIP: {
# [rt.perl.org #128843]
- skip("non-IEEE-754-non-64-bit", scalar @subnormals + 34)
+ my $skip_count = scalar @subnormals + 34;
+ skip("non-IEEE-754-non-64-bit", $skip_count)
unless ($Config{nvsize} == 8 &&
$Config{nv_preserves_uv_bits} == 53 &&
($Config{doublekind} == 3 ||
$Config{doublekind} == 4));
+ if ($^O eq 'dec_osf') {
+ skip("$^O subnormals", $skip_count);
+ }
for my $t (@subnormals) {
# Note that "0x1p+2" is not considered numeric,
skip("non-80-bit-long-double", 17)
unless ($Config{uselongdouble} &&
($Config{nvsize} == 16 || $Config{nvsize} == 12) &&
- ($Config{longdblkind} == 3 ||
- $Config{longdblkind} == 4));
+ ($Config{long_double_style_ieee_extended}));
{
# The last normal for this format.
is(sprintf("%a", eval '0x1p-16494'), '0x1p-16494'); # underflow
}
+# check all calls to croak_memory_wrap()
+# RT #131260
+
+{
+ my $s = 8 * $Config{sizesize};
+ my $i = 1;
+ my $max;
+ while ($s--) { $max |= $i; $i <<= 1; }
+
+ my @tests = (
+ # format, arg
+ ["%.${max}a", 1.1 ],
+ ["%.${max}i", 1 ],
+ ["%.${max}i", -1 ],
+ );
+
+ for my $test (@tests) {
+ my ($fmt, $arg) = @$test;
+ eval { my $s = sprintf $fmt, $arg; };
+ like("$@", qr/panic: memory wrap/, qq{memory wrap: "$fmt", "$arg"});
+ }
+}
+
+{
+ # handle utf8 correctly when skipping invalid format
+ my $w_red = 0;
+ my $w_inv = 0;
+ my $w_other = 0;
+ local $SIG{__WARN__} = sub {
+ if ($_[0] =~ /^Invalid conversion/) {
+ $w_inv++;
+ }
+ elsif ($_[0] =~ /^Redundant argument/) {
+ $w_red++;
+ }
+ else {
+ $w_other++;
+ }
+ };
+
+ use warnings;
+ my $s = sprintf "%s%\xc4\x80%s", "\x{102}", "\xc4\x83";
+ is($s, "\x{102}%\xc4\x80\xc4\x83", "utf8 for invalid format");
+ is($w_inv, 1, "utf8 for invalid format: invalid warnings");
+ is($w_red, 0, "utf8 for invalid format: redundant warnings");
+ is($w_other, 0, "utf8 for invalid format: other warnings");
+}
+
+# it used to upgrade the result to utf8 if the 1st arg happened to be utf8
+
+{
+ my $precis = "9";
+ utf8::upgrade($precis);
+ my $s = sprintf "%.*f\n", $precis, 1.1;
+ ok(!utf8::is_utf8($s), "first arg not special utf8-wise");
+}
+
+# sprintf("%n") used to croak "Modification of a read-only value"
+# as it tried to set &PL_sv_no
+
+{
+ eval { my $s = sprintf("%n"); };
+ like $@, qr/Missing argument for %n in sprintf/, "%n";
+}
+
+# %p of an Inf or Nan address should still print its address, not
+# 'Inf' etc.
+
+like sprintf("%p", 0+'Inf'), qr/^[0-9a-f]+$/, "%p and Inf";
+like sprintf("%p", 0+'NaN'), qr/^[0-9a-f]+$/, "%p and NaN";
+
done_testing();