This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Remove deprecated comma-less format variable lists
[perl5.git] / t / op / write.t
CommitLineData
a687059c
LW
1#!./perl
2
9ccde9ea
JH
3BEGIN {
4 chdir 't' if -d 't';
6108250c 5 require './test.pl';
43ece5b1 6 set_up_inc('../lib');
9ccde9ea
JH
7}
8
90f67b00 9use strict; # Amazed that this hackery can be made strict ...
9b4bdfd4 10use Tie::Scalar;
90f67b00 11
a344b90b
DM
12# read in a file
13sub cat {
14 my $file = shift;
15 local $/;
16 open my $fh, $file or die "can't open '$file': $!";
17 my $data = <$fh>;
18 close $fh;
19 $data;
20}
21
9b4bdfd4
DM
22# read in a utf-8 file
23#
24sub cat_utf8 {
25 my $file = shift;
26 local $/;
27 open my $fh, '<', $file or die "can't open '$file': $!";
28 binmode $fh, ':utf8';
29 my $data = <$fh> // die "Can't read from '$file': $!";
30 close $fh or die "error closing '$file': $!";
31 $data;
32}
33
34# write a format to a utf8 file, then read it back in and compare
35
36sub is_format_utf8 {
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': $!";
41 write $glob;
42 close $glob or die "Could not close '$file': $!";
43 is(cat_utf8($file), $want, $desc);
44}
45
46sub 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': $!";
51 write $glob;
52 close $glob or die "Could not close '$file': $!";
53 like(cat_utf8($file), $want, $desc);
54}
55
56
57
a1b95068
WL
58#-- testing numeric fields in all variants (WL)
59
60sub swrite {
61 my $format = shift;
62 local $^A = ""; # don't litter, use a local bin
63 formline( $format, @_ );
64 return $^A;
65}
66
67my @NumTests = (
d1f6232e 68 # [ format, value1, expected1, value2, expected2, .... ]
9acd3e2c
DM
69 [ '@###', 0, ' 0', 1, ' 1', 9999.6, '####',
70 9999.4999, '9999', -999.6, '####', 1e+100, '####' ],
d1f6232e 71
9acd3e2c
DM
72 [ '@0##', 0, '0000', 1, '0001', 9999.6, '####',
73 -999.4999, '-999', -999.6, '####', 1e+100, '####' ],
d1f6232e
DM
74
75 [ '^###', 0, ' 0', undef, ' ' ],
76
77 [ '^0##', 0, '0000', undef, ' ' ],
78
9acd3e2c
DM
79 [ '@###.', 0, ' 0.', 1, ' 1.', 9999.6, '#####',
80 9999.4999, '9999.', -999.6, '#####' ],
d1f6232e 81
9acd3e2c 82 [ '@##.##', 0, ' 0.00', 1, ' 1.00', 999.996, '######',
d1f6232e
DM
83 999.99499, '999.99', -100, '######' ],
84
85 [ '@0#.##', 0, '000.00', 1, '001.00', 10, '010.00',
8975a8c2 86 -0.0001, qr/^[\-0]00\.00$/ ],
d1f6232e
DM
87
88);
89
a1b95068
WL
90
91my $num_tests = 0;
92for my $tref ( @NumTests ){
d1f6232e 93 $num_tests += (@$tref - 1)/2;
a1b95068
WL
94}
95#---------------------------------------------------------
96
97# number of tests in section 1
b27dce25 98my $bas_tests = 21;
a1b95068
WL
99
100# number of tests in section 3
c7321345 101my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 6 + 2 + 3 + 96 + 11 + 14;
a1b95068 102
f5b75c1c 103# number of tests in section 4
f60e6763 104my $hmb_tests = 37;
f5b75c1c
NC
105
106my $tests = $bas_tests + $num_tests + $bug_tests + $hmb_tests;
6108250c
NC
107
108plan $tests;
a687059c 109
a1b95068
WL
110############
111## Section 1
112############
113
90f67b00
NC
114use vars qw($fox $multiline $foo $good);
115
a687059c
LW
116format OUT =
117the quick brown @<<
118$fox
119jumped
120@*
121$multiline
122^<<<<<<<<<
123$foo
124^<<<<<<<<<
125$foo
126^<<<<<<...
127$foo
128now @<<the@>>>> for all@|||||men to come @<<<<
a0d0e21e
LW
129{
130 'i' . 's', "time\n", $good, 'to'
131}
a687059c
LW
132.
133
a0d0e21e 134open(OUT, '>Op_write.tmp') || die "Can't create Op_write.tmp";
951af6b5 135END { unlink_all 'Op_write.tmp' }
a687059c
LW
136
137$fox = 'foxiness';
138$good = 'good';
139$multiline = "forescore\nand\nseven years\n";
140$foo = 'when in the course of human events it becomes necessary';
141write(OUT);
d1e4d418 142close OUT or die "Could not close: $!";
a687059c 143
90f67b00 144my $right =
a687059c
LW
145"the quick brown fox
146jumped
147forescore
148and
149seven years
150when in
151the course
152of huma...
153now is the time for all good men to come to\n";
154
951af6b5 155is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
a687059c 156
748a9306
LW
157$fox = 'wolfishness';
158my $fox = 'foxiness'; # Test a lexical variable.
159
a687059c
LW
160format OUT2 =
161the quick brown @<<
162$fox
163jumped
164@*
165$multiline
166^<<<<<<<<< ~~
167$foo
168now @<<the@>>>> for all@|||||men to come @<<<<
169'i' . 's', "time\n", $good, 'to'
170.
171
a0d0e21e 172open OUT2, '>Op_write.tmp' or die "Can't create Op_write.tmp";
a687059c 173
a687059c
LW
174$good = 'good';
175$multiline = "forescore\nand\nseven years\n";
176$foo = 'when in the course of human events it becomes necessary';
177write(OUT2);
d1e4d418 178close OUT2 or die "Could not close: $!";
a687059c
LW
179
180$right =
181"the quick brown fox
182jumped
183forescore
184and
185seven years
186when in
187the course
188of human
189events it
190becomes
191necessary
192now is the time for all good men to come to\n";
193
951af6b5 194is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
a687059c 195
0f85fab0
LW
196eval <<'EOFORMAT';
197format OUT2 =
198the brown quick @<<
199$fox
200jumped
201@*
202$multiline
a0d0e21e 203and
0f85fab0
LW
204^<<<<<<<<< ~~
205$foo
206now @<<the@>>>> for all@|||||men to come @<<<<
207'i' . 's', "time\n", $good, 'to'
208.
209EOFORMAT
210
a0d0e21e 211open(OUT2, '>Op_write.tmp') || die "Can't create Op_write.tmp";
0f85fab0
LW
212
213$fox = 'foxiness';
214$good = 'good';
215$multiline = "forescore\nand\nseven years\n";
216$foo = 'when in the course of human events it becomes necessary';
217write(OUT2);
d1e4d418 218close OUT2 or die "Could not close: $!";
0f85fab0
LW
219
220$right =
221"the brown quick fox
222jumped
223forescore
224and
225seven years
a0d0e21e 226and
0f85fab0
LW
227when in
228the course
229of human
230events it
231becomes
232necessary
233now is the time for all good men to come to\n";
234
951af6b5 235is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
0f85fab0 236
55497cff 237# formline tests
238
90f67b00 239$right = <<EOT;
55497cff 240@ a
241@> ab
242@>> abc
243@>>> abc
244@>>>> abc
245@>>>>> abc
246@>>>>>> abc
247@>>>>>>> abc
248@>>>>>>>> abc
249@>>>>>>>>> abc
250@>>>>>>>>>> abc
251EOT
252
90f67b00
NC
253my $was1 = my $was2 = '';
254use vars '$format2';
55497cff 255for (0..10) {
256 # lexical picture
257 $^A = '';
258 my $format1 = '@' . '>' x $_;
259 formline $format1, 'abc';
260 $was1 .= "$format1 $^A\n";
261 # global
262 $^A = '';
263 local $format2 = '@' . '>' x $_;
264 formline $format2, 'abc';
265 $was2 .= "$format2 $^A\n";
266}
90f67b00
NC
267is $was1, $right;
268is $was2, $right;
55497cff 269
7056ecde
KM
270$^A = '';
271
272# more test
273
274format OUT3 =
275^<<<<<<...
276$foo
277.
278
279open(OUT3, '>Op_write.tmp') || die "Can't create Op_write.tmp";
280
281$foo = 'fit ';
282write(OUT3);
d1e4d418 283close OUT3 or die "Could not close: $!";
7056ecde
KM
284
285$right =
286"fit\n";
287
951af6b5 288is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
2027357e 289
7056ecde 290
445b3f51
GS
291# test lexicals and globals
292{
2027357e 293 my $test = curr_test();
445b3f51 294 my $this = "ok";
2027357e 295 our $that = $test;
445b3f51
GS
296 format LEX =
297@<<@|
298$this,$that
299.
300 open(LEX, ">&STDOUT") or die;
301 write LEX;
2027357e 302 $that = ++$test;
445b3f51 303 write LEX;
d1e4d418 304 close LEX or die "Could not close: $!";
2027357e 305 curr_test($test + 1);
445b3f51 306}
c2e66d9e
GS
307# LEX_INTERPNORMAL test
308my %e = ( a => 1 );
309format OUT4 =
310@<<<<<<
311"$e{a}"
312.
313open OUT4, ">Op_write.tmp" or die "Can't create Op_write.tmp";
314write (OUT4);
d1e4d418 315close OUT4 or die "Could not close: $!";
951af6b5 316is cat('Op_write.tmp'), "1\n" and unlink_all "Op_write.tmp";
784707d5 317
b27dce25
FC
318# More LEX_INTERPNORMAL
319format OUT4a=
320@<<<<<<<<<<<<<<<
321"${; use
322 strict; \'Nasdaq dropping like flies'}"
323.
324open OUT4a, ">Op_write.tmp" or die "Can't create Op_write.tmp";
325write (OUT4a);
326close OUT4a or die "Could not close: $!";
327is cat('Op_write.tmp'), "Nasdaq dropping\n", 'skipspace inside "${...}"'
328 and unlink_all "Op_write.tmp";
329
784707d5
JP
330eval <<'EOFORMAT';
331format OUT10 =
332@####.## @0###.##
333$test1, $test1
334.
335EOFORMAT
336
337open(OUT10, '>Op_write.tmp') || die "Can't create Op_write.tmp";
338
90f67b00 339use vars '$test1';
784707d5
JP
340$test1 = 12.95;
341write(OUT10);
d1e4d418 342close OUT10 or die "Could not close: $!";
784707d5
JP
343
344$right = " 12.95 00012.95\n";
951af6b5 345is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
784707d5
JP
346
347eval <<'EOFORMAT';
348format OUT11 =
349@0###.##
350$test1
351@ 0#
352$test1
353@0 #
354$test1
355.
356EOFORMAT
357
358open(OUT11, '>Op_write.tmp') || die "Can't create Op_write.tmp";
359
360$test1 = 12.95;
361write(OUT11);
d1e4d418 362close OUT11 or die "Could not close: $!";
784707d5
JP
363
364$right =
365"00012.95
3661 0#
36710 #\n";
951af6b5 368is cat('Op_write.tmp'), $right and unlink_all 'Op_write.tmp';
9ccde9ea 369
31869a79 370{
2027357e 371 my $test = curr_test();
71f882da 372 my $el;
a1b95068 373 format OUT12 =
31869a79
AE
374ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze
375$el
376.
2027357e 377 my %hash = ($test => 3);
a1b95068
WL
378 open(OUT12, '>Op_write.tmp') || die "Can't create Op_write.tmp";
379
31869a79 380 for $el (keys %hash) {
a1b95068 381 write(OUT12);
31869a79 382 }
a1b95068 383 close OUT12 or die "Could not close: $!";
a344b90b 384 print cat('Op_write.tmp');
2027357e 385 curr_test($test + 1);
31869a79
AE
386}
387
ea42cebc 388{
2027357e 389 my $test = curr_test();
ea42cebc 390 # Bug report and testcase by Alexey Tourbin
ea42cebc
RGS
391 my $v;
392 tie $v, 'Tie::StdScalar';
2027357e 393 $v = $test;
ea42cebc
RGS
394 format OUT13 =
395ok ^<<<<<<<<< ~~
396$v
397.
398 open(OUT13, '>Op_write.tmp') || die "Can't create Op_write.tmp";
399 write(OUT13);
400 close OUT13 or die "Could not close: $!";
a344b90b 401 print cat('Op_write.tmp');
2027357e 402 curr_test($test + 1);
ea42cebc
RGS
403}
404
a1b95068
WL
405{ # test 14
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)
f5c235e7
DM
408 my @v = ('k');
409 eval "format OUT14 = \n@\n\@v";
2027357e 410 like $@, qr/Format not terminated/;
f5c235e7
DM
411}
412
a1b95068
WL
413{ # test 15
414 # text lost in ^<<< field with \r in value (WL)
415 my $txt = "line 1\rline 2";
416 format OUT15 =
417^<<<<<<<<<<<<<<<<<<
418$txt
419^<<<<<<<<<<<<<<<<<<
420$txt
421.
422 open(OUT15, '>Op_write.tmp') || die "Can't create Op_write.tmp";
423 write(OUT15);
424 close OUT15 or die "Could not close: $!";
a344b90b 425 my $res = cat('Op_write.tmp');
2027357e 426 is $res, "line 1\nline 2\n";
a1b95068
WL
427}
428
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";
431 format OUT16 =
432^<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<
433$txt, $txt
434^<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<
435$txt, $txt
436.
437 open(OUT16, '>Op_write.tmp') || die "Can't create Op_write.tmp";
438 write(OUT16);
439 close OUT16 or die "Could not close: $!";
a344b90b 440 my $res = cat('Op_write.tmp');
2027357e 441 is $res, <<EOD;
a1b95068
WL
442this_is_block_1 this_is_block_2
443this_is_block_3 this_is_block_4
444EOD
445}
446
447{ # test 17: @* "should be on a line of its own", but it should work
448 # cleanly with literals before and after. (WL)
449
450 my $txt = "This is line 1.\nThis is the second line.\nThird and last.\n";
451 format OUT17 =
452Here we go: @* That's all, folks!
453 $txt
454.
455 open(OUT17, '>Op_write.tmp') || die "Can't create Op_write.tmp";
456 write(OUT17);
457 close OUT17 or die "Could not close: $!";
a344b90b 458 my $res = cat('Op_write.tmp');
a1b95068
WL
459 chomp( $txt );
460 my $exp = <<EOD;
461Here we go: $txt That's all, folks!
462EOD
2027357e 463 is $res, $exp;
a1b95068
WL
464}
465
466{ # test 18: @# and ~~ would cause runaway format, but we now
467 # catch this while compiling (WL)
468
469 format OUT18 =
470@######## ~~
47110
472.
473 open(OUT18, '>Op_write.tmp') || die "Can't create Op_write.tmp";
474 eval { write(OUT18); };
2027357e 475 like $@, qr/Repeated format line will never terminate/;
a1b95068
WL
476 close OUT18 or die "Could not close: $!";
477}
478
479{ # test 19: \0 in an evel'ed format, doesn't cause empty lines (WL)
480 my $v = 'gaga';
481 eval "format OUT19 = \n" .
482 '@<<<' . "\0\n" .
483 '$v' . "\n" .
484 '@<<<' . "\0\n" .
485 '$v' . "\n.\n";
486 open(OUT19, '>Op_write.tmp') || die "Can't create Op_write.tmp";
487 write(OUT19);
a344b90b
DM
488 close OUT19 or die "Could not close: $!";
489 my $res = cat('Op_write.tmp');
2027357e 490 is $res, <<EOD;
a1b95068
WL
491gaga\0
492gaga\0
493EOD
494}
495
496{ # test 20: hash accesses; single '}' must not terminate format '}' (WL)
497 my %h = ( xkey => 'xval', ykey => 'yval' );
498 format OUT20 =
499@>>>> @<<<< ~~
500each %h
501@>>>> @<<<<
502$h{xkey}, $h{ykey}
503@>>>> @<<<<
504{ $h{xkey}, $h{ykey}
505}
506}
507.
508 my $exp = '';
509 while( my( $k, $v ) = each( %h ) ){
510 $exp .= sprintf( "%5s %s\n", $k, $v );
511 }
512 $exp .= sprintf( "%5s %s\n", $h{xkey}, $h{ykey} );
513 $exp .= sprintf( "%5s %s\n", $h{xkey}, $h{ykey} );
514 $exp .= "}\n";
515 open(OUT20, '>Op_write.tmp') || die "Can't create Op_write.tmp";
516 write(OUT20);
a344b90b
DM
517 close OUT20 or die "Could not close: $!";
518 my $res = cat('Op_write.tmp');
2027357e 519 is $res, $exp;
a1b95068
WL
520}
521
522
523#####################
524## Section 2
525## numeric formatting
526#####################
527
2027357e
NC
528curr_test($bas_tests + 1);
529
a1b95068
WL
530for my $tref ( @NumTests ){
531 my $writefmt = shift( @$tref );
d1f6232e
DM
532 while (@$tref) {
533 my $val = shift @$tref;
534 my $expected = shift @$tref;
a1b95068 535 my $writeres = swrite( $writefmt, $val );
2027357e
NC
536 if (ref $expected) {
537 like $writeres, $expected, $writefmt;
538 } else {
539 is $writeres, $expected, $writefmt;
540 }
a1b95068
WL
541 }
542}
543
544
545#####################################
546## Section 3
f5b75c1c 547## Easiest to add new tests just here
2027357e 548#####################################
9ccde9ea 549
30a1e583
DM
550# DAPM. Exercise a couple of error codepaths
551
552{
553 local $~ = '';
554 eval { write };
2d1ebc9b 555 like $@, qr/Undefined format ""/, 'format with 0-length name';
30a1e583 556
44b7e78a
FC
557 $~ = "\0foo";
558 eval { write };
559 like $@, qr/Undefined format "\0foo"/,
560 'no such format beginning with null';
561
30a1e583
DM
562 $~ = "NOSUCHFORMAT";
563 eval { write };
44b7e78a 564 like $@, qr/Undefined format "NOSUCHFORMAT"/, 'no such format';
30a1e583
DM
565}
566
44b7e78a
FC
567select +(select(OUT21), do {
568 open(OUT21, '>Op_write.tmp') || die "Can't create Op_write.tmp";
569
570 format OUT21 =
571@<<
572$_
573.
574
575 local $^ = '';
576 local $= = 1;
577 $_ = "aataaaaaaaaaaaaaa"; eval { write(OUT21) };
578 like $@, qr/Undefined top format ""/, 'top format with 0-length name';
579
580 $^ = "\0foo";
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';
586
587 $^ = "NOSUCHFORMAT";
588 $_ = "aataaaaaaaaaaaaaa"; eval { write(OUT21) };
589 $_ = "aataaaaaaaaaaaaaa"; eval { write(OUT21) };
590 like $@, qr/Undefined top format "NOSUCHFORMAT"/, 'no such top format';
591
592 # reset things;
593 eval { write(OUT21) };
594 undef $^A;
595
596 close OUT21 or die "Could not close: $!";
597})[0];
598
9b4bdfd4
DM
599
600
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.
605
606
607my $u22a = "N" x 8;
608
609format OUT22a =
610'^<<<<<<<<'~~
611$u22a
612.
613
614is_format_utf8(\*OUT22a,
615 "'NNNNNNNN '\n");
616
617
618my $u22b = "N" x 8;
619utf8::upgrade($u22b);
620
621format OUT22b =
622'^<<<<<<<<'~~
623$u22b
624.
625
626is_format_utf8(\*OUT22b,
627 "'NNNNNNNN '\n");
628
629my $u22c = "\x{FF}" x 8;
630
631format OUT22c =
632'^<<<<<<<<'~~
633$u22c
634.
635
636is_format_utf8(\*OUT22c,
637 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
638
639my $u22d = "\x{FF}" x 8;
640utf8::upgrade($u22d);
641
642format OUT22d =
643'^<<<<<<<<'~~
644$u22d
645.
646
647is_format_utf8(\*OUT22d,
648 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
649
650my $u22e = "\x{100}" x 8;
651
652format OUT22e =
653'^<<<<<<<<'~~
654$u22e
655.
656
657is_format_utf8(\*OUT22e,
658 "'\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} '\n");
659
660
661my $u22f = "N" x 8;
662
663format OUT22f =
664'^<'~~
665$u22f
666.
667
668is_format_utf8(\*OUT22f,
669 "'NN'\n"x4);
670
671
672my $u22g = "N" x 8;
673utf8::upgrade($u22g);
674
675format OUT22g =
676'^<'~~
677$u22g
678.
679
680is_format_utf8(\*OUT22g,
681 "'NN'\n"x4);
682
683my $u22h = "\x{FF}" x 8;
684
685format OUT22h =
686'^<'~~
687$u22h
688.
689
690is_format_utf8(\*OUT22h,
691 "'\x{FF}\x{FF}'\n"x4);
692
693my $u22i = "\x{FF}" x 8;
694utf8::upgrade($u22i);
695
696format OUT22i =
697'^<'~~
698$u22i
699.
700
701is_format_utf8(\*OUT22i,
702 "'\x{FF}\x{FF}'\n"x4);
703
704my $u22j = "\x{100}" x 8;
705
706format OUT22j =
707'^<'~~
708$u22j
709.
710
711is_format_utf8(\*OUT22j,
712 "'\x{100}\x{100}'\n"x4);
713
714
715tie my $u23a, 'Tie::StdScalar';
716$u23a = "N" x 8;
717
718format OUT23a =
719'^<<<<<<<<'~~
720$u23a
721.
722
723is_format_utf8(\*OUT23a,
724 "'NNNNNNNN '\n");
725
726
727tie my $u23b, 'Tie::StdScalar';
728$u23b = "N" x 8;
729utf8::upgrade($u23b);
730
731format OUT23b =
732'^<<<<<<<<'~~
733$u23b
734.
735
736is_format_utf8(\*OUT23b,
737 "'NNNNNNNN '\n");
738
739tie my $u23c, 'Tie::StdScalar';
740$u23c = "\x{FF}" x 8;
741
742format OUT23c =
743'^<<<<<<<<'~~
744$u23c
745.
746
747is_format_utf8(\*OUT23c,
748 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
749
750tie my $u23d, 'Tie::StdScalar';
751my $temp = "\x{FF}" x 8;
752utf8::upgrade($temp);
753$u23d = $temp;
754
755format OUT23d =
756'^<<<<<<<<'~~
757$u23d
758.
759
760is_format_utf8(\*OUT23d,
761 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
762
763tie my $u23e, 'Tie::StdScalar';
764$u23e = "\x{100}" x 8;
765
766format OUT23e =
767'^<<<<<<<<'~~
768$u23e
769.
770
771is_format_utf8(\*OUT23e,
772 "'\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} '\n");
773
774tie my $u23f, 'Tie::StdScalar';
775$u23f = "N" x 8;
776
777format OUT23f =
778'^<'~~
779$u23f
780.
781
782is_format_utf8(\*OUT23f,
783 "'NN'\n"x4);
784
785
786tie my $u23g, 'Tie::StdScalar';
787my $temp = "N" x 8;
788utf8::upgrade($temp);
789$u23g = $temp;
790
791format OUT23g =
792'^<'~~
793$u23g
794.
795
796is_format_utf8(\*OUT23g,
797 "'NN'\n"x4);
798
799tie my $u23h, 'Tie::StdScalar';
800$u23h = "\x{FF}" x 8;
801
802format OUT23h =
803'^<'~~
804$u23h
805.
806
807is_format_utf8(\*OUT23h,
808 "'\x{FF}\x{FF}'\n"x4);
809
810$temp = "\x{FF}" x 8;
811utf8::upgrade($temp);
812tie my $u23i, 'Tie::StdScalar';
813$u23i = $temp;
814
815format OUT23i =
816'^<'~~
817$u23i
818.
819
820is_format_utf8(\*OUT23i,
821 "'\x{FF}\x{FF}'\n"x4);
822
823tie my $u23j, 'Tie::StdScalar';
824$u23j = "\x{100}" x 8;
825
826format OUT23j =
827'^<'~~
828$u23j
829.
830
831is_format_utf8(\*OUT23j,
832 "'\x{100}\x{100}'\n"x4);
833
834{
835 package UTF8Toggle;
836
837 sub TIESCALAR {
838 my $class = shift;
839 my $value = shift;
840 my $state = shift||0;
841 return bless [$value, $state], $class;
842 }
843
844 sub FETCH {
845 my $self = shift;
846 $self->[1] = ! $self->[1];
847 if ($self->[1]) {
848 utf8::downgrade($self->[0]);
849 } else {
850 utf8::upgrade($self->[0]);
851 }
852 $self->[0];
853 }
854
855 sub STORE {
856 my $self = shift;
857 $self->[0] = shift;
858 }
859}
860
861tie my $u24a, 'UTF8Toggle';
862$u24a = "N" x 8;
863
864format OUT24a =
865'^<<<<<<<<'~~
866$u24a
867.
868
869is_format_utf8(\*OUT24a,
870 "'NNNNNNNN '\n");
871
872
873tie my $u24b, 'UTF8Toggle';
874$u24b = "N" x 8;
875utf8::upgrade($u24b);
876
877format OUT24b =
878'^<<<<<<<<'~~
879$u24b
880.
881
882is_format_utf8(\*OUT24b,
883 "'NNNNNNNN '\n");
884
885tie my $u24c, 'UTF8Toggle';
886$u24c = "\x{FF}" x 8;
887
888format OUT24c =
889'^<<<<<<<<'~~
890$u24c
891.
892
893is_format_utf8(\*OUT24c,
894 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
895
896tie my $u24d, 'UTF8Toggle', 1;
897$u24d = "\x{FF}" x 8;
898
899format OUT24d =
900'^<<<<<<<<'~~
901$u24d
902.
903
904is_format_utf8(\*OUT24d,
905 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
906
907
908
909tie my $u24f, 'UTF8Toggle';
910$u24f = "N" x 8;
911
912format OUT24f =
913'^<'~~
914$u24f
915.
916
917is_format_utf8(\*OUT24f,
918 "'NN'\n"x4);
919
920
921tie my $u24g, 'UTF8Toggle';
922my $temp = "N" x 8;
923utf8::upgrade($temp);
924$u24g = $temp;
925
926format OUT24g =
927'^<'~~
928$u24g
929.
930
931is_format_utf8(\*OUT24g,
932 "'NN'\n"x4);
933
934tie my $u24h, 'UTF8Toggle';
935$u24h = "\x{FF}" x 8;
936
937format OUT24h =
938'^<'~~
939$u24h
940.
941
942is_format_utf8(\*OUT24h,
943 "'\x{FF}\x{FF}'\n"x4);
944
945tie my $u24i, 'UTF8Toggle', 1;
946$u24i = "\x{FF}" x 8;
947
948format OUT24i =
949'^<'~~
950$u24i
951.
952
953is_format_utf8(\*OUT24i,
954 "'\x{FF}\x{FF}'\n"x4);
955
956{
957 package OS;
958 use overload '""' => sub { ${$_[0]}; };
959
960 sub new {
961 my ($class, $value) = @_;
962 bless \$value, $class;
963 }
964}
965
966my $u25a = OS->new("N" x 8);
967
968format OUT25a =
969'^<<<<<<<<'~~
970$u25a
971.
972
973is_format_utf8(\*OUT25a,
974 "'NNNNNNNN '\n");
975
976
977my $temp = "N" x 8;
978utf8::upgrade($temp);
979my $u25b = OS->new($temp);
980
981format OUT25b =
982'^<<<<<<<<'~~
983$u25b
984.
985
986is_format_utf8(\*OUT25b,
987 "'NNNNNNNN '\n");
988
989my $u25c = OS->new("\x{FF}" x 8);
990
991format OUT25c =
992'^<<<<<<<<'~~
993$u25c
994.
995
996is_format_utf8(\*OUT25c,
997 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
998
999$temp = "\x{FF}" x 8;
1000utf8::upgrade($temp);
1001my $u25d = OS->new($temp);
1002
1003format OUT25d =
1004'^<<<<<<<<'~~
1005$u25d
1006.
1007
1008is_format_utf8(\*OUT25d,
1009 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
1010
1011my $u25e = OS->new("\x{100}" x 8);
1012
1013format OUT25e =
1014'^<<<<<<<<'~~
1015$u25e
1016.
1017
1018is_format_utf8(\*OUT25e,
1019 "'\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} '\n");
1020
1021
1022my $u25f = OS->new("N" x 8);
1023
1024format OUT25f =
1025'^<'~~
1026$u25f
1027.
1028
1029is_format_utf8(\*OUT25f,
1030 "'NN'\n"x4);
1031
1032
1033$temp = "N" x 8;
1034utf8::upgrade($temp);
1035my $u25g = OS->new($temp);
1036
1037format OUT25g =
1038'^<'~~
1039$u25g
1040.
1041
1042is_format_utf8(\*OUT25g,
1043 "'NN'\n"x4);
1044
1045my $u25h = OS->new("\x{FF}" x 8);
1046
1047format OUT25h =
1048'^<'~~
1049$u25h
1050.
1051
1052is_format_utf8(\*OUT25h,
1053 "'\x{FF}\x{FF}'\n"x4);
1054
1055$temp = "\x{FF}" x 8;
1056utf8::upgrade($temp);
1057my $u25i = OS->new($temp);
1058
1059format OUT25i =
1060'^<'~~
1061$u25i
1062.
1063
1064is_format_utf8(\*OUT25i,
1065 "'\x{FF}\x{FF}'\n"x4);
1066
1067my $u25j = OS->new("\x{100}" x 8);
1068
1069format OUT25j =
1070'^<'~~
1071$u25j
1072.
1073
1074is_format_utf8(\*OUT25j,
1075 "'\x{100}\x{100}'\n"x4);
1076
1077{
1078 package OS::UTF8Toggle;
1079 use overload '""' => sub {
1080 my $self = shift;
1081 $self->[1] = ! $self->[1];
1082 if ($self->[1]) {
1083 utf8::downgrade($self->[0]);
1084 } else {
1085 utf8::upgrade($self->[0]);
1086 }
1087 $self->[0];
1088 };
1089
1090 sub new {
1091 my ($class, $value, $state) = @_;
1092 bless [$value, $state], $class;
1093 }
1094}
1095
1096
1097my $u26a = OS::UTF8Toggle->new("N" x 8);
1098
1099format OUT26a =
1100'^<<<<<<<<'~~
1101$u26a
1102.
1103
1104is_format_utf8(\*OUT26a,
1105 "'NNNNNNNN '\n");
1106
1107
1108my $u26b = OS::UTF8Toggle->new("N" x 8, 1);
1109
1110format OUT26b =
1111'^<<<<<<<<'~~
1112$u26b
1113.
1114
1115is_format_utf8(\*OUT26b,
1116 "'NNNNNNNN '\n");
1117
1118my $u26c = OS::UTF8Toggle->new("\x{FF}" x 8);
1119
1120format OUT26c =
1121'^<<<<<<<<'~~
1122$u26c
1123.
1124
1125is_format_utf8(\*OUT26c,
1126 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
1127
1128my $u26d = OS::UTF8Toggle->new("\x{FF}" x 8, 1);
1129
1130format OUT26d =
1131'^<<<<<<<<'~~
1132$u26d
1133.
1134
1135is_format_utf8(\*OUT26d,
1136 "'\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF} '\n");
1137
1138
1139my $u26f = OS::UTF8Toggle->new("N" x 8);
1140
1141format OUT26f =
1142'^<'~~
1143$u26f
1144.
1145
1146is_format_utf8(\*OUT26f,
1147 "'NN'\n"x4);
1148
1149
1150my $u26g = OS::UTF8Toggle->new("N" x 8, 1);
1151
1152format OUT26g =
1153'^<'~~
1154$u26g
1155.
1156
1157is_format_utf8(\*OUT26g,
1158 "'NN'\n"x4);
1159
1160my $u26h = OS::UTF8Toggle->new("\x{FF}" x 8);
1161
1162format OUT26h =
1163'^<'~~
1164$u26h
1165.
1166
1167is_format_utf8(\*OUT26h,
1168 "'\x{FF}\x{FF}'\n"x4);
1169
1170my $u26i = OS::UTF8Toggle->new("\x{FF}" x 8, 1);
1171
1172format OUT26i =
1173'^<'~~
1174$u26i
1175.
1176
1177is_format_utf8(\*OUT26i,
1178 "'\x{FF}\x{FF}'\n"x4);
1179
1180
1181
1182{
1183 my $zero = $$ - $$;
1184
1185 package Number;
1186
1187 sub TIESCALAR {
1188 my $class = shift;
1189 my $value = shift;
1190 return bless \$value, $class;
1191 }
1192
1193 # The return value should always be SvNOK() only:
1194 sub FETCH {
1195 my $self = shift;
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;
1200 }
1201
1202 sub STORE {
1203 my $self = shift;
1204 $$self = shift;
1205 }
1206
1207 package ONumber;
1208
1209 use overload '""' => sub {
1210 my $self = shift;
1211 return $$self - 0.5 + $zero + 0.5;
1212 };
1213
1214 sub new {
1215 my $class = shift;
1216 my $value = shift;
1217 return bless \$value, $class;
1218 }
1219}
1220
1221my $v27a = 1/256;
1222
1223format OUT27a =
1224'^<<<<<<<<<'~~
1225$v27a
1226.
1227
1228is_format_utf8(\*OUT27a,
1229 "'0.00390625'\n");
1230
1231my $v27b = 1/256;
1232
1233format OUT27b =
1234'^<'~~
1235$v27b
1236.
1237
1238is_format_utf8(\*OUT27b,
1239 "'0.'\n'00'\n'39'\n'06'\n'25'\n");
1240
1241tie my $v27c, 'Number', 1/256;
1242
1243format OUT27c =
1244'^<<<<<<<<<'~~
1245$v27c
1246.
1247
1248is_format_utf8(\*OUT27c,
1249 "'0.00390625'\n");
1250
1251my $v27d = 1/256;
1252
1253format OUT27d =
1254'^<'~~
1255$v27d
1256.
1257
1258is_format_utf8(\*OUT27d,
1259 "'0.'\n'00'\n'39'\n'06'\n'25'\n");
1260
1261my $v27e = ONumber->new(1/256);
1262
1263format OUT27e =
1264'^<<<<<<<<<'~~
1265$v27e
1266.
1267
1268is_format_utf8(\*OUT27e,
1269 "'0.00390625'\n");
1270
1271my $v27f = ONumber->new(1/256);
1272
1273format OUT27f =
1274'^<'~~
1275$v27f
1276.
1277
1278is_format_utf8(\*OUT27f,
1279 "'0.'\n'00'\n'39'\n'06'\n'25'\n");
1280
1281{
1282 package Ref;
1283 use overload '""' => sub {
1284 return ${$_[0]};
1285 };
1286
1287 sub new {
1288 my $class = shift;
1289 my $value = shift;
1290 return bless \$value, $class;
1291 }
1292}
1293
1294my $v28a = {};
1295
1296format OUT28a =
1297'^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'~~
1298$v28a
1299.
1300
1301
1302# 'HASH(0x1716b60) '
1303my $qr_hash = qr/^'HASH\(0x[0-9a-f]+\)\s+'\n$/;
1304
1305# 'HASH'
1306# '(0x1'
1307# '716b'
1308# 'c0) '
1309my $qr_hash_m = qr/^'HASH'\n('[0-9a-fx() ]{4}'\n)+$/;
1310
1311like_format_utf8(\*OUT28a, $qr_hash);
1312
1313my $v28b = {};
1314
1315format OUT28b =
1316'^<<<'~~
1317$v28b
1318.
1319
1320like_format_utf8(\*OUT28b, $qr_hash_m);
1321
1322
1323tie my $v28c, 'Tie::StdScalar';
1324$v28c = {};
1325
1326format OUT28c =
1327'^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'~~
1328$v28c
1329.
1330
1331like_format_utf8(\*OUT28c, $qr_hash);
1332
1333tie my $v28d, 'Tie::StdScalar';
1334$v28d = {};
1335
1336format OUT28d =
1337'^<<<'~~
1338$v28d
1339.
1340
1341like_format_utf8(\*OUT28d, $qr_hash_m);
1342
1343my $v28e = Ref->new({});
1344
1345format OUT28e =
1346'^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'~~
1347$v28e
1348.
1349
1350like_format_utf8(\*OUT28e, $qr_hash);
1351
1352my $v28f = Ref->new({});
1353
1354format OUT28f =
1355'^<<<'~~
1356$v28f
1357.
1358
1359like_format_utf8(\*OUT28f, $qr_hash_m);
1360
1361
1362
f3f2f1a3 1363{
e8e72d41
NC
1364 package Count;
1365
1366 sub TIESCALAR {
1367 my $class = shift;
1368 bless [shift, 0, 0], $class;
1369 }
1370
1371 sub FETCH {
1372 my $self = shift;
1373 ++$self->[1];
1374 $self->[0];
1375 }
1376
1377 sub STORE {
1378 my $self = shift;
1379 ++$self->[2];
1380 $self->[0] = shift;
1381 }
1382}
1383
1384{
1385 my ($pound_utf8, $pm_utf8) = map { my $a = "$_\x{100}"; chop $a; $a}
f3f2f1a3
NC
1386 my ($pound, $pm) = ("\xA3", "\xB1");
1387
1388 foreach my $first ('N', $pound, $pound_utf8) {
1389 foreach my $base ('N', $pm, $pm_utf8) {
003d2c64
NC
1390 foreach my $second ($base, "$base\n", "$base\nMoo!", "$base\nMoo!\n",
1391 "$base\nMoo!\n",) {
1392 foreach (['^*', qr/(.+)/], ['@*', qr/(.*?)$/s]) {
1393 my ($format, $re) = @$_;
b57b1734 1394 $format = "1^*2 3${format}4";
e8e72d41 1395 foreach my $class ('', 'Count') {
b57b1734 1396 my $name = qq{swrite("$format", "$first", "$second") class="$class"};
e8e72d41 1397 $name =~ s/\n/\\n/g;
b57b1734
DM
1398 $name =~ s{(.)}{
1399 ord($1) > 126 ? sprintf("\\x{%x}",ord($1)) : $1
1400 }ge;
e8e72d41
NC
1401
1402 $first =~ /(.+)/ or die $first;
1403 my $expect = "1${1}2";
1404 $second =~ $re or die $second;
1405 $expect .= " 3${1}4";
1406
1407 if ($class) {
1408 my $copy1 = $first;
1409 my $copy2;
1410 tie $copy2, $class, $second;
b57b1734 1411 is swrite("$format", $copy1, $copy2), $expect, $name;
e8e72d41
NC
1412 my $obj = tied $copy2;
1413 is $obj->[1], 1, 'value read exactly once';
1414 } else {
1415 my ($copy1, $copy2) = ($first, $second);
b57b1734 1416 is swrite("$format", $copy1, $copy2), $expect, $name;
e8e72d41
NC
1417 }
1418 }
003d2c64 1419 }
f3f2f1a3
NC
1420 }
1421 }
1422 }
1423}
9ccde9ea 1424
35c6393c
NC
1425{
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
1429 my $ref = [];
9b4bdfd4
DM
1430 my $exp = ">$ref<";
1431 is swrite('>^*<', $ref), $exp;
1432 $ref = [];
1433 my $exp = ">$ref<";
1434 is swrite('>@*<', $ref), $exp;
35c6393c
NC
1435}
1436
d57f9278
MB
1437format EMPTY =
1438.
1439
f5b75c1c 1440my $test = curr_test();
6108250c 1441
d57f9278
MB
1442format Comment =
1443ok @<<<<<
1444$test
1445.
1446
d57f9278 1447
64eff8b7 1448# RT #8698 format bug with undefined _TOP
0bd0581c
DM
1449
1450open STDOUT_DUP, ">&STDOUT";
1451my $oldfh = select STDOUT_DUP;
1452$= = 10;
6108250c
NC
1453{
1454 local $~ = "Comment";
1455 write;
1456 curr_test($test + 1);
64eff8b7 1457 is $-, 9;
6108250c 1458 is $^, "STDOUT_DUP_TOP";
0bd0581c
DM
1459}
1460select $oldfh;
68ba3c2c 1461close STDOUT_DUP;
d57f9278 1462
ef595a33
MB
1463*CmT = *{$::{Comment}}{FORMAT};
1464ok defined *{$::{CmT}}{FORMAT}, "glob assign";
1465
3808a683
DM
1466
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
1470
1471
1472{
1473 package RT91032;
1474
1475 sub TIESCALAR { bless [] }
1476 my $i = 0;
1477 sub FETCH { $i++; "A$i @> Z\n" }
1478
1479 use overload '""' => \&FETCH;
1480
1481 tie my $f, 'RT91032';
1482
1483 formline $f, "a";
1484 formline $f, "bc";
1485 ::is $^A, "A1 a Z\nA2 bc Z\n", "RT 91032: tied";
1486 $^A = '';
1487
1488 my $g = bless []; # has overloaded stringify
1489 formline $g, "de";
1490 formline $g, "f";
1491 ::is $^A, "A3 de Z\nA4 f Z\n", "RT 91032: overloaded";
1492 $^A = '';
1493
1494 my $h = [];
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";
1500 $^A = '';
1501
1502 # used to overwrite the ~~ in the *original SV with spaces. Naughty!
1503
1504 my $orig = my $format = "^<<<<< ~~\n";
1505 my $abc = "abc";
1506 formline $format, $abc;
1507 $^A ='';
1508 ::is $format, $orig, "RT91032: don't overwrite orig format string";
1509
b57b1734
DM
1510 # check that ~ and ~~ are displayed correctly as whitespace,
1511 # under the influence of various different types of border
1512
1513 for my $n (1,2) {
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;
1522 my $exp = $^A;
1523 $^A = '';
1524 ($a, $bc, $stop) = ('a', 'bc', 's');
1525 formline $fmt, $stop, $a, $bc;
1526 my $got = $^A;
1527 $^A = '';
1528 $fmt =~ s/\n/\\n/;
1529 ::is($got, $exp, "chop munging: [$fmt]");
1530 }
1531 }
1532 }
3808a683
DM
1533}
1534
f5ada144
DM
1535# check that '~ (delete current line if empty) works when
1536# the target gets upgraded to uft8 (and re-allocated) midstream.
1537
1538{
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";
1543 local $^A = $orig;
1544 my $empty = "";
1545 formline $format, $empty;
1546 is $^A , $orig, "~ and realloc";
1547
1548 # check similarly that trailing blank removal works ok
1549
1550 $format = "@<\n\x{100}"; # format is utf8
1551 chop $format;
1552 $orig = " ";
1553 $^A = $orig;
1554 formline $format, " ";
1555 is $^A, "$orig\n", "end-of-line blanks and realloc";
26e935cf
DM
1556
1557 # and check this doesn't overflow the buffer
1558
1559 local $^A = '';
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";
76912796 1564
e452bf1c
DM
1565 # ...nor this (RT #130703).
1566 # Under 'use bytes', the two bytes (c2, 80) making up each \x80 char
1567 # each get expanded to two bytes (so four in total per \x80 char); the
1568 # buffer growth wasn't accounting for this doubling in size
1569
1570 {
1571 local $^A = '';
1572 my $format = "X\n\x{100}" . ("\x80" x 200);
1573 my $expected = $format;
1574 utf8::encode($expected);
1575 use bytes;
1576 formline($format);
1577 is $^A, $expected, "RT #130703";
1578 }
1579
f62fd06d
DM
1580 # further buffer overflows with RT #130703
1581
1582 {
1583 local $^A = '';
1584 my $n = 200;
1585 my $long = 'x' x 300;
1586 my $numf = ('@###' x $n);
1587 my $expected = $long . "\n" . (" 1" x $n);
1588 formline("@*\n$numf", $long, ('1') x $n);
1589
1590 is $^A, $expected, "RT #130703 part 2";
1591 }
1592
e452bf1c 1593
76912796
DM
1594 # make sure it can cope with formats > 64k
1595
1596 $format = 'x' x 65537;
1597 $^A = '';
1598 formline $format;
1599 # don't use 'is' here, as the diag output will be too long!
1600 ok $^A eq $format, ">64K";
f5ada144
DM
1601}
1602
3808a683 1603
d3d1232e
NC
1604SKIP: {
1605 skip_if_miniperl('miniperl does not support scalario');
60fe2d11 1606 my $buf = "";
fda0c190
MB
1607 open my $fh, ">", \$buf;
1608 my $old_fh = select $fh;
1609 local $~ = "CmT";
1610 write;
1611 select $old_fh;
1612 close $fh;
1613 is $buf, "ok $test\n", "write to duplicated format";
1614}
1615
64eff8b7
DM
1616format caret_A_test_TOP =
1617T
1618.
1619
1620format caret_A_test =
1621L1
1622L2
1623L3
1624L4
1625.
1626
1627SKIP: {
1628 skip_if_miniperl('miniperl does not support scalario');
1629 my $buf = "";
1630 open my $fh, ">", \$buf;
1631 my $old_fh = select $fh;
1632 local $^ = "caret_A_test_TOP";
1633 local $~ = "caret_A_test";
1634 local $= = 3;
1635 local $^A = "A1\nA2\nA3\nA4\n";
1636 write;
1637 select $old_fh;
1638 close $fh;
1639 is $buf, "T\nA1\nA2\n\fT\nA3\nA4\n\fT\nL1\nL2\n\fT\nL3\nL4\n",
1640 "assign to ^A sets FmLINES";
1641}
1642
ee6d2783
NC
1643fresh_perl_like(<<'EOP', qr/^Format STDOUT redefined at/, {stderr => 1}, '#64562 - Segmentation fault with redefined formats and warnings');
1644#!./perl
1645
1646use strict;
1647use warnings; # crashes!
1648
1649format =
1650.
1651
1652write;
1653
1654format =
1655.
1656
1657write;
1658EOP
1659
37ffbfcc
NC
1660fresh_perl_is(<<'EOP', ">ARRAY<\ncrunch_eth\n", {stderr => 1}, '#79532 - formline coerces its arguments');
1661use strict;
1662use warnings;
1663my $zamm = ['crunch_eth'];
1664formline $zamm;
1665printf ">%s<\n", ref $zamm;
1666print "$zamm->[0]\n";
1667EOP
1668
86191aed
TC
1669# [perl #129125] - detected by -fsanitize=address or valgrind
1670# the compiled format would be freed when the format string was modified
1671# by the chop operator
1672fresh_perl_is(<<'EOP', "^", { stderr => 1 }, '#129125 - chop on format');
1673my $x = '^@';
1674formline$x=>$x;
1675print $^A;
1676EOP
1677
1678fresh_perl_is(<<'EOP', '<^< xx AA><xx ^<><>', { stderr => 1 }, '#129125 - chop on format, later values');
1679my $x = '^< xx ^<';
1680my $y = 'AA';
1681formline $x => $x, $y;
1682print "<$^A><$x><$y>";
1683EOP
1684
1685
8e4ecf23
JL
1686# [perl #73690]
1687
1688select +(select(RT73690), do {
1689 open(RT73690, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1690 format RT73690 =
1691@<< @<<
169211, 22
1693.
1694
1695 my @ret;
591097e0 1696
8e4ecf23
JL
1697 @ret = write;
1698 is(scalar(@ret), 1);
1699 ok($ret[0]);
1700 @ret = scalar(write);
1701 is(scalar(@ret), 1);
1702 ok($ret[0]);
1703 @ret = write(RT73690);
1704 is(scalar(@ret), 1);
1705 ok($ret[0]);
1706 @ret = scalar(write(RT73690));
1707 is(scalar(@ret), 1);
1708 ok($ret[0]);
1709
591097e0
JL
1710 @ret = ('a', write, 'z');
1711 is(scalar(@ret), 3);
1712 is($ret[0], 'a');
1713 ok($ret[1]);
1714 is($ret[2], 'z');
1715 @ret = ('b', scalar(write), 'y');
1716 is(scalar(@ret), 3);
1717 is($ret[0], 'b');
1718 ok($ret[1]);
1719 is($ret[2], 'y');
1720 @ret = ('c', write(RT73690), 'x');
1721 is(scalar(@ret), 3);
1722 is($ret[0], 'c');
1723 ok($ret[1]);
1724 is($ret[2], 'x');
1725 @ret = ('d', scalar(write(RT73690)), 'w');
1726 is(scalar(@ret), 3);
1727 is($ret[0], 'd');
1728 ok($ret[1]);
1729 is($ret[2], 'w');
1730
1731 @ret = do { write; 'foo' };
1732 is(scalar(@ret), 1);
1733 is($ret[0], 'foo');
1734 @ret = do { scalar(write); 'bar' };
1735 is(scalar(@ret), 1);
1736 is($ret[0], 'bar');
1737 @ret = do { write(RT73690); 'baz' };
1738 is(scalar(@ret), 1);
1739 is($ret[0], 'baz');
1740 @ret = do { scalar(write(RT73690)); 'quux' };
1741 is(scalar(@ret), 1);
1742 is($ret[0], 'quux');
1743
1744 @ret = ('a', do { write; 'foo' }, 'z');
1745 is(scalar(@ret), 3);
1746 is($ret[0], 'a');
1747 is($ret[1], 'foo');
1748 is($ret[2], 'z');
1749 @ret = ('b', do { scalar(write); 'bar' }, 'y');
1750 is(scalar(@ret), 3);
1751 is($ret[0], 'b');
1752 is($ret[1], 'bar');
1753 is($ret[2], 'y');
1754 @ret = ('c', do { write(RT73690); 'baz' }, 'x');
1755 is(scalar(@ret), 3);
1756 is($ret[0], 'c');
1757 is($ret[1], 'baz');
1758 is($ret[2], 'x');
1759 @ret = ('d', do { scalar(write(RT73690)); 'quux' }, 'w');
1760 is(scalar(@ret), 3);
1761 is($ret[0], 'd');
1762 is($ret[1], 'quux');
1763 is($ret[2], 'w');
1764
8e4ecf23
JL
1765 close RT73690 or die "Could not close: $!";
1766})[0];
1767
1768select +(select(RT73690_2), do {
1769 open(RT73690_2, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1770 format RT73690_2 =
1771@<< @<<
1772return
1773.
1774
1775 my @ret;
591097e0 1776
8e4ecf23
JL
1777 @ret = write;
1778 is(scalar(@ret), 1);
1779 ok(!$ret[0]);
1780 @ret = scalar(write);
1781 is(scalar(@ret), 1);
1782 ok(!$ret[0]);
1783 @ret = write(RT73690_2);
1784 is(scalar(@ret), 1);
1785 ok(!$ret[0]);
1786 @ret = scalar(write(RT73690_2));
1787 is(scalar(@ret), 1);
1788 ok(!$ret[0]);
1789
591097e0
JL
1790 @ret = ('a', write, 'z');
1791 is(scalar(@ret), 3);
1792 is($ret[0], 'a');
1793 ok(!$ret[1]);
1794 is($ret[2], 'z');
1795 @ret = ('b', scalar(write), 'y');
1796 is(scalar(@ret), 3);
1797 is($ret[0], 'b');
1798 ok(!$ret[1]);
1799 is($ret[2], 'y');
1800 @ret = ('c', write(RT73690_2), 'x');
1801 is(scalar(@ret), 3);
1802 is($ret[0], 'c');
1803 ok(!$ret[1]);
1804 is($ret[2], 'x');
1805 @ret = ('d', scalar(write(RT73690_2)), 'w');
1806 is(scalar(@ret), 3);
1807 is($ret[0], 'd');
1808 ok(!$ret[1]);
1809 is($ret[2], 'w');
1810
1811 @ret = do { write; 'foo' };
1812 is(scalar(@ret), 1);
1813 is($ret[0], 'foo');
1814 @ret = do { scalar(write); 'bar' };
1815 is(scalar(@ret), 1);
1816 is($ret[0], 'bar');
1817 @ret = do { write(RT73690_2); 'baz' };
1818 is(scalar(@ret), 1);
1819 is($ret[0], 'baz');
1820 @ret = do { scalar(write(RT73690_2)); 'quux' };
1821 is(scalar(@ret), 1);
1822 is($ret[0], 'quux');
1823
1824 @ret = ('a', do { write; 'foo' }, 'z');
1825 is(scalar(@ret), 3);
1826 is($ret[0], 'a');
1827 is($ret[1], 'foo');
1828 is($ret[2], 'z');
1829 @ret = ('b', do { scalar(write); 'bar' }, 'y');
1830 is(scalar(@ret), 3);
1831 is($ret[0], 'b');
1832 is($ret[1], 'bar');
1833 is($ret[2], 'y');
1834 @ret = ('c', do { write(RT73690_2); 'baz' }, 'x');
1835 is(scalar(@ret), 3);
1836 is($ret[0], 'c');
1837 is($ret[1], 'baz');
1838 is($ret[2], 'x');
1839 @ret = ('d', do { scalar(write(RT73690_2)); 'quux' }, 'w');
1840 is(scalar(@ret), 3);
1841 is($ret[0], 'd');
1842 is($ret[1], 'quux');
1843 is($ret[2], 'w');
1844
8e4ecf23
JL
1845 close RT73690_2 or die "Could not close: $!";
1846})[0];
1847
ee23553f
FC
1848open(UNDEF, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1849select +(select(UNDEF), $~ = "UNDEFFORMAT")[0];
1850format UNDEFFORMAT =
1851@
1852undef *UNDEFFORMAT
1853.
1854write UNDEF;
1855pass "active format cannot be freed";
c782dc1d
FC
1856
1857select +(select(UNDEF), $~ = "UNDEFFORMAT2")[0];
1858format UNDEFFORMAT2 =
1859@
1860close UNDEF or die "Could not close: $!"; undef *UNDEF
1861.
1862write UNDEF;
1863pass "freeing current handle in format";
1864undef $^A;
ee23553f 1865
7c70caa5
FC
1866ok !eval q|
1867format foo {
1868@<<<
1869$a
1870}
1871;1
1872|, 'format foo { ... } is not allowed';
1873
1874ok !eval q|
1875format =
1876@<<<
1877}
1878;1
1879|, 'format = ... } is not allowed';
1880
64a40898
FC
1881open(NEST, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1882format NEST =
1883@<<<
1884{
1885 my $birds = "birds";
1886 local *NEST = *BIRDS{FORMAT};
1887 write NEST;
1888 format BIRDS =
1889@<<<<<
1890$birds;
1891.
1892 "nest"
1893}
1894.
1895write NEST;
1896close NEST or die "Could not close: $!";
1897is cat('Op_write.tmp'), "birds\nnest\n", 'nested formats';
1898
2c658e55
FC
1899# A compilation error should not create a format
1900eval q|
1901format ERROR =
1902@
1903@_ =~ s///
1904.
1905|;
1906eval { write ERROR };
1907like $@, qr'Undefined format',
1908 'formats with compilation errors are not created';
1909
6c7ae946
FC
1910# This syntax error used to cause a crash, double free, or a least
1911# a bad read.
1912# See the long-winded explanation at:
1913# https://rt.perl.org/rt3/Ticket/Display.html?id=43425#txn-1144500
1914eval q|
1915format =
1916@
1917use;format
1918strict
1919.
1920|;
1921pass('no crash with invalid use/format inside format');
1922
ee23553f 1923
705fe0e5
FC
1924# Low-precedence operators on argument line
1925format AND =
1926@
19270 and die
1928.
1929$- = $=;
1930ok eval { local $~ = "AND"; print "# "; write; 1 },
1931 "low-prec ops on arg line" or diag $@;
1932
1933# Anonymous hashes
1934open(HASH, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1935format HASH =
1936@<<<
1937${{qw[ Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6 ]}}{"Wed"}
1938.
1939write HASH;
1940close HASH or die "Could not close: $!";
1941is cat('Op_write.tmp'), "3\n", 'anonymous hashes';
1942
f60e6763
FC
1943open(HASH2, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1944format HASH2 =
1945@<<<
1946+{foo=>"bar"}
1947.
1948write HASH2;
1949close HASH2 or die "Could not close: $!";
1950is cat('Op_write.tmp'), "HASH\n", '+{...} is interpreted as anon hash';
1951
1952# Anonymous hashes
1953open(BLOCK, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1954format BLOCK =
1955@<<< @<<<
1956{foo=>"bar"} # this is a block, not a hash!
1957.
1958write BLOCK;
1959close BLOCK or die "Could not close: $!";
1960is cat('Op_write.tmp'), "foo bar\n", 'initial { is always BLOCK';
1961
705fe0e5
FC
1962# pragmata inside argument line
1963open(STRICT, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1964format STRICT =
1965@<<<
1966no strict; $foo
1967.
1968$::foo = 'oof::$';
1969write STRICT;
1970close STRICT or die "Could not close: $!";
1971is cat('Op_write.tmp'), "oof:\n", 'pragmata on format line';
1972
7c93c29b
FC
1973SKIP: {
1974 skip "no weak refs" unless eval { require Scalar::Util };
1975 sub Potshriggley {
1976format Potshriggley =
1977.
1978 }
1979 Scalar::Util::weaken(my $x = *Potshriggley{FORMAT});
1980 undef *Potshriggley;
1981 is $x, undef, 'formats in subs do not leak';
7c93c29b
FC
1982}
1983
fcaef4dc
TC
1984fresh_perl_is(<<'EOP', <<'EXPECT',
1985use warnings 'syntax' ;
1986format STDOUT =
1987^*|^*
1988my $x = q/dd/, $x
1989.
1990write;
1991EOP
1992dd|
1993EXPECT
1994 { stderr => 1 }, '#123245 panic in sv_chop');
1995
1996fresh_perl_is(<<'EOP', <<'EXPECT',
1997use warnings 'syntax' ;
1998format STDOUT =
1999^*|^*
2000my $x = q/dd/
2001.
2002write;
2003EOP
2004Not enough format arguments at - line 4.
2005dd|
2006EXPECT
2007 { stderr => 1 }, '#123245 different panic in sv_chop');
705fe0e5 2008
62db6ea5
TC
2009fresh_perl_is(<<'EOP', <<'EXPECT',
2010format STDOUT =
2011# x at the end to make the spaces visible
2012@... x
2013q/a/
2014.
2015write;
2016EOP
2017a x
2018EXPECT
2019 { stderr => 1 }, '#123538 crash in FF_MORE');
2020
a4031a72
Z
2021{
2022 $^A = "";
2023 my $a = *globcopy;
2024 my $r = eval { formline "^<<", $a };
2025 is $@, "";
2026 ok $r, "^ format with glob copy";
2027 is $^A, "*ma", "^ format with glob copy";
2028 is $a, "in::globcopy", "^ format with glob copy";
2029}
2030
2031{
2032 $^A = "";
2033 my $r = eval { formline "^<<", *realglob };
2034 like $@, qr/\AModification of a read-only value attempted /;
2035 is $r, undef, "^ format with real glob";
2036 is $^A, "*ma", "^ format with real glob";
2037 is ref(\*realglob), "GLOB";
2038}
2039
2040$^A = "";
59a08c76 2041
dd314e1c
TC
2042# [perl #130722] assertion failure
2043fresh_perl_is('for(1..2){formline*0}', '', { stderr => 1 } , "#130722 - assertion failure");
2044
2027357e
NC
2045#############################
2046## Section 4
2047## Add new tests *above* here
2048#############################
2049
f5b75c1c
NC
2050# scary format testing from H.Merijn Brand
2051
2052# Just a complete test for format, including top-, left- and bottom marging
2053# and format detection through glob entries
2054
7b903762 2055if ($^O eq 'VMS' || $^O eq 'MSWin32' || $^O eq 'dos' ||
f5b75c1c
NC
2056 ($^O eq 'os2' and not eval '$OS2::can_fork')) {
2057 $test = curr_test();
2058 SKIP: {
2059 skip "'|-' and '-|' not supported", $tests - $test + 1;
2060 }
2061 exit(0);
2062}
2063
2064
0bd0581c
DM
2065$^ = "STDOUT_TOP";
2066$= = 7; # Page length
2067$- = 0; # Lines left
9ccde9ea
JH
2068my $ps = $^L; $^L = ""; # Catch the page separator
2069my $tm = 1; # Top margin (empty lines before first output)
2070my $bm = 2; # Bottom marging (empty lines between last text and footer)
2071my $lm = 4; # Left margin (indent in spaces)
2072
68ba3c2c
DM
2073# -----------------------------------------------------------------------
2074#
2075# execute the rest of the script in a child process. The parent reads the
2076# output from the child and compares it with <DATA>.
2077
2078my @data = <DATA>;
2079
2080select ((select (STDOUT), $| = 1)[0]); # flush STDOUT
2081
2082my $opened = open FROM_CHILD, "-|";
2083unless (defined $opened) {
6108250c
NC
2084 fail "open gave $!";
2085 exit 0;
68ba3c2c
DM
2086}
2087
2088if ($opened) {
2089 # in parent here
2090
6108250c 2091 pass 'open';
9ccde9ea 2092 my $s = " " x $lm;
68ba3c2c
DM
2093 while (<FROM_CHILD>) {
2094 unless (@data) {
6108250c 2095 fail 'too much output';
68ba3c2c
DM
2096 exit;
2097 }
9ccde9ea 2098 s/^/$s/;
68ba3c2c 2099 my $exp = shift @data;
6108250c 2100 is $_, $exp;
9ccde9ea 2101 }
68ba3c2c 2102 close FROM_CHILD;
6108250c 2103 is "@data", "", "correct length of output";
68ba3c2c
DM
2104 exit;
2105}
2106
2107# in child here
6108250c 2108$::NO_ENDING = 1;
68ba3c2c
DM
2109
2110 select ((select (STDOUT), $| = 1)[0]);
9ccde9ea
JH
2111$tm = "\n" x $tm;
2112$= -= $bm + 1; # count one for the trailing "----"
2113my $lastmin = 0;
2114
2115my @E;
2116
2117sub wryte
2118{
2119 $lastmin = $-;
2120 write;
2121 } # wryte;
2122
2123sub footer
2124{
2125 $% == 1 and return "";
2126
2127 $lastmin < $= and print "\n" x $lastmin;
2128 print "\n" x $bm, "----\n", $ps;
2129 $lastmin = $-;
2130 "";
2131 } # footer
2132
2133# Yes, this is sick ;-)
2134format TOP =
2135@* ~
2136@{[footer]}
2137@* ~
2138$tm
2139.
2140
9ccde9ea
JH
2141format ENTRY =
2142@ @<<<<~~
2143@{(shift @E)||["",""]}
2144.
2145
2146format EOR =
2147- -----
2148.
2149
2150sub has_format ($)
2151{
2152 my $fmt = shift;
2153 exists $::{$fmt} or return 0;
2154 $^O eq "MSWin32" or return defined *{$::{$fmt}}{FORMAT};
2155 open my $null, "> /dev/null" or die;
2156 my $fh = select $null;
2157 local $~ = $fmt;
2158 eval "write";
2159 select $fh;
2160 $@?0:1;
2161 } # has_format
2162
d57f9278 2163$^ = has_format ("TOP") ? "TOP" : "EMPTY";
9ccde9ea
JH
2164has_format ("ENTRY") or die "No format defined for ENTRY";
2165foreach my $e ( [ map { [ $_, "Test$_" ] } 1 .. 7 ],
2166 [ map { [ $_, "${_}tseT" ] } 1 .. 5 ]) {
2167 @E = @$e;
2168 local $~ = "ENTRY";
2169 wryte;
2170 has_format ("EOR") or next;
2171 local $~ = "EOR";
2172 wryte;
2173 }
2174if (has_format ("EOF")) {
2175 local $~ = "EOF";
2176 wryte;
2177 }
2178
2179close STDOUT;
2180
ea42cebc 2181# That was test 48.
9ccde9ea
JH
2182
2183__END__
2184
2185 1 Test1
2186 2 Test2
2187 3 Test3
2188
2189
2190 ----
2191 \f
2192 4 Test4
2193 5 Test5
2194 6 Test6
2195
2196
2197 ----
2198 \f
2199 7 Test7
2200 - -----
2201
2202
2203
2204 ----
2205 \f
2206 1 1tseT
2207 2 2tseT
2208 3 3tseT
2209
2210
2211 ----
2212 \f
2213 4 4tseT
2214 5 5tseT
2215 - -----