This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
buffer overrun with format and 'use bytes'
[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
e452bf1c 101my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 6 + 2 + 3 + 96 + 11 + 13;
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
1580
76912796
DM
1581 # make sure it can cope with formats > 64k
1582
1583 $format = 'x' x 65537;
1584 $^A = '';
1585 formline $format;
1586 # don't use 'is' here, as the diag output will be too long!
1587 ok $^A eq $format, ">64K";
f5ada144
DM
1588}
1589
3808a683 1590
d3d1232e
NC
1591SKIP: {
1592 skip_if_miniperl('miniperl does not support scalario');
60fe2d11 1593 my $buf = "";
fda0c190
MB
1594 open my $fh, ">", \$buf;
1595 my $old_fh = select $fh;
1596 local $~ = "CmT";
1597 write;
1598 select $old_fh;
1599 close $fh;
1600 is $buf, "ok $test\n", "write to duplicated format";
1601}
1602
64eff8b7
DM
1603format caret_A_test_TOP =
1604T
1605.
1606
1607format caret_A_test =
1608L1
1609L2
1610L3
1611L4
1612.
1613
1614SKIP: {
1615 skip_if_miniperl('miniperl does not support scalario');
1616 my $buf = "";
1617 open my $fh, ">", \$buf;
1618 my $old_fh = select $fh;
1619 local $^ = "caret_A_test_TOP";
1620 local $~ = "caret_A_test";
1621 local $= = 3;
1622 local $^A = "A1\nA2\nA3\nA4\n";
1623 write;
1624 select $old_fh;
1625 close $fh;
1626 is $buf, "T\nA1\nA2\n\fT\nA3\nA4\n\fT\nL1\nL2\n\fT\nL3\nL4\n",
1627 "assign to ^A sets FmLINES";
1628}
1629
ee6d2783
NC
1630fresh_perl_like(<<'EOP', qr/^Format STDOUT redefined at/, {stderr => 1}, '#64562 - Segmentation fault with redefined formats and warnings');
1631#!./perl
1632
1633use strict;
1634use warnings; # crashes!
1635
1636format =
1637.
1638
1639write;
1640
1641format =
1642.
1643
1644write;
1645EOP
1646
37ffbfcc
NC
1647fresh_perl_is(<<'EOP', ">ARRAY<\ncrunch_eth\n", {stderr => 1}, '#79532 - formline coerces its arguments');
1648use strict;
1649use warnings;
1650my $zamm = ['crunch_eth'];
1651formline $zamm;
1652printf ">%s<\n", ref $zamm;
1653print "$zamm->[0]\n";
1654EOP
1655
86191aed
TC
1656# [perl #129125] - detected by -fsanitize=address or valgrind
1657# the compiled format would be freed when the format string was modified
1658# by the chop operator
1659fresh_perl_is(<<'EOP', "^", { stderr => 1 }, '#129125 - chop on format');
1660my $x = '^@';
1661formline$x=>$x;
1662print $^A;
1663EOP
1664
1665fresh_perl_is(<<'EOP', '<^< xx AA><xx ^<><>', { stderr => 1 }, '#129125 - chop on format, later values');
1666my $x = '^< xx ^<';
1667my $y = 'AA';
1668formline $x => $x, $y;
1669print "<$^A><$x><$y>";
1670EOP
1671
1672
8e4ecf23
JL
1673# [perl #73690]
1674
1675select +(select(RT73690), do {
1676 open(RT73690, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1677 format RT73690 =
1678@<< @<<
167911, 22
1680.
1681
1682 my @ret;
591097e0 1683
8e4ecf23
JL
1684 @ret = write;
1685 is(scalar(@ret), 1);
1686 ok($ret[0]);
1687 @ret = scalar(write);
1688 is(scalar(@ret), 1);
1689 ok($ret[0]);
1690 @ret = write(RT73690);
1691 is(scalar(@ret), 1);
1692 ok($ret[0]);
1693 @ret = scalar(write(RT73690));
1694 is(scalar(@ret), 1);
1695 ok($ret[0]);
1696
591097e0
JL
1697 @ret = ('a', write, 'z');
1698 is(scalar(@ret), 3);
1699 is($ret[0], 'a');
1700 ok($ret[1]);
1701 is($ret[2], 'z');
1702 @ret = ('b', scalar(write), 'y');
1703 is(scalar(@ret), 3);
1704 is($ret[0], 'b');
1705 ok($ret[1]);
1706 is($ret[2], 'y');
1707 @ret = ('c', write(RT73690), 'x');
1708 is(scalar(@ret), 3);
1709 is($ret[0], 'c');
1710 ok($ret[1]);
1711 is($ret[2], 'x');
1712 @ret = ('d', scalar(write(RT73690)), 'w');
1713 is(scalar(@ret), 3);
1714 is($ret[0], 'd');
1715 ok($ret[1]);
1716 is($ret[2], 'w');
1717
1718 @ret = do { write; 'foo' };
1719 is(scalar(@ret), 1);
1720 is($ret[0], 'foo');
1721 @ret = do { scalar(write); 'bar' };
1722 is(scalar(@ret), 1);
1723 is($ret[0], 'bar');
1724 @ret = do { write(RT73690); 'baz' };
1725 is(scalar(@ret), 1);
1726 is($ret[0], 'baz');
1727 @ret = do { scalar(write(RT73690)); 'quux' };
1728 is(scalar(@ret), 1);
1729 is($ret[0], 'quux');
1730
1731 @ret = ('a', do { write; 'foo' }, 'z');
1732 is(scalar(@ret), 3);
1733 is($ret[0], 'a');
1734 is($ret[1], 'foo');
1735 is($ret[2], 'z');
1736 @ret = ('b', do { scalar(write); 'bar' }, 'y');
1737 is(scalar(@ret), 3);
1738 is($ret[0], 'b');
1739 is($ret[1], 'bar');
1740 is($ret[2], 'y');
1741 @ret = ('c', do { write(RT73690); 'baz' }, 'x');
1742 is(scalar(@ret), 3);
1743 is($ret[0], 'c');
1744 is($ret[1], 'baz');
1745 is($ret[2], 'x');
1746 @ret = ('d', do { scalar(write(RT73690)); 'quux' }, 'w');
1747 is(scalar(@ret), 3);
1748 is($ret[0], 'd');
1749 is($ret[1], 'quux');
1750 is($ret[2], 'w');
1751
8e4ecf23
JL
1752 close RT73690 or die "Could not close: $!";
1753})[0];
1754
1755select +(select(RT73690_2), do {
1756 open(RT73690_2, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1757 format RT73690_2 =
1758@<< @<<
1759return
1760.
1761
1762 my @ret;
591097e0 1763
8e4ecf23
JL
1764 @ret = write;
1765 is(scalar(@ret), 1);
1766 ok(!$ret[0]);
1767 @ret = scalar(write);
1768 is(scalar(@ret), 1);
1769 ok(!$ret[0]);
1770 @ret = write(RT73690_2);
1771 is(scalar(@ret), 1);
1772 ok(!$ret[0]);
1773 @ret = scalar(write(RT73690_2));
1774 is(scalar(@ret), 1);
1775 ok(!$ret[0]);
1776
591097e0
JL
1777 @ret = ('a', write, 'z');
1778 is(scalar(@ret), 3);
1779 is($ret[0], 'a');
1780 ok(!$ret[1]);
1781 is($ret[2], 'z');
1782 @ret = ('b', scalar(write), 'y');
1783 is(scalar(@ret), 3);
1784 is($ret[0], 'b');
1785 ok(!$ret[1]);
1786 is($ret[2], 'y');
1787 @ret = ('c', write(RT73690_2), 'x');
1788 is(scalar(@ret), 3);
1789 is($ret[0], 'c');
1790 ok(!$ret[1]);
1791 is($ret[2], 'x');
1792 @ret = ('d', scalar(write(RT73690_2)), 'w');
1793 is(scalar(@ret), 3);
1794 is($ret[0], 'd');
1795 ok(!$ret[1]);
1796 is($ret[2], 'w');
1797
1798 @ret = do { write; 'foo' };
1799 is(scalar(@ret), 1);
1800 is($ret[0], 'foo');
1801 @ret = do { scalar(write); 'bar' };
1802 is(scalar(@ret), 1);
1803 is($ret[0], 'bar');
1804 @ret = do { write(RT73690_2); 'baz' };
1805 is(scalar(@ret), 1);
1806 is($ret[0], 'baz');
1807 @ret = do { scalar(write(RT73690_2)); 'quux' };
1808 is(scalar(@ret), 1);
1809 is($ret[0], 'quux');
1810
1811 @ret = ('a', do { write; 'foo' }, 'z');
1812 is(scalar(@ret), 3);
1813 is($ret[0], 'a');
1814 is($ret[1], 'foo');
1815 is($ret[2], 'z');
1816 @ret = ('b', do { scalar(write); 'bar' }, 'y');
1817 is(scalar(@ret), 3);
1818 is($ret[0], 'b');
1819 is($ret[1], 'bar');
1820 is($ret[2], 'y');
1821 @ret = ('c', do { write(RT73690_2); 'baz' }, 'x');
1822 is(scalar(@ret), 3);
1823 is($ret[0], 'c');
1824 is($ret[1], 'baz');
1825 is($ret[2], 'x');
1826 @ret = ('d', do { scalar(write(RT73690_2)); 'quux' }, 'w');
1827 is(scalar(@ret), 3);
1828 is($ret[0], 'd');
1829 is($ret[1], 'quux');
1830 is($ret[2], 'w');
1831
8e4ecf23
JL
1832 close RT73690_2 or die "Could not close: $!";
1833})[0];
1834
ee23553f
FC
1835open(UNDEF, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1836select +(select(UNDEF), $~ = "UNDEFFORMAT")[0];
1837format UNDEFFORMAT =
1838@
1839undef *UNDEFFORMAT
1840.
1841write UNDEF;
1842pass "active format cannot be freed";
c782dc1d
FC
1843
1844select +(select(UNDEF), $~ = "UNDEFFORMAT2")[0];
1845format UNDEFFORMAT2 =
1846@
1847close UNDEF or die "Could not close: $!"; undef *UNDEF
1848.
1849write UNDEF;
1850pass "freeing current handle in format";
1851undef $^A;
ee23553f 1852
7c70caa5
FC
1853ok !eval q|
1854format foo {
1855@<<<
1856$a
1857}
1858;1
1859|, 'format foo { ... } is not allowed';
1860
1861ok !eval q|
1862format =
1863@<<<
1864}
1865;1
1866|, 'format = ... } is not allowed';
1867
64a40898
FC
1868open(NEST, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1869format NEST =
1870@<<<
1871{
1872 my $birds = "birds";
1873 local *NEST = *BIRDS{FORMAT};
1874 write NEST;
1875 format BIRDS =
1876@<<<<<
1877$birds;
1878.
1879 "nest"
1880}
1881.
1882write NEST;
1883close NEST or die "Could not close: $!";
1884is cat('Op_write.tmp'), "birds\nnest\n", 'nested formats';
1885
2c658e55
FC
1886# A compilation error should not create a format
1887eval q|
1888format ERROR =
1889@
1890@_ =~ s///
1891.
1892|;
1893eval { write ERROR };
1894like $@, qr'Undefined format',
1895 'formats with compilation errors are not created';
1896
6c7ae946
FC
1897# This syntax error used to cause a crash, double free, or a least
1898# a bad read.
1899# See the long-winded explanation at:
1900# https://rt.perl.org/rt3/Ticket/Display.html?id=43425#txn-1144500
1901eval q|
1902format =
1903@
1904use;format
1905strict
1906.
1907|;
1908pass('no crash with invalid use/format inside format');
1909
ee23553f 1910
705fe0e5
FC
1911# Low-precedence operators on argument line
1912format AND =
1913@
19140 and die
1915.
1916$- = $=;
1917ok eval { local $~ = "AND"; print "# "; write; 1 },
1918 "low-prec ops on arg line" or diag $@;
1919
1920# Anonymous hashes
1921open(HASH, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1922format HASH =
1923@<<<
1924${{qw[ Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6 ]}}{"Wed"}
1925.
1926write HASH;
1927close HASH or die "Could not close: $!";
1928is cat('Op_write.tmp'), "3\n", 'anonymous hashes';
1929
f60e6763
FC
1930open(HASH2, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1931format HASH2 =
1932@<<<
1933+{foo=>"bar"}
1934.
1935write HASH2;
1936close HASH2 or die "Could not close: $!";
1937is cat('Op_write.tmp'), "HASH\n", '+{...} is interpreted as anon hash';
1938
1939# Anonymous hashes
1940open(BLOCK, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1941format BLOCK =
1942@<<< @<<<
1943{foo=>"bar"} # this is a block, not a hash!
1944.
1945write BLOCK;
1946close BLOCK or die "Could not close: $!";
1947is cat('Op_write.tmp'), "foo bar\n", 'initial { is always BLOCK';
1948
705fe0e5
FC
1949# pragmata inside argument line
1950open(STRICT, '>Op_write.tmp') || die "Can't create Op_write.tmp";
1951format STRICT =
1952@<<<
1953no strict; $foo
1954.
1955$::foo = 'oof::$';
1956write STRICT;
1957close STRICT or die "Could not close: $!";
1958is cat('Op_write.tmp'), "oof:\n", 'pragmata on format line';
1959
7c93c29b
FC
1960SKIP: {
1961 skip "no weak refs" unless eval { require Scalar::Util };
1962 sub Potshriggley {
1963format Potshriggley =
1964.
1965 }
1966 Scalar::Util::weaken(my $x = *Potshriggley{FORMAT});
1967 undef *Potshriggley;
1968 is $x, undef, 'formats in subs do not leak';
7c93c29b
FC
1969}
1970
fcaef4dc
TC
1971fresh_perl_is(<<'EOP', <<'EXPECT',
1972use warnings 'syntax' ;
1973format STDOUT =
1974^*|^*
1975my $x = q/dd/, $x
1976.
1977write;
1978EOP
1979dd|
1980EXPECT
1981 { stderr => 1 }, '#123245 panic in sv_chop');
1982
1983fresh_perl_is(<<'EOP', <<'EXPECT',
1984use warnings 'syntax' ;
1985format STDOUT =
1986^*|^*
1987my $x = q/dd/
1988.
1989write;
1990EOP
1991Not enough format arguments at - line 4.
1992dd|
1993EXPECT
1994 { stderr => 1 }, '#123245 different panic in sv_chop');
705fe0e5 1995
62db6ea5
TC
1996fresh_perl_is(<<'EOP', <<'EXPECT',
1997format STDOUT =
1998# x at the end to make the spaces visible
1999@... x
2000q/a/
2001.
2002write;
2003EOP
2004a x
2005EXPECT
2006 { stderr => 1 }, '#123538 crash in FF_MORE');
2007
59a08c76
DM
2008# this used to assert fail
2009fresh_perl_like(<<'EOP',
2010format STDOUT =
2011@
20120"$x"
2013.
2014print "got here\n";
2015EOP
2016 qr/Use of comma-less variable list is deprecated.*got here/s,
2017 { stderr => 1 },
2018 '#128255 Assert fail in S_sublex_done');
2019
a4031a72
Z
2020{
2021 $^A = "";
2022 my $a = *globcopy;
2023 my $r = eval { formline "^<<", $a };
2024 is $@, "";
2025 ok $r, "^ format with glob copy";
2026 is $^A, "*ma", "^ format with glob copy";
2027 is $a, "in::globcopy", "^ format with glob copy";
2028}
2029
2030{
2031 $^A = "";
2032 my $r = eval { formline "^<<", *realglob };
2033 like $@, qr/\AModification of a read-only value attempted /;
2034 is $r, undef, "^ format with real glob";
2035 is $^A, "*ma", "^ format with real glob";
2036 is ref(\*realglob), "GLOB";
2037}
2038
2039$^A = "";
59a08c76 2040
2027357e
NC
2041#############################
2042## Section 4
2043## Add new tests *above* here
2044#############################
2045
f5b75c1c
NC
2046# scary format testing from H.Merijn Brand
2047
2048# Just a complete test for format, including top-, left- and bottom marging
2049# and format detection through glob entries
2050
7b903762 2051if ($^O eq 'VMS' || $^O eq 'MSWin32' || $^O eq 'dos' ||
f5b75c1c
NC
2052 ($^O eq 'os2' and not eval '$OS2::can_fork')) {
2053 $test = curr_test();
2054 SKIP: {
2055 skip "'|-' and '-|' not supported", $tests - $test + 1;
2056 }
2057 exit(0);
2058}
2059
2060
0bd0581c
DM
2061$^ = "STDOUT_TOP";
2062$= = 7; # Page length
2063$- = 0; # Lines left
9ccde9ea
JH
2064my $ps = $^L; $^L = ""; # Catch the page separator
2065my $tm = 1; # Top margin (empty lines before first output)
2066my $bm = 2; # Bottom marging (empty lines between last text and footer)
2067my $lm = 4; # Left margin (indent in spaces)
2068
68ba3c2c
DM
2069# -----------------------------------------------------------------------
2070#
2071# execute the rest of the script in a child process. The parent reads the
2072# output from the child and compares it with <DATA>.
2073
2074my @data = <DATA>;
2075
2076select ((select (STDOUT), $| = 1)[0]); # flush STDOUT
2077
2078my $opened = open FROM_CHILD, "-|";
2079unless (defined $opened) {
6108250c
NC
2080 fail "open gave $!";
2081 exit 0;
68ba3c2c
DM
2082}
2083
2084if ($opened) {
2085 # in parent here
2086
6108250c 2087 pass 'open';
9ccde9ea 2088 my $s = " " x $lm;
68ba3c2c
DM
2089 while (<FROM_CHILD>) {
2090 unless (@data) {
6108250c 2091 fail 'too much output';
68ba3c2c
DM
2092 exit;
2093 }
9ccde9ea 2094 s/^/$s/;
68ba3c2c 2095 my $exp = shift @data;
6108250c 2096 is $_, $exp;
9ccde9ea 2097 }
68ba3c2c 2098 close FROM_CHILD;
6108250c 2099 is "@data", "", "correct length of output";
68ba3c2c
DM
2100 exit;
2101}
2102
2103# in child here
6108250c 2104$::NO_ENDING = 1;
68ba3c2c
DM
2105
2106 select ((select (STDOUT), $| = 1)[0]);
9ccde9ea
JH
2107$tm = "\n" x $tm;
2108$= -= $bm + 1; # count one for the trailing "----"
2109my $lastmin = 0;
2110
2111my @E;
2112
2113sub wryte
2114{
2115 $lastmin = $-;
2116 write;
2117 } # wryte;
2118
2119sub footer
2120{
2121 $% == 1 and return "";
2122
2123 $lastmin < $= and print "\n" x $lastmin;
2124 print "\n" x $bm, "----\n", $ps;
2125 $lastmin = $-;
2126 "";
2127 } # footer
2128
2129# Yes, this is sick ;-)
2130format TOP =
2131@* ~
2132@{[footer]}
2133@* ~
2134$tm
2135.
2136
9ccde9ea
JH
2137format ENTRY =
2138@ @<<<<~~
2139@{(shift @E)||["",""]}
2140.
2141
2142format EOR =
2143- -----
2144.
2145
2146sub has_format ($)
2147{
2148 my $fmt = shift;
2149 exists $::{$fmt} or return 0;
2150 $^O eq "MSWin32" or return defined *{$::{$fmt}}{FORMAT};
2151 open my $null, "> /dev/null" or die;
2152 my $fh = select $null;
2153 local $~ = $fmt;
2154 eval "write";
2155 select $fh;
2156 $@?0:1;
2157 } # has_format
2158
d57f9278 2159$^ = has_format ("TOP") ? "TOP" : "EMPTY";
9ccde9ea
JH
2160has_format ("ENTRY") or die "No format defined for ENTRY";
2161foreach my $e ( [ map { [ $_, "Test$_" ] } 1 .. 7 ],
2162 [ map { [ $_, "${_}tseT" ] } 1 .. 5 ]) {
2163 @E = @$e;
2164 local $~ = "ENTRY";
2165 wryte;
2166 has_format ("EOR") or next;
2167 local $~ = "EOR";
2168 wryte;
2169 }
2170if (has_format ("EOF")) {
2171 local $~ = "EOF";
2172 wryte;
2173 }
2174
2175close STDOUT;
2176
ea42cebc 2177# That was test 48.
9ccde9ea
JH
2178
2179__END__
2180
2181 1 Test1
2182 2 Test2
2183 3 Test3
2184
2185
2186 ----
2187 \f
2188 4 Test4
2189 5 Test5
2190 6 Test6
2191
2192
2193 ----
2194 \f
2195 7 Test7
2196 - -----
2197
2198
2199
2200 ----
2201 \f
2202 1 1tseT
2203 2 2tseT
2204 3 3tseT
2205
2206
2207 ----
2208 \f
2209 4 4tseT
2210 5 5tseT
2211 - -----