9 use strict; # Amazed that this hackery can be made strict ...
16 open my $fh, $file or die "can't open '$file': $!";
22 # read in a utf-8 file
27 open my $fh, '<', $file or die "can't open '$file': $!";
29 my $data = <$fh> // die "Can't read from '$file': $!";
30 close $fh or die "error closing '$file': $!";
34 # write a format to a utf8 file, then read it back in and compare
37 my ($glob, $want, $desc) = @_;
38 local $::Level = $::Level + 1;
39 my $file = 'Op_write.tmp';
40 open $glob, '>:utf8', $file or die "Can't create '$file': $!";
42 close $glob or die "Could not close '$file': $!";
43 is(cat_utf8($file), $want, $desc);
46 sub like_format_utf8 {
47 my ($glob, $want, $desc) = @_;
48 local $::Level = $::Level + 1;
49 my $file = 'Op_write.tmp';
50 open $glob, '>:utf8', $file or die "Can't create '$file': $!";
52 close $glob or die "Could not close '$file': $!";
53 like(cat_utf8($file), $want, $desc);
58 #-- testing numeric fields in all variants (WL)
62 local $^A = ""; # don't litter, use a local bin
63 formline( $format, @_ );
68 # [ format, value1, expected1, value2, expected2, .... ]
69 [ '@###', 0, ' 0', 1, ' 1', 9999.6, '####',
70 9999.4999, '9999', -999.6, '####', 1e+100, '####' ],
72 [ '@0##', 0, '0000', 1, '0001', 9999.6, '####',
73 -999.4999, '-999', -999.6, '####', 1e+100, '####' ],
75 [ '^###', 0, ' 0', undef, ' ' ],
77 [ '^0##', 0, '0000', undef, ' ' ],
79 [ '@###.', 0, ' 0.', 1, ' 1.', 9999.6, '#####',
80 9999.4999, '9999.', -999.6, '#####' ],
82 [ '@##.##', 0, ' 0.00', 1, ' 1.00', 999.996, '######',
83 999.99499, '999.99', -100, '######' ],
85 [ '@0#.##', 0, '000.00', 1, '001.00', 10, '010.00',
86 -0.0001, qr/^[\-0]00\.00$/ ],
92 for my $tref ( @NumTests ){
93 $num_tests += (@$tref - 1)/2;
95 #---------------------------------------------------------
97 # number of tests in section 1
100 # number of tests in section 3
101 my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 6 + 2 + 3 + 96 + 11 + 4;
103 # number of tests in section 4
106 my $tests = $bas_tests + $num_tests + $bug_tests + $hmb_tests;
114 use vars qw($fox $multiline $foo $good);
128 now @<<the@>>>> for all@|||||men to come @<<<<
130 'i' . 's', "time\n", $good, 'to'
134 open(OUT, '>Op_write.tmp') || die "Can't create Op_write.tmp";
135 END { unlink_all 'Op_write.tmp' }
139 $multiline = "forescore\nand\nseven years\n";
140 $foo = 'when in the course of human events it becomes necessary';
142 close OUT or die "Could not close: $!";
153 now is the time for all good men to come to\n";
155 is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
157 $fox = 'wolfishness';
158 my $fox = 'foxiness'; # Test a lexical variable.
168 now @<<the@>>>> for all@|||||men to come @<<<<
169 'i' . 's', "time\n", $good, 'to'
172 open OUT2, '>Op_write.tmp' or die "Can't create Op_write.tmp";
175 $multiline = "forescore\nand\nseven years\n";
176 $foo = 'when in the course of human events it becomes necessary';
178 close OUT2 or die "Could not close: $!";
192 now is the time for all good men to come to\n";
194 is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
206 now @<<the@>>>> for all@|||||men to come @<<<<
207 'i' . 's', "time\n", $good, 'to'
211 open(OUT2, '>Op_write.tmp') || die "Can't create Op_write.tmp";
215 $multiline = "forescore\nand\nseven years\n";
216 $foo = 'when in the course of human events it becomes necessary';
218 close OUT2 or die "Could not close: $!";
233 now is the time for all good men to come to\n";
235 is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
253 my $was1 = my $was2 = '';
258 my $format1 = '@' . '>' x $_;
259 formline $format1, 'abc';
260 $was1 .= "$format1 $^A\n";
263 local $format2 = '@' . '>' x $_;
264 formline $format2, 'abc';
265 $was2 .= "$format2 $^A\n";
279 open(OUT3, '>Op_write.tmp') || die "Can't create Op_write.tmp";
283 close OUT3 or die "Could not close: $!";
288 is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
291 # test lexicals and globals
293 my $test = curr_test();
300 open(LEX, ">&STDOUT") or die;
304 close LEX or die "Could not close: $!";
305 curr_test($test + 1);
307 # LEX_INTERPNORMAL test
313 open OUT4, ">Op_write.tmp" or die "Can't create Op_write.tmp";
315 close OUT4 or die "Could not close: $!";
316 is cat('Op_write.tmp'), "1\n" and unlink_all "Op_write.tmp";
318 # More LEX_INTERPNORMAL
322 strict; \'Nasdaq dropping like flies'}"
324 open OUT4a, ">Op_write.tmp" or die "Can't create Op_write.tmp";
326 close OUT4a or die "Could not close: $!";
327 is cat('Op_write.tmp'), "Nasdaq dropping\n", 'skipspace inside "${...}"'
328 and unlink_all "Op_write.tmp";
337 open(OUT10, '>Op_write.tmp') || die "Can't create Op_write.tmp";
342 close OUT10 or die "Could not close: $!";
344 $right = " 12.95 00012.95\n";
345 is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
358 open(OUT11, '>Op_write.tmp') || die "Can't create Op_write.tmp";
362 close OUT11 or die "Could not close: $!";
368 is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
371 my $test = curr_test();
374 ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze
377 my %hash = ($test => 3);
378 open(OUT12, '>Op_write.tmp') || die "Can't create Op_write.tmp";
380 for $el (keys %hash) {
383 close OUT12 or die "Could not close: $!";
384 print cat('Op_write.tmp');
385 curr_test($test + 1);
389 my $test = curr_test();
390 # Bug report and testcase by Alexey Tourbin
392 tie $v, 'Tie::StdScalar';
398 open(OUT13, '>Op_write.tmp') || die "Can't create Op_write.tmp";
400 close OUT13 or die "Could not close: $!";
401 print cat('Op_write.tmp');
402 curr_test($test + 1);
406 # Bug #24774 format without trailing \n failed assertion, but this
407 # must fail since we have a trailing ; in the eval'ed string (WL)
409 eval "format OUT14 = \n@\n\@v";
410 like $@, qr/Format not terminated/;
414 # text lost in ^<<< field with \r in value (WL)
415 my $txt = "line 1\rline 2";
422 open(OUT15, '>Op_write.tmp') || die "Can't create Op_write.tmp";
424 close OUT15 or die "Could not close: $!";
425 my $res = cat('Op_write.tmp');
426 is $res, "line 1\nline 2\n";
429 { # test 16: multiple use of a variable in same line with ^<
430 my $txt = "this_is_block_1 this_is_block_2 this_is_block_3 this_is_block_4";
432 ^<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<
434 ^<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<
437 open(OUT16, '>Op_write.tmp') || die "Can't create Op_write.tmp";
439 close OUT16 or die "Could not close: $!";
440 my $res = cat('Op_write.tmp');
442 this_is_block_1 this_is_block_2
443 this_is_block_3 this_is_block_4
447 { # test 17: @* "should be on a line of its own", but it should work
448 # cleanly with literals before and after. (WL)
450 my $txt = "This is line 1.\nThis is the second line.\nThird and last.\n";
452 Here we go: @* That's all, folks!
455 open(OUT17, '>Op_write.tmp') || die "Can't create Op_write.tmp";
457 close OUT17 or die "Could not close: $!";
458 my $res = cat('Op_write.tmp');
461 Here we go: $txt That's all, folks!
466 { # test 18: @# and ~~ would cause runaway format, but we now
467 # catch this while compiling (WL)
473 open(OUT18, '>Op_write.tmp') || die "Can't create Op_write.tmp";
474 eval { write(OUT18); };
475 like $@, qr/Repeated format line will never terminate/;
476 close OUT18 or die "Could not close: $!";
479 { # test 19: \0 in an evel'ed format, doesn't cause empty lines (WL)
481 eval "format OUT19 = \n" .
486 open(OUT19, '>Op_write.tmp') || die "Can't create Op_write.tmp";
488 close OUT19 or die "Could not close: $!";
489 my $res = cat('Op_write.tmp');
496 { # test 20: hash accesses; single '}' must not terminate format '}' (WL)
497 my %h = ( xkey => 'xval', ykey => 'yval' );
509 while( my( $k, $v ) = each( %h ) ){
510 $exp .= sprintf( "%5s %s\n", $k, $v );
512 $exp .= sprintf( "%5s %s\n", $h{xkey}, $h{ykey} );
513 $exp .= sprintf( "%5s %s\n", $h{xkey}, $h{ykey} );
515 open(OUT20, '>Op_write.tmp') || die "Can't create Op_write.tmp";
517 close OUT20 or die "Could not close: $!";
518 my $res = cat('Op_write.tmp');
523 #####################
525 ## numeric formatting
526 #####################
528 curr_test($bas_tests + 1);
530 for my $tref ( @NumTests ){
531 my $writefmt = shift( @$tref );
533 my $val = shift @$tref;
534 my $expected = shift @$tref;
535 my $writeres = swrite( $writefmt, $val );
537 like $writeres, $expected, $writefmt;
539 is $writeres, $expected, $writefmt;
545 #####################################
547 ## Easiest to add new tests just here
548 #####################################
550 # DAPM. Exercise a couple of error codepaths
555 like $@, qr/Undefined format ""/, 'format with 0-length name';
559 like $@, qr/Undefined format "\0foo"/,
560 'no such format beginning with null';
564 like $@, qr/Undefined format "NOSUCHFORMAT"/, 'no such format';
567 select +(select(OUT21), do {
568 open(OUT21, '>Op_write.tmp') || die "Can't create Op_write.tmp";
577 $_ = "aataaaaaaaaaaaaaa"; eval { write(OUT21) };
578 like $@, qr/Undefined top format ""/, 'top format with 0-length name';
581 # For some reason, we have to do this twice to get the error again.
582 $_ = "aataaaaaaaaaaaaaa"; eval { write(OUT21) };
583 $_ = "aataaaaaaaaaaaaaa"; eval { write(OUT21) };
584 like $@, qr/Undefined top format "\0foo"/,
585 'no such top format beginning with null';
588 $_ = "aataaaaaaaaaaaaaa"; eval { write(OUT21) };
589 $_ = "aataaaaaaaaaaaaaa"; eval { write(OUT21) };
590 like $@, qr/Undefined top format "NOSUCHFORMAT"/, 'no such top format';
593 eval { write(OUT21) };
596 close OUT21 or die "Could not close: $!";
601 # [perl #119847], [perl #119849], [perl #119851]
602 # Non-real vars like tied, overloaded and refs could, when stringified,
603 # fail to be processed properly, causing infinite loops on ~~, utf8
604 # warnings etc, ad nauseum.
614 is_format_utf8(\*OUT22a,
619 utf8::upgrade($u22b);
626 is_format_utf8(\*OUT22b,
629 my $u22c = "\x{FF}" x 8;
636 is_format_utf8(\*OUT22c,
637 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
639 my $u22d = "\x{FF}" x 8;
640 utf8::upgrade($u22d);
647 is_format_utf8(\*OUT22d,
648 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
650 my $u22e = "\x{100}" x 8;
657 is_format_utf8(\*OUT22e,
658 "'\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} '\n");
668 is_format_utf8(\*OUT22f,
673 utf8::upgrade($u22g);
680 is_format_utf8(\*OUT22g,
683 my $u22h = "\x{FF}" x 8;
690 is_format_utf8(\*OUT22h,
691 "'\x{FF}\x{FF}'\n"x4);
693 my $u22i = "\x{FF}" x 8;
694 utf8::upgrade($u22i);
701 is_format_utf8(\*OUT22i,
702 "'\x{FF}\x{FF}'\n"x4);
704 my $u22j = "\x{100}" x 8;
711 is_format_utf8(\*OUT22j,
712 "'\x{100}\x{100}'\n"x4);
715 tie my $u23a, 'Tie::StdScalar';
723 is_format_utf8(\*OUT23a,
727 tie my $u23b, 'Tie::StdScalar';
729 utf8::upgrade($u23b);
736 is_format_utf8(\*OUT23b,
739 tie my $u23c, 'Tie::StdScalar';
740 $u23c = "\x{FF}" x 8;
747 is_format_utf8(\*OUT23c,
748 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
750 tie my $u23d, 'Tie::StdScalar';
751 my $temp = "\x{FF}" x 8;
752 utf8::upgrade($temp);
760 is_format_utf8(\*OUT23d,
761 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
763 tie my $u23e, 'Tie::StdScalar';
764 $u23e = "\x{100}" x 8;
771 is_format_utf8(\*OUT23e,
772 "'\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} '\n");
774 tie my $u23f, 'Tie::StdScalar';
782 is_format_utf8(\*OUT23f,
786 tie my $u23g, 'Tie::StdScalar';
788 utf8::upgrade($temp);
796 is_format_utf8(\*OUT23g,
799 tie my $u23h, 'Tie::StdScalar';
800 $u23h = "\x{FF}" x 8;
807 is_format_utf8(\*OUT23h,
808 "'\x{FF}\x{FF}'\n"x4);
810 $temp = "\x{FF}" x 8;
811 utf8::upgrade($temp);
812 tie my $u23i, 'Tie::StdScalar';
820 is_format_utf8(\*OUT23i,
821 "'\x{FF}\x{FF}'\n"x4);
823 tie my $u23j, 'Tie::StdScalar';
824 $u23j = "\x{100}" x 8;
831 is_format_utf8(\*OUT23j,
832 "'\x{100}\x{100}'\n"x4);
840 my $state = shift||0;
841 return bless [$value, $state], $class;
846 $self->[1] = ! $self->[1];
848 utf8::downgrade($self->[0]);
850 utf8::upgrade($self->[0]);
861 tie my $u24a, 'UTF8Toggle';
869 is_format_utf8(\*OUT24a,
873 tie my $u24b, 'UTF8Toggle';
875 utf8::upgrade($u24b);
882 is_format_utf8(\*OUT24b,
885 tie my $u24c, 'UTF8Toggle';
886 $u24c = "\x{FF}" x 8;
893 is_format_utf8(\*OUT24c,
894 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
896 tie my $u24d, 'UTF8Toggle', 1;
897 $u24d = "\x{FF}" x 8;
904 is_format_utf8(\*OUT24d,
905 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
909 tie my $u24f, 'UTF8Toggle';
917 is_format_utf8(\*OUT24f,
921 tie my $u24g, 'UTF8Toggle';
923 utf8::upgrade($temp);
931 is_format_utf8(\*OUT24g,
934 tie my $u24h, 'UTF8Toggle';
935 $u24h = "\x{FF}" x 8;
942 is_format_utf8(\*OUT24h,
943 "'\x{FF}\x{FF}'\n"x4);
945 tie my $u24i, 'UTF8Toggle', 1;
946 $u24i = "\x{FF}" x 8;
953 is_format_utf8(\*OUT24i,
954 "'\x{FF}\x{FF}'\n"x4);
958 use overload '""' => sub { ${$_[0]}; };
961 my ($class, $value) = @_;
962 bless \$value, $class;
966 my $u25a = OS->new("N" x 8);
973 is_format_utf8(\*OUT25a,
978 utf8::upgrade($temp);
979 my $u25b = OS->new($temp);
986 is_format_utf8(\*OUT25b,
989 my $u25c = OS->new("\x{FF}" x 8);
996 is_format_utf8(\*OUT25c,
997 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
999 $temp = "\x{FF}" x 8;
1000 utf8::upgrade($temp);
1001 my $u25d = OS->new($temp);
1008 is_format_utf8(\*OUT25d,
1009 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
1011 my $u25e = OS->new("\x{100}" x 8);
1018 is_format_utf8(\*OUT25e,
1019 "'\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} '\n");
1022 my $u25f = OS->new("N" x 8);
1029 is_format_utf8(\*OUT25f,
1034 utf8::upgrade($temp);
1035 my $u25g = OS->new($temp);
1042 is_format_utf8(\*OUT25g,
1045 my $u25h = OS->new("\x{FF}" x 8);
1052 is_format_utf8(\*OUT25h,
1053 "'\x{FF}\x{FF}'\n"x4);
1055 $temp = "\x{FF}" x 8;
1056 utf8::upgrade($temp);
1057 my $u25i = OS->new($temp);
1064 is_format_utf8(\*OUT25i,
1065 "'\x{FF}\x{FF}'\n"x4);
1067 my $u25j = OS->new("\x{100}" x 8);
1074 is_format_utf8(\*OUT25j,
1075 "'\x{100}\x{100}'\n"x4);
1078 package OS::UTF8Toggle;
1079 use overload '""' => sub {
1081 $self->[1] = ! $self->[1];
1083 utf8::downgrade($self->[0]);
1085 utf8::upgrade($self->[0]);
1091 my ($class, $value, $state) = @_;
1092 bless [$value, $state], $class;
1097 my $u26a = OS::UTF8Toggle->new("N" x 8);
1104 is_format_utf8(\*OUT26a,
1108 my $u26b = OS::UTF8Toggle->new("N" x 8, 1);
1115 is_format_utf8(\*OUT26b,
1118 my $u26c = OS::UTF8Toggle->new("\x{FF}" x 8);
1125 is_format_utf8(\*OUT26c,
1126 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
1128 my $u26d = OS::UTF8Toggle->new("\x{FF}" x 8, 1);
1135 is_format_utf8(\*OUT26d,
1136 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
1139 my $u26f = OS::UTF8Toggle->new("N" x 8);
1146 is_format_utf8(\*OUT26f,
1150 my $u26g = OS::UTF8Toggle->new("N" x 8, 1);
1157 is_format_utf8(\*OUT26g,
1160 my $u26h = OS::UTF8Toggle->new("\x{FF}" x 8);
1167 is_format_utf8(\*OUT26h,
1168 "'\x{FF}\x{FF}'\n"x4);
1170 my $u26i = OS::UTF8Toggle->new("\x{FF}" x 8, 1);
1177 is_format_utf8(\*OUT26i,
1178 "'\x{FF}\x{FF}'\n"x4);
1190 return bless \$value, $class;
1193 # The return value should always be SvNOK() only:
1196 # avoid "" getting converted to "0" and thus
1197 # causing an infinite loop
1198 return "" unless length ($$self);
1199 return $$self - 0.5 + $zero + 0.5;
1209 use overload '""' => sub {
1211 return $$self - 0.5 + $zero + 0.5;
1217 return bless \$value, $class;
1228 is_format_utf8(\*OUT27a,
1238 is_format_utf8(\*OUT27b,
1239 "'0.'\n'00'\n'39'\n'06'\n'25'\n");
1241 tie my $v27c, 'Number', 1/256;
1248 is_format_utf8(\*OUT27c,
1258 is_format_utf8(\*OUT27d,
1259 "'0.'\n'00'\n'39'\n'06'\n'25'\n");
1261 my $v27e = ONumber->new(1/256);
1268 is_format_utf8(\*OUT27e,
1271 my $v27f = ONumber->new(1/256);
1278 is_format_utf8(\*OUT27f,
1279 "'0.'\n'00'\n'39'\n'06'\n'25'\n");
1283 use overload '""' => sub {
1290 return bless \$value, $class;
1297 '^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'~~
1302 # 'HASH(0x1716b60) '
1303 my $qr_hash = qr/^'HASH\(0x[0-9a-f]+\)\s+'\n$/;
1309 my $qr_hash_m = qr/^'HASH'\n('[0-9a-fx() ]{4}'\n)+$/;
1311 like_format_utf8(\*OUT28a, $qr_hash);
1320 like_format_utf8(\*OUT28b, $qr_hash_m);
1323 tie my $v28c, 'Tie::StdScalar';
1327 '^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'~~
1331 like_format_utf8(\*OUT28c, $qr_hash);
1333 tie my $v28d, 'Tie::StdScalar';
1341 like_format_utf8(\*OUT28d, $qr_hash_m);
1343 my $v28e = Ref->new({});
1346 '^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'~~
1350 like_format_utf8(\*OUT28e, $qr_hash);
1352 my $v28f = Ref->new({});
1359 like_format_utf8(\*OUT28f, $qr_hash_m);
1368 bless [shift, 0, 0], $class;
1385 my ($pound_utf8, $pm_utf8) = map { my $a = "$_\x{100}"; chop $a; $a}
1386 my ($pound, $pm) = ("\xA3", "\xB1");
1388 foreach my $first ('N', $pound, $pound_utf8) {
1389 foreach my $base ('N', $pm, $pm_utf8) {
1390 foreach my $second ($base, "$base\n", "$base\nMoo!", "$base\nMoo!\n",
1392 foreach (['^*', qr/(.+)/], ['@*', qr/(.*?)$/s]) {
1393 my ($format, $re) = @$_;
1394 $format = "1^*2 3${format}4";
1395 foreach my $class ('', 'Count') {
1396 my $name = qq{swrite("$format", "$first", "$second") class="$class"};
1397 $name =~ s/\n/\\n/g;
1399 ord($1) > 126 ? sprintf("\\x{%x}",ord($1)) : $1
1402 $first =~ /(.+)/ or die $first;
1403 my $expect = "1${1}2";
1404 $second =~ $re or die $second;
1405 $expect .= " 3${1}4";
1410 tie $copy2, $class, $second;
1411 is swrite("$format", $copy1, $copy2), $expect, $name;
1412 my $obj = tied $copy2;
1413 is $obj->[1], 1, 'value read exactly once';
1415 my ($copy1, $copy2) = ($first, $second);
1416 is swrite("$format", $copy1, $copy2), $expect, $name;
1426 # This will fail an assertion in 5.10.0 built with -DDEBUGGING (because
1427 # pp_formline attempts to set SvCUR() on an SVt_RV). I suspect that it will
1428 # be doing something similarly out of bounds on everything from 5.000
1431 is swrite('>^*<', $ref), $exp;
1434 is swrite('>@*<', $ref), $exp;
1440 my $test = curr_test();
1448 # RT #8698 format bug with undefined _TOP
1450 open STDOUT_DUP, ">&STDOUT";
1451 my $oldfh = select STDOUT_DUP;
1454 local $~ = "Comment";
1456 curr_test($test + 1);
1458 is $^, "STDOUT_DUP_TOP";
1463 *CmT = *{$::{Comment}}{FORMAT};
1464 ok defined *{$::{CmT}}{FORMAT}, "glob assign";
1467 # RT #91032: Check that "non-real" strings like tie and overload work,
1468 # especially that they re-compile the pattern on each FETCH, and that
1469 # they don't overrun the buffer
1475 sub TIESCALAR { bless [] }
1477 sub FETCH { $i++; "A$i @> Z\n" }
1479 use overload '""' => \&FETCH;
1481 tie my $f, 'RT91032';
1485 ::is $^A, "A1 a Z\nA2 bc Z\n", "RT 91032: tied";
1488 my $g = bless []; # has overloaded stringify
1491 ::is $^A, "A3 de Z\nA4 f Z\n", "RT 91032: overloaded";
1495 formline $h, "junk1";
1496 formline $h, "junk2";
1497 ::is ref($h), 'ARRAY', "RT 91032: array ref still a ref";
1498 ::like "$h", qr/^ARRAY\(0x[0-9a-f]+\)$/, "RT 91032: array stringifies ok";
1499 ::is $^A, "$h$h","RT 91032: stringified array";
1502 # used to overwrite the ~~ in the *original SV with spaces. Naughty!
1504 my $orig = my $format = "^<<<<< ~~\n";
1506 formline $format, $abc;
1508 ::is $format, $orig, "RT91032: don't overwrite orig format string";
1510 # check that ~ and ~~ are displayed correctly as whitespace,
1511 # under the influence of various different types of border
1514 for my $lhs (' ', 'Y', '^<<<', '^|||', '^>>>') {
1515 for my $rhs ('', ' ', 'Z', '^<<<', '^|||', '^>>>') {
1516 my $fmt = "^<B$lhs" . ('~' x $n) . "$rhs\n";
1517 my $sfmt = ($fmt =~ s/~/ /gr);
1518 my ($a, $bc, $stop);
1519 ($a, $bc, $stop) = ('a', 'bc', 's');
1520 # $stop is to stop '~~' deleting the whole line
1521 formline $sfmt, $stop, $a, $bc;
1524 ($a, $bc, $stop) = ('a', 'bc', 's');
1525 formline $fmt, $stop, $a, $bc;
1529 ::is($got, $exp, "chop munging: [$fmt]");
1535 # check that '~ (delete current line if empty) works when
1536 # the target gets upgraded to uft8 (and re-allocated) midstream.
1539 my $format = "\x{100}@~\n"; # format is utf8
1540 # this target is not utf8, but will expand (and get reallocated)
1541 # when upgraded to utf8.
1542 my $orig = "\x80\x81\x82";
1545 formline $format, $empty;
1546 is $^A , $orig, "~ and realloc";
1548 # check similarly that trailing blank removal works ok
1550 $format = "@<\n\x{100}"; # format is utf8
1554 formline $format, " ";
1555 is $^A, "$orig\n", "end-of-line blanks and realloc";
1557 # and check this doesn't overflow the buffer
1560 $format = "@* @####\n";
1561 $orig = "x" x 100 . "\n";
1562 formline $format, $orig, 12345;
1563 is $^A, ("x" x 100) . " 12345\n", "\@* doesn't overflow";
1565 # make sure it can cope with formats > 64k
1567 $format = 'x' x 65537;
1570 # don't use 'is' here, as the diag output will be too long!
1571 ok $^A eq $format, ">64K";
1576 skip_if_miniperl('miniperl does not support scalario');
1578 open my $fh, ">", \$buf;
1579 my $old_fh = select $fh;
1584 is $buf, "ok $test\n", "write to duplicated format";
1587 format caret_A_test_TOP =
1591 format caret_A_test =
1599 skip_if_miniperl('miniperl does not support scalario');
1601 open my $fh, ">", \$buf;
1602 my $old_fh = select $fh;
1603 local $^ = "caret_A_test_TOP";
1604 local $~ = "caret_A_test";
1606 local $^A = "A1\nA2\nA3\nA4\n";
1610 is $buf, "T\nA1\nA2\n\fT\nA3\nA4\n\fT\nL1\nL2\n\fT\nL3\nL4\n",
1611 "assign to ^A sets FmLINES";
1614 fresh_perl_like(<<'EOP', qr/^Format STDOUT redefined at/, {stderr => 1}, '#64562 - Segmentation fault with redefined formats and warnings');
1618 use warnings; # crashes!
1631 fresh_perl_is(<<'EOP', ">ARRAY<\ncrunch_eth\n", {stderr => 1}, '#79532 - formline coerces its arguments');
1634 my $zamm = ['crunch_eth'];
1636 printf ">%s<\n", ref $zamm;
1637 print "$zamm->[0]\n";
1640 # [perl #129125] - detected by -fsanitize=address or valgrind
1641 # the compiled format would be freed when the format string was modified
1642 # by the chop operator
1643 fresh_perl_is(<<'EOP', "^", { stderr => 1 }, '#129125 - chop on format');
1649 fresh_perl_is(<<'EOP', '<^< xx AA><xx ^<><>', { stderr => 1 }, '#129125 - chop on format, later values');
1652 formline $x => $x, $y;
1653 print "<$^A><$x><$y>";
1659 select +(select(RT73690), do {
1660 open(RT73690, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1669 is(scalar(@ret), 1);
1671 @ret = scalar(write);
1672 is(scalar(@ret), 1);
1674 @ret = write(RT73690);
1675 is(scalar(@ret), 1);
1677 @ret = scalar(write(RT73690));
1678 is(scalar(@ret), 1);
1681 @ret = ('a', write, 'z');
1682 is(scalar(@ret), 3);
1686 @ret = ('b', scalar(write), 'y');
1687 is(scalar(@ret), 3);
1691 @ret = ('c', write(RT73690), 'x');
1692 is(scalar(@ret), 3);
1696 @ret = ('d', scalar(write(RT73690)), 'w');
1697 is(scalar(@ret), 3);
1702 @ret = do { write; 'foo' };
1703 is(scalar(@ret), 1);
1705 @ret = do { scalar(write); 'bar' };
1706 is(scalar(@ret), 1);
1708 @ret = do { write(RT73690); 'baz' };
1709 is(scalar(@ret), 1);
1711 @ret = do { scalar(write(RT73690)); 'quux' };
1712 is(scalar(@ret), 1);
1713 is($ret[0], 'quux');
1715 @ret = ('a', do { write; 'foo' }, 'z');
1716 is(scalar(@ret), 3);
1720 @ret = ('b', do { scalar(write); 'bar' }, 'y');
1721 is(scalar(@ret), 3);
1725 @ret = ('c', do { write(RT73690); 'baz' }, 'x');
1726 is(scalar(@ret), 3);
1730 @ret = ('d', do { scalar(write(RT73690)); 'quux' }, 'w');
1731 is(scalar(@ret), 3);
1733 is($ret[1], 'quux');
1736 close RT73690 or die "Could not close: $!";
1739 select +(select(RT73690_2), do {
1740 open(RT73690_2, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1749 is(scalar(@ret), 1);
1751 @ret = scalar(write);
1752 is(scalar(@ret), 1);
1754 @ret = write(RT73690_2);
1755 is(scalar(@ret), 1);
1757 @ret = scalar(write(RT73690_2));
1758 is(scalar(@ret), 1);
1761 @ret = ('a', write, 'z');
1762 is(scalar(@ret), 3);
1766 @ret = ('b', scalar(write), 'y');
1767 is(scalar(@ret), 3);
1771 @ret = ('c', write(RT73690_2), 'x');
1772 is(scalar(@ret), 3);
1776 @ret = ('d', scalar(write(RT73690_2)), 'w');
1777 is(scalar(@ret), 3);
1782 @ret = do { write; 'foo' };
1783 is(scalar(@ret), 1);
1785 @ret = do { scalar(write); 'bar' };
1786 is(scalar(@ret), 1);
1788 @ret = do { write(RT73690_2); 'baz' };
1789 is(scalar(@ret), 1);
1791 @ret = do { scalar(write(RT73690_2)); 'quux' };
1792 is(scalar(@ret), 1);
1793 is($ret[0], 'quux');
1795 @ret = ('a', do { write; 'foo' }, 'z');
1796 is(scalar(@ret), 3);
1800 @ret = ('b', do { scalar(write); 'bar' }, 'y');
1801 is(scalar(@ret), 3);
1805 @ret = ('c', do { write(RT73690_2); 'baz' }, 'x');
1806 is(scalar(@ret), 3);
1810 @ret = ('d', do { scalar(write(RT73690_2)); 'quux' }, 'w');
1811 is(scalar(@ret), 3);
1813 is($ret[1], 'quux');
1816 close RT73690_2 or die "Could not close: $!";
1819 open(UNDEF, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1820 select +(select(UNDEF), $~ = "UNDEFFORMAT")[0];
1821 format UNDEFFORMAT =
1826 pass "active format cannot be freed";
1828 select +(select(UNDEF), $~ = "UNDEFFORMAT2")[0];
1829 format UNDEFFORMAT2 =
1831 close UNDEF or die "Could not close: $!"; undef *UNDEF
1834 pass "freeing current handle in format";
1843 |, 'format foo { ... } is not allowed';
1850 |, 'format = ... } is not allowed';
1852 open(NEST, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1856 my $birds = "birds";
1857 local *NEST = *BIRDS{FORMAT};
1867 close NEST or die "Could not close: $!";
1868 is cat('Op_write.tmp'), "birds\nnest\n", 'nested formats';
1870 # A compilation error should not create a format
1877 eval { write ERROR };
1878 like $@, qr'Undefined format',
1879 'formats with compilation errors are not created';
1881 # This syntax error used to cause a crash, double free, or a least
1883 # See the long-winded explanation at:
1884 # https://rt.perl.org/rt3/Ticket/Display.html?id=43425#txn-1144500
1892 pass('no crash with invalid use/format inside format');
1895 # Low-precedence operators on argument line
1901 ok eval { local $~ = "AND"; print "# "; write; 1 },
1902 "low-prec ops on arg line" or diag $@;
1905 open(HASH, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1908 ${{qw[ Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6 ]}}{"Wed"}
1911 close HASH or die "Could not close: $!";
1912 is cat('Op_write.tmp'), "3\n", 'anonymous hashes';
1914 open(HASH2, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1920 close HASH2 or die "Could not close: $!";
1921 is cat('Op_write.tmp'), "HASH\n", '+{...} is interpreted as anon hash';
1924 open(BLOCK, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1927 {foo=>"bar"} # this is a block, not a hash!
1930 close BLOCK or die "Could not close: $!";
1931 is cat('Op_write.tmp'), "foo bar\n", 'initial { is always BLOCK';
1933 # pragmata inside argument line
1934 open(STRICT, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1941 close STRICT or die "Could not close: $!";
1942 is cat('Op_write.tmp'), "oof:\n", 'pragmata on format line';
1945 skip "no weak refs" unless eval { require Scalar::Util };
1947 format Potshriggley =
1950 Scalar::Util::weaken(my $x = *Potshriggley{FORMAT});
1951 undef *Potshriggley;
1952 is $x, undef, 'formats in subs do not leak';
1955 fresh_perl_is(<<'EOP', <<'EXPECT',
1956 use warnings 'syntax' ;
1965 { stderr => 1 }, '#123245 panic in sv_chop');
1967 fresh_perl_is(<<'EOP', <<'EXPECT',
1968 use warnings 'syntax' ;
1975 Not enough format arguments at - line 4.
1978 { stderr => 1 }, '#123245 different panic in sv_chop');
1980 fresh_perl_is(<<'EOP', <<'EXPECT',
1982 # x at the end to make the spaces visible
1990 { stderr => 1 }, '#123538 crash in FF_MORE');
1992 # this used to assert fail
1993 fresh_perl_like(<<'EOP',
2000 qr/Use of comma-less variable list is deprecated.*got here/s,
2002 '#128255 Assert fail in S_sublex_done');
2005 #############################
2007 ## Add new tests *above* here
2008 #############################
2010 # scary format testing from H.Merijn Brand
2012 # Just a complete test for format, including top-, left- and bottom marging
2013 # and format detection through glob entries
2015 if ($^O eq 'VMS' || $^O eq 'MSWin32' || $^O eq 'dos' ||
2016 ($^O eq 'os2' and not eval '$OS2::can_fork')) {
2017 $test = curr_test();
2019 skip "'|-' and '-|' not supported", $tests - $test + 1;
2026 $= = 7; # Page length
2027 $- = 0; # Lines left
2028 my $ps = $^L; $^L = ""; # Catch the page separator
2029 my $tm = 1; # Top margin (empty lines before first output)
2030 my $bm = 2; # Bottom marging (empty lines between last text and footer)
2031 my $lm = 4; # Left margin (indent in spaces)
2033 # -----------------------------------------------------------------------
2035 # execute the rest of the script in a child process. The parent reads the
2036 # output from the child and compares it with <DATA>.
2040 select ((select (STDOUT), $| = 1)[0]); # flush STDOUT
2042 my $opened = open FROM_CHILD, "-|";
2043 unless (defined $opened) {
2044 fail "open gave $!";
2053 while (<FROM_CHILD>) {
2055 fail 'too much output';
2059 my $exp = shift @data;
2063 is "@data", "", "correct length of output";
2070 select ((select (STDOUT), $| = 1)[0]);
2072 $= -= $bm + 1; # count one for the trailing "----"
2085 $% == 1 and return "";
2087 $lastmin < $= and print "\n" x $lastmin;
2088 print "\n" x $bm, "----\n", $ps;
2093 # Yes, this is sick ;-)
2103 @{(shift @E)||["",""]}
2113 exists $::{$fmt} or return 0;
2114 $^O eq "MSWin32" or return defined *{$::{$fmt}}{FORMAT};
2115 open my $null, "> /dev/null" or die;
2116 my $fh = select $null;
2123 $^ = has_format ("TOP") ? "TOP" : "EMPTY";
2124 has_format ("ENTRY") or die "No format defined for ENTRY";
2125 foreach my $e ( [ map { [ $_, "Test$_" ] } 1 .. 7 ],
2126 [ map { [ $_, "${_}tseT" ] } 1 .. 5 ]) {
2130 has_format ("EOR") or next;
2134 if (has_format ("EOF")) {