This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make coreamp.t pass with PERL_UNICODE set
[perl5.git] / t / x2p / s2p.t
CommitLineData
939256b9
JH
1#!./perl
2
3=head1 NAME
4
5s2p.t - test suite for s2p/psed
6
7=head1 NOTES
8
9The general idea is to
10
11 (a) run psed with a sed script and input data to obtain some output
12 (b) run s2p with a sed script creating a Perl program and then run the
13 Perl program with the input data, again producing output
14
15Both final outputs should be identical to the expected output.
16
17A $testcase{<name>} contains entries (after the comment ### <name> ###):
18
19 - script: the sed script
20 - input: the key of the input data, stored in $input{<input>}
21 - expect: the expected output
22 - datfil: an additional file [ <path>, <data> ] (if required)
23
24Temporary files are created in the working directory (embedding $$
25in the name), and removed after the test.
26
27Except for bin2dec (which indeed converts binary to decimal) none of the
28sed scripts is doing something useful.
29
30Author: Wolfgang Laun.
31
32=cut
33
34BEGIN {
35 chdir 't' if -d 't';
36 @INC = ( '../lib' );
37}
38
939256b9
JH
39use File::Copy;
40use File::Spec;
41require './test.pl';
42
43# BRE extensions
44$ENV{PSEDEXTBRE} = '<>wW';
45
46our %input = (
47 bins => <<'[TheEnd]',
480
49111
501000
5110001
52[TheEnd]
53
54 text => <<'[TheEnd]',
55line 1
56line 2
57line 3
58line 4
59line 5
60line 6
61line 7
62line 8
63[TheEnd]
64
65 adr1 => <<'[TheEnd]',
66#no autoprint
67# This script should be run on itself
68/^#__DATA__$/,${
69 /^#A$/p
70 s/^# *[0-9]* *//
71 /^#\*$/p
72 /^#\.$/p
73 /^#\(..\)\(..\)\2\1*$/p
74 /^#[abc]\{1,\}[def]\{1,\}$/p
75}
76#__DATA__
77#A
78#*
79#.
80#abxyxy
81#abxyxyab
82#abxyxyabab
83#ad
84#abcdef
85[TheEnd]
86);
87
88
89our %testcase = (
90
91### bin2dec ###
92'bin2dec' => {
93 script => <<'[TheEnd]',
94# binary -> decimal
95s/^[ ]*\([01]\{1,\}\)[ ]*/\1/
96t go
97i\
98is not a binary number
99d
100
101# expand binary to Xs
102: go
103s/^0*//
104s/^1/X/
105: expand
106s/^\(X\{1,\}\)0/\1\1/
107s/^\(X\{1,\}\)1/\1\1X/
108t expand
109
110# count Xs in decimal
111: count
112s/^X/1/
113s/0X/1/
114s/1X/2/
115s/2X/3/
116s/3X/4/
117s/4X/5/
118s/5X/6/
119s/6X/7/
120s/7X/8/
121s/8X/9/
122s/9X/X0/
123t count
124s/^$/0/
125[TheEnd]
126 input => 'bins',
127 expect => <<'[TheEnd]',
1280
1297
1308
13117
132[TheEnd]
133},
134
135
136### = ###
137'=' => {
138 script => <<'[TheEnd]',
1391=
140$=
141[TheEnd]
142 input => 'text',
143 expect => <<'[TheEnd]',
1441
145line 1
146line 2
147line 3
148line 4
149line 5
150line 6
151line 7
1528
153line 8
154[TheEnd]
155},
156
157### D ###
158'D' => {
159 script => <<'[TheEnd]',
160#no autoprint
161/1/{
162N
163N
164N
165D
166}
167p
168/2/D
169=
170p
171[TheEnd]
172 input => 'text',
173 expect => <<'[TheEnd]',
174line 2
175line 3
176line 4
177line 3
178line 4
1794
180line 3
181line 4
182line 5
1835
184line 5
185line 6
1866
187line 6
188line 7
1897
190line 7
191line 8
1928
193line 8
194[TheEnd]
195},
196
197### H ###
198'H' => {
199 script => <<'[TheEnd]',
200#no autoprint
2011,$H
202$g
203$=
204$p
205[TheEnd]
206 input => 'text',
207 expect => <<'[TheEnd]',
2088
209
210line 1
211line 2
212line 3
213line 4
214line 5
215line 6
216line 7
217line 8
218[TheEnd]
219},
220
221### N ###
222'N' => {
223 script => <<'[TheEnd]',
2243a\
225added line
2264a\
227added line
2285a\
229added line
2303,5N
231=
232d
233[TheEnd]
234 input => 'text',
235 expect => <<'[TheEnd]',
2361
2372
238added line
2394
240added line
2416
2427
2438
244[TheEnd]
245},
246
247### P ###
248'P' => {
249 script => <<'[TheEnd]',
2501N
2512N
2523N
2534=
2544P
2554,$d
256[TheEnd]
257 input => 'text',
258 expect => <<'[TheEnd]',
2594
260line 1
261[TheEnd]
262},
263
264### a ###
265'a' => {
266 script => <<'[TheEnd]',
2671a\
268added line 1.1\
269added line 1.2
270
2713a\
272added line 3.1
2733a\
274added line 3.2
275
276[TheEnd]
277 input => 'text',
278 expect => <<'[TheEnd]',
279line 1
280added line 1.1
281added line 1.2
282line 2
283line 3
284added line 3.1
285added line 3.2
286line 4
287line 5
288line 6
289line 7
290line 8
291[TheEnd]
292},
293
294### b ###
295'b' => {
296 script => <<'[TheEnd]',
297#no autoprint
2982 b eos
2994 b eos
300p
301: eos
302[TheEnd]
303 input => 'text',
304 expect => <<'[TheEnd]',
305line 1
306line 3
307line 5
308line 6
309line 7
310line 8
311[TheEnd]
312},
313
314### block ###
315'block' => {
316 script => "#no autoprint\n1,3{\n=\np\n}",
317 input => 'text',
318 expect => <<'[TheEnd]',
3191
320line 1
3212
322line 2
3233
324line 3
325[TheEnd]
326},
327
328### c ###
329'c' => {
330 script => <<'[TheEnd]',
3312=
332
3332,4c\
334change 2,4 line 1\
335change 2,4 line 2
336
3372=
338
3393,5c\
340change 3,5 line 1\
341change 3,5 line 2
342
3433=
344
345[TheEnd]
346 input => 'text',
347 expect => <<'[TheEnd]',
348line 1
3492
350change 2,4 line 1
351change 2,4 line 2
352line 5
353line 6
354line 7
355line 8
356[TheEnd]
357},
358
359### c1 ###
360'c1' => {
361 script => <<'[TheEnd]',
3621c\
363replaces line 1
364
3652,3c\
366replaces lines 2-3
367
368/5/,/6/c\
369replaces lines 3-4
370
3718,10c\
372replaces lines 6-10
373[TheEnd]
374 input => 'text',
375 expect => <<'[TheEnd]',
376replaces line 1
377replaces lines 2-3
378line 4
379replaces lines 3-4
380line 7
381[TheEnd]
382},
383
384### c2 ###
385'c2' => {
386 script => <<'[TheEnd]',
3873!c\
388replace all except line 3
389
390[TheEnd]
391 input => 'text',
392 expect => <<'[TheEnd]',
393replace all except line 3
394replace all except line 3
395line 3
396replace all except line 3
397replace all except line 3
398replace all except line 3
399replace all except line 3
400replace all except line 3
401[TheEnd]
402},
403
404### c3 ###
405'c3' => {
406 script => <<'[TheEnd]',
4071,4!c\
408replace all except 1-4
409
410/5/,/8/!c\
411replace all except 5-8
412[TheEnd]
413 input => 'text',
414 expect => <<'[TheEnd]',
415replace all except 5-8
416replace all except 5-8
417replace all except 5-8
418replace all except 5-8
419replace all except 1-4
420replace all except 1-4
421replace all except 1-4
422replace all except 1-4
423[TheEnd]
424},
425
426### d ###
427'd' => {
428 script => <<'[TheEnd]',
429# d delete pattern space, start next cycle
4302,4 d
4315 d
432[TheEnd]
433 input => 'text',
434 expect => <<'[TheEnd]',
435line 1
436line 6
437line 7
438line 8
439[TheEnd]
440},
441
442### gh ###
443'gh' => {
444 script => <<'[TheEnd]',
4451h
4462g
4473h
4484g
4495q
450[TheEnd]
451 input => 'text',
452 expect => <<'[TheEnd]',
453line 1
454line 1
455line 3
456line 3
457line 5
458[TheEnd]
459},
460
461### i ###
462'i' => {
463 script => <<'[TheEnd]',
4641i\
465inserted line 1.1\
466inserted line 1.2
467
4683i\
469inserted line 3.1
4703i\
471inserted line 3.2
472[TheEnd]
473 input => 'text',
474 expect => <<'[TheEnd]',
475inserted line 1.1
476inserted line 1.2
477line 1
478line 2
479inserted line 3.1
480inserted line 3.2
481line 3
482line 4
483line 5
484line 6
485line 7
486line 8
487[TheEnd]
488},
489
490### n ###
491'n' => {
492 script => <<'[TheEnd]',
4933a\
494added line
4954a\
496added line
4975a\
498added line
4993,5n
500=
501d
502[TheEnd]
503 input => 'text',
504 expect => <<'[TheEnd]',
5051
5062
507line 3
508added line
5094
510line 5
511added line
5126
5137
5148
515[TheEnd]
516},
517
518### o ###
519'o' => {
520 script => <<'[TheEnd]',
521/abc/,/def/ s//XXX/
522// i\
523cheers
524[TheEnd]
525 input => 'text',
526 expect => <<'[TheEnd]',
527line 1
528line 2
529line 3
530line 4
531line 5
532line 6
533line 7
534line 8
535[TheEnd]
536},
537
538### q ###
539'q' => {
540 script => <<'[TheEnd]',
5412a\
542append to line 2
5433a\
544append to line 3 - should not appear in output
5453q
546[TheEnd]
547 input => 'text',
548 expect => <<'[TheEnd]',
549line 1
550line 2
551append to line 2
552line 3
553[TheEnd]
554},
555
556### r ###
557'r' => {
558 datfil => [ 'r.txt', "r.txt line 1\nr.txt line 2\nr.txt line 3\n" ],
559 script => <<'[TheEnd]',
5602r%r.txt%
5614r %r.txt%
562[TheEnd]
563 input => 'text',
564 expect => <<'[TheEnd]',
565line 1
566line 2
567r.txt line 1
568r.txt line 2
569r.txt line 3
570line 3
571line 4
572r.txt line 1
573r.txt line 2
574r.txt line 3
575line 5
576line 6
577line 7
578line 8
579[TheEnd]
580},
581
582### s ###
583's' => {
584 script => <<'[TheEnd]',
585# enclose any `(a)'.. `(c)' in `-'
586s/([a-z])/-\1-/g
587
588s/\([abc]\)/-\1-/g
589[TheEnd]
590 input => 'text',
591 expect => <<'[TheEnd]',
592line 1
593line 2
594line 3
595line 4
596line 5
597line 6
598line 7
599line 8
600[TheEnd]
601},
602
603### s1 ###
604's1' => {
605 script => <<'[TheEnd]',
606s/\w/@1/
607s/\y/@2/
608
609s/\n/@3/
610
611# this is literal { }
612s/a{3}/@4/
613
614# proper repetition
615s/a\{3\}/a rep 3/
616[TheEnd]
617 input => 'text',
618 expect => <<'[TheEnd]',
619@1ine 1
620@1ine 2
621@1ine 3
622@1ine 4
623@1ine 5
624@1ine 6
625@1ine 7
626@1ine 8
627[TheEnd]
628},
629
630### t ###
631't' => {
632 script => join( "\n",
633 '#no autoprint', 's/./X/p', 's/foo/bar/p', 't bye', '=', 'p', ':bye' ),
634 input => 'text',
635 expect => <<'[TheEnd]',
636Xine 1
637Xine 2
638Xine 3
639Xine 4
640Xine 5
641Xine 6
642Xine 7
643Xine 8
644[TheEnd]
645},
646
647### w ###
648'w' => {
649 datfil => [ 'w.txt', '' ],
650 script => <<'[TheEnd]',
651w %w.txt%
652[TheEnd]
653 input => 'text',
654 expect => <<'[TheEnd]',
655line 1
656line 2
657line 3
658line 4
659line 5
660line 6
661line 7
662line 8
663[TheEnd]
664},
665
666### x ###
667'x' => {
668 script => <<'[TheEnd]',
6691h
6701d
6712x
6722,$G
673[TheEnd]
674 input => 'text',
675 expect => <<'[TheEnd]',
676line 1
677line 2
678line 3
679line 2
680line 4
681line 2
682line 5
683line 2
684line 6
685line 2
686line 7
687line 2
688line 8
689line 2
690[TheEnd]
691},
692
693### y ###
694'y' => {
695 script => <<'[TheEnd]',
696y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
697y/|/\
698/
699[TheEnd]
700 input => 'text',
701 expect => <<'[TheEnd]',
702LINE 1
703LINE 2
704LINE 3
705LINE 4
706LINE 5
707LINE 6
708LINE 7
709LINE 8
710[TheEnd]
711},
712
713### cnt ###
714'cnt' => {
715 script => <<'[TheEnd]',
716#no autoprint
717
718# delete line, append NL to hold space
719s/.*//
720H
721$!b
722
723# last line only: get hold
724g
725s/./X/g
726t count
727: count
728s/^X/1/
729s/0X/1/
730s/1X/2/
731s/2X/3/
732s/3X/4/
733s/4X/5/
734s/5X/6/
735s/6X/7/
736s/7X/8/
737s/8X/9/
738s/9X/X0/
739t count
740p
741[TheEnd]
742 input => 'text',
743 expect => <<'[TheEnd]',
7448
745[TheEnd]
746},
747
748### adr1 ###
749'adr1' => {
750 script => <<'[TheEnd]',
751#no autoprint
752# This script should be run on itself
753/^#__DATA__$/,${
754 /^#A$/p
755 s/^# *[0-9]* *//
756 /^#\*$/p
757 /^#\.$/p
758 /^#\(..\)\(..\)\2\1*$/p
759 /^#[abc]\{1,\}[def]\{1,\}$/p
760}
761#__DATA__
762#A
763#*
764#.
765#abxyxy
766#abxyxyab
767#abxyxyabab
768#ad
769#abcdef
770[TheEnd]
771 input => 'adr1',
772 expect => <<'[TheEnd]',
773#A
774[TheEnd]
775},
776
777);
778
779my @aux = ();
780my $ntc = 2 * keys %testcase;
781plan( $ntc );
782
783# temporary file names
784my $script = "s2pt$$.sed";
785my $stdin = "s2pt$$.in";
786my $plsed = "s2pt$$.pl";
787
788# various command lines for
789my $s2p = File::Spec->catfile( File::Spec->updir(), 'x2p', 's2p' );
790my $psed = File::Spec->catfile( File::Spec->curdir(), 'psed' );
9ae2b9a0 791if ($^O eq 'VMS') {
93f09d7b 792 # default in the .com extension if it's not already there
16ed4686
JM
793 $s2p = VMS::Filespec::vmsify($s2p);
794 $psed = VMS::Filespec::vmsify($psed);
3e2a970d
JM
795 # Converting file specs from Unix format to VMS with the extended
796 # character set active can result in a trailing '.' added for null
797 # extensions. This must be removed if the intent is to default the
798 # extension.
799 $s2p =~ s/\.$//;
800 $psed =~ s/\.$//;
9ae2b9a0
CB
801 $s2p = VMS::Filespec::rmsexpand($s2p, '.com');
802 $psed = VMS::Filespec::rmsexpand($psed, '.com');
803}
939256b9
JH
804my $sedcmd = [ $psed, '-f', $script, $stdin ];
805my $s2pcmd = [ $s2p, '-f', $script ];
806my $plcmd = [ $plsed, $stdin ];
807
808# psed: we create a local copy as linking may not work on some systems.
809copy( $s2p, $psed );
810push( @aux, $psed );
811
812# process all testcases
813#
814my $indat = '';
815for my $tc ( sort keys %testcase ){
816 my( $psedres, $s2pres );
817
818 # 1st test: run psed
819 # prepare the script
820 open( SED, ">$script" ) || goto FAIL_BOTH;
821 my $script = $testcase{$tc}{script};
822
823 # additional files for r, w: patch script, inserting temporary names
824 if( exists( $testcase{$tc}{datfil} ) ){
825 my( $datnam, $datdat ) = @{$testcase{$tc}{datfil}};
826 my $datfil = "s2pt$$" . $datnam;
827 push( @aux, $datfil );
828 open( DAT, ">$datfil" ) || goto FAIL_BOTH;
829 print DAT $datdat;
830 close( DAT );
831 $script =~ s/\%$datnam\%/$datfil/eg;
832 }
833 print SED $script;
834 close( SED ) || goto FAIL_BOTH;
835
836 # prepare input
837 #
838 if( $indat ne $testcase{$tc}{input} ){
839 $indat = $testcase{$tc}{input};
840 open( IN, ">$stdin" ) || goto FAIL_BOTH;
841 print IN $input{$indat};
842 close( IN ) || goto FAIL_BOTH;
843 }
844
9ae2b9a0
CB
845 # on VMS, runperl eats blank lines to work around
846 # spurious newlines in pipes
847 $testcase{$tc}{expect} =~ s/\n\n/\n/ if $^O eq 'VMS';
848
939256b9
JH
849 # run and compare
850 #
7b903762 851 $psedres = runperl( args => $sedcmd );
939256b9
JH
852 is( $psedres, $testcase{$tc}{expect}, "psed $tc" );
853
854 # 2nd test: run s2p
855 # translate the sed script to a Perl program
e69a2255 856
7b903762 857 my $perlprog = runperl( args => $s2pcmd );
939256b9
JH
858 open( PP, ">$plsed" ) || goto FAIL_S2P;
859 print PP $perlprog;
860 close( PP ) || goto FAIL_S2P;
861
862 # execute generated Perl program, compare
7b903762 863 $s2pres = runperl( args => $plcmd );
939256b9
JH
864 is( $s2pres, $testcase{$tc}{expect}, "s2p $tc" );
865 next;
866
867FAIL_BOTH:
868 fail( "psed $tc" );
869FAIL_S2P:
870 fail( "s2p $tc" );
871}
872
873END {
874 for my $f ( $script, $stdin, $plsed, @aux ){
875 1 while unlink( $f ); # hats off to VMS...
876 }
877}