xref: /openbsd-src/gnu/usr.bin/perl/t/run/switches.t (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1#!./perl -w
2
3# Tests for the command-line switches:
4# -0, -c, -l, -s, -m, -M, -V, -v, -h, -i, -E and all unknown
5# Some switches have their own tests, see MANIFEST.
6
7BEGIN {
8    chdir 't' if -d 't';
9    @INC = '../lib';
10    require Config; import Config;
11}
12
13BEGIN { require "./test.pl"; }
14
15plan(tests => 115);
16
17use Config;
18use Errno qw(EACCES EISDIR);
19BEGIN { eval 'use POSIX qw(setlocale LC_ALL)' }
20
21# due to a bug in VMS's piping which makes it impossible for runperl()
22# to emulate echo -n (ie. stdin always winds up with a newline), these
23# tests almost totally fail.
24$TODO = "runperl() unable to emulate echo -n due to pipe bug" if $^O eq 'VMS';
25
26my $r;
27my @tmpfiles = ();
28END { unlink_all @tmpfiles }
29
30# Tests for -0
31
32$r = runperl(
33    switches	=> [ '-0', ],
34    stdin	=> 'foo\0bar\0baz\0',
35    prog	=> 'print qq(<$_>) while <>',
36);
37is( $r, "<foo\0><bar\0><baz\0>", "-0" );
38
39$r = runperl(
40    switches	=> [ '-l', '-0', '-p' ],
41    stdin	=> 'foo\0bar\0baz\0',
42    prog	=> '1',
43);
44is( $r, "foo\nbar\nbaz\n", "-0 after a -l" );
45
46$r = runperl(
47    switches	=> [ '-0', '-l', '-p' ],
48    stdin	=> 'foo\0bar\0baz\0',
49    prog	=> '1',
50);
51is( $r, "foo\0bar\0baz\0", "-0 before a -l" );
52
53$r = runperl(
54    switches	=> [ sprintf("-0%o", ord 'x') ],
55    stdin	=> 'fooxbarxbazx',
56    prog	=> 'print qq(<$_>) while <>',
57);
58is( $r, "<foox><barx><bazx>", "-0 with octal number" );
59
60$r = runperl(
61    switches	=> [ '-00', '-p' ],
62    stdin	=> 'abc\ndef\n\nghi\njkl\nmno\n\npq\n',
63    prog	=> 's/\n/-/g;$_.=q(/)',
64);
65is( $r, 'abc-def--/ghi-jkl-mno--/pq-/', '-00 (paragraph mode)' );
66
67$r = runperl(
68    switches	=> [ '-0777', '-p' ],
69    stdin	=> 'abc\ndef\n\nghi\njkl\nmno\n\npq\n',
70    prog	=> 's/\n/-/g;$_.=q(/)',
71);
72is( $r, 'abc-def--ghi-jkl-mno--pq-/', '-0777 (slurp mode)' );
73
74$r = runperl(
75    switches	=> [ '-066' ],
76    prog	=> 'BEGIN { print qq{($/)} } print qq{[$/]}',
77);
78is( $r, "(\066)[\066]", '$/ set at compile-time' );
79
80# Tests for -c
81
82my $filename = tempfile();
83SKIP: {
84    local $TODO = '';   # this one works on VMS
85
86    open my $f, ">$filename" or skip( "Can't write temp file $filename: $!" );
87    print $f <<'SWTEST';
88BEGIN { print "block 1\n"; }
89CHECK { print "block 2\n"; }
90INIT  { print "block 3\n"; }
91	print "block 4\n";
92END   { print "block 5\n"; }
93SWTEST
94    close $f or die "Could not close: $!";
95    $r = runperl(
96	switches	=> [ '-c' ],
97	progfile	=> $filename,
98	stderr		=> 1,
99    );
100    # Because of the stderr redirection, we can't tell reliably the order
101    # in which the output is given
102    ok(
103	$r =~ /$filename syntax OK/
104	&& $r =~ /\bblock 1\b/
105	&& $r =~ /\bblock 2\b/
106	&& $r !~ /\bblock 3\b/
107	&& $r !~ /\bblock 4\b/
108	&& $r !~ /\bblock 5\b/,
109	'-c'
110    );
111}
112
113SKIP: {
114    skip "no POSIX on miniperl", 1, unless $INC{"POSIX.pm"};
115    skip 'No locale testing without d_setlocale', 1 if(!$Config{d_setlocale});
116
117    my $tempdir = tempfile;
118    mkdir $tempdir, 0700 or die "Can't mkdir '$tempdir': $!";
119
120    local $ENV{'LC_ALL'} = 'C'; # Keep the test simple: expect English
121    local $ENV{LANGUAGE} = 'C';
122    setlocale(LC_ALL, "C");
123
124    # Win32 won't let us open the directory, so we never get to die with
125    # EISDIR, which happens after open.
126    my $error  = do { local $! = $^O eq 'MSWin32' ? EACCES : EISDIR; "$!" };
127    like(
128        runperl( switches => [ '-c' ], args  => [ $tempdir ], stderr => 1),
129        qr/Can't open perl script.*$tempdir.*\Q$error/s,
130        "RT \#61362: Cannot syntax-check a directory"
131    );
132    rmdir $tempdir or die "Can't rmdir '$tempdir': $!";
133}
134
135# Tests for -l
136
137$r = runperl(
138    switches	=> [ sprintf("-l%o", ord 'x') ],
139    prog	=> 'print for qw/foo bar/'
140);
141is( $r, 'fooxbarx', '-l with octal number' );
142
143# Tests for -s
144
145$r = runperl(
146    switches	=> [ '-s' ],
147    prog	=> 'for (qw/abc def ghi/) {print defined $$_ ? $$_ : q(-)}',
148    args	=> [ '--', '-abc=2', '-def', ],
149);
150is( $r, '21-', '-s switch parsing' );
151
152$filename = tempfile();
153SKIP: {
154    open my $f, ">$filename" or skip( "Can't write temp file $filename: $!" );
155    print $f <<'SWTEST';
156#!perl -s
157BEGIN { print $x,$y; exit }
158SWTEST
159    close $f or die "Could not close: $!";
160    $r = runperl(
161	progfile    => $filename,
162	args	    => [ '-x=foo -y' ],
163    );
164    is( $r, 'foo1', '-s on the shebang line' );
165}
166
167# Bug ID 20011106.084
168$filename = tempfile();
169SKIP: {
170    open my $f, ">$filename" or skip( "Can't write temp file $filename: $!" );
171    print $f <<'SWTEST';
172#!perl -sn
173BEGIN { print $x; exit }
174SWTEST
175    close $f or die "Could not close: $!";
176    $r = runperl(
177	progfile    => $filename,
178	args	    => [ '-x=foo' ],
179    );
180    is( $r, 'foo', '-sn on the shebang line' );
181}
182
183# Tests for -m and -M
184
185my $package = tempfile();
186$filename = "$package.pm";
187SKIP: {
188    open my $f, ">$filename" or skip( "Can't write temp file $filename: $!",4 );
189    print $f <<"SWTESTPM";
190package $package;
191sub import { print map "<\$_>", \@_ }
1921;
193SWTESTPM
194    close $f or die "Could not close: $!";
195    $r = runperl(
196	switches    => [ "-M$package" ],
197	prog	    => '1',
198    );
199    is( $r, "<$package>", '-M' );
200    $r = runperl(
201	switches    => [ "-M$package=foo" ],
202	prog	    => '1',
203    );
204    is( $r, "<$package><foo>", '-M with import parameter' );
205    $r = runperl(
206	switches    => [ "-m$package" ],
207	prog	    => '1',
208    );
209
210    {
211        local $TODO = '';  # this one works on VMS
212        is( $r, '', '-m' );
213    }
214    $r = runperl(
215	switches    => [ "-m$package=foo,bar" ],
216	prog	    => '1',
217    );
218    is( $r, "<$package><foo><bar>", '-m with import parameters' );
219    push @tmpfiles, $filename;
220
221  {
222    local $TODO = '';  # these work on VMS
223
224    is( runperl( switches => [ '-MTie::Hash' ], stderr => 1, prog => 1 ),
225	  '', "-MFoo::Bar allowed" );
226
227    like( runperl( switches => [ "-M:$package" ], stderr => 1,
228		   prog => 'die q{oops}' ),
229	  qr/Invalid module name [\w:]+ with -M option\b/,
230          "-M:Foo not allowed" );
231
232    like( runperl( switches => [ '-mA:B:C' ], stderr => 1,
233		   prog => 'die q{oops}' ),
234	  qr/Invalid module name [\w:]+ with -m option\b/,
235          "-mFoo:Bar not allowed" );
236
237    like( runperl( switches => [ '-m-A:B:C' ], stderr => 1,
238		   prog => 'die q{oops}' ),
239	  qr/Invalid module name [\w:]+ with -m option\b/,
240          "-m-Foo:Bar not allowed" );
241
242    like( runperl( switches => [ '-m-' ], stderr => 1,
243		   prog => 'die q{oops}' ),
244	  qr/Module name required with -m option\b/,
245  	  "-m- not allowed" );
246
247    like( runperl( switches => [ '-M-=' ], stderr => 1,
248		   prog => 'die q{oops}' ),
249	  qr/Module name required with -M option\b/,
250  	  "-M- not allowed" );
251  }  # disable TODO on VMS
252}
253is runperl(stderr => 1, prog => '#!perl -m'),
254   qq 'Too late for "-m" option at -e line 1.\n', '#!perl -m';
255is runperl(stderr => 1, prog => '#!perl -M'),
256   qq 'Too late for "-M" option at -e line 1.\n', '#!perl -M';
257
258# Tests for -V
259
260{
261    local $TODO = '';   # these ones should work on VMS
262
263    # basic perl -V should generate significant output.
264    # we don't test actual format too much since it could change
265    like( runperl( switches => ['-V'] ), qr/(\n.*){20}/,
266          '-V generates 20+ lines' );
267
268    like( runperl( switches => ['-V'] ),
269	  qr/\ASummary of my perl5 .*configuration:/,
270          '-V looks okay' );
271
272    # lookup a known config var
273    chomp( $r=runperl( switches => ['-V:osname'] ) );
274    is( $r, "osname='$^O';", 'perl -V:osname');
275
276    # lookup a nonexistent var
277    chomp( $r=runperl( switches => ['-V:this_var_makes_switches_test_fail'] ) );
278    is( $r, "this_var_makes_switches_test_fail='UNKNOWN';",
279        'perl -V:unknown var');
280
281    # regexp lookup
282    # platforms that don't like this quoting can either skip this test
283    # or fix test.pl _quote_args
284    $r = runperl( switches => ['"-V:i\D+size"'] );
285    # should be unlike( $r, qr/^$|not found|UNKNOWN/ );
286    like( $r, qr/^(?!.*(not found|UNKNOWN))./, 'perl -V:re got a result' );
287
288    # make sure each line we got matches the re
289    ok( !( grep !/^i\D+size=/, split /^/, $r ), '-V:re correct' );
290}
291
292# Tests for -v
293
294{
295    local $TODO = '';   # these ones should work on VMS
296    # there are definitely known build configs where this test will fail
297    # DG/UX comes to mind. Maybe we should remove these special cases?
298    my $v = sprintf "%vd", $^V;
299    my $ver = $Config{PERL_VERSION};
300    my $rel = $Config{PERL_SUBVERSION};
301    like( runperl( switches => ['-v'] ),
302	  qr/This is perl 5, version \Q$ver\E, subversion \Q$rel\E \(v\Q$v\E(?:[-*\w]+| \([^)]+\))?\) built for \Q$Config{archname}\E.+Copyright.+Larry Wall.+Artistic License.+GNU General Public License/s,
303          '-v looks okay' );
304
305}
306
307# Tests for -h
308
309{
310    local $TODO = '';   # these ones should work on VMS
311
312    like( runperl( switches => ['-h'] ),
313	  qr/Usage: .+(?i:perl(?:$Config{_exe})?).+switches.+programfile.+arguments/,
314          '-h looks okay' );
315
316}
317
318# Tests for switches which do not exist
319
320foreach my $switch (split //, "ABbGgHJjKkLNOoPQqRrYyZz123456789_")
321{
322    local $TODO = '';   # these ones should work on VMS
323
324    like( runperl( switches => ["-$switch"], stderr => 1,
325		   prog => 'die q{oops}' ),
326	  qr/\QUnrecognized switch: -$switch  (-h will show valid options)./,
327          "-$switch correctly unknown" );
328
329    # [perl #104288]
330    like( runperl( stderr => 1, prog => "#!perl -$switch" ),
331	  qr/^Unrecognized switch: -$switch  \(-h will show valid (?x:
332	     )options\) at -e line 1\./,
333          "-$switch unrecognised on #! line" );
334}
335
336# Tests for unshebangable switches
337for (qw( e f x E S V )) {
338    $r = runperl(
339	stderr   => 1,
340	prog     => "#!perl -$_",
341    );
342    is $r, "Can't emulate -$_ on #! line at -e line 1.\n","-$_ on #! line";
343}
344
345# Tests for -i
346
347{
348    local $TODO = '';   # these ones should work on VMS
349
350    sub do_i_unlink { unlink_all("file", "file.bak") }
351
352    open(FILE, ">file") or die "$0: Failed to create 'file': $!";
353    print FILE <<__EOF__;
354foo yada dada
355bada foo bing
356king kong foo
357__EOF__
358    close FILE;
359
360    END { do_i_unlink() }
361
362    runperl( switches => ['-pi.bak'], prog => 's/foo/bar/', args => ['file'] );
363
364    open(FILE, "file") or die "$0: Failed to open 'file': $!";
365    chomp(my @file = <FILE>);
366    close FILE;
367
368    open(BAK, "file.bak") or die "$0: Failed to open 'file': $!";
369    chomp(my @bak = <BAK>);
370    close BAK;
371
372    is(join(":", @file),
373       "bar yada dada:bada bar bing:king kong bar",
374       "-i new file");
375    is(join(":", @bak),
376       "foo yada dada:bada foo bing:king kong foo",
377       "-i backup file");
378
379    my $out1 = runperl(
380        switches => ['-i.bak -p'],
381        prog     => 'exit',
382        stderr   => 1,
383        stdin    => "1\n",
384    );
385    is(
386        $out1,
387        "-i used with no filenames on the command line, reading from STDIN.\n",
388        "warning when no files given"
389    );
390    my $out2 = runperl(
391        switches => ['-i.bak -p'],
392        prog     => 'exit',
393        stderr   => 1,
394        stdin    => "1\n",
395        args     => ['file'],
396    );
397    is($out2, "", "no warning when files given");
398}
399
400# Tests for -E
401
402$TODO = '';  # the -E tests work on VMS
403
404$r = runperl(
405    switches	=> [ '-E', '"say q(Hello, world!)"']
406);
407is( $r, "Hello, world!\n", "-E say" );
408
409
410$r = runperl(
411    switches	=> [ '-E', '"no warnings q{experimental::smartmatch}; undef ~~ undef and say q(Hello, world!)"']
412);
413is( $r, "Hello, world!\n", "-E ~~" );
414
415$r = runperl(
416    switches	=> [ '-E', '"no warnings q{experimental::smartmatch}; given(undef) {when(undef) { say q(Hello, world!)"}}']
417);
418is( $r, "Hello, world!\n", "-E given" );
419
420$r = runperl(
421    switches    => [ '-nE', q("} END { say q/affe/") ],
422    stdin       => 'zomtek',
423);
424is( $r, "affe\n", '-E works outside of the block created by -n' );
425
426$r = runperl(
427    switches	=> [ '-E', q("*{'bar'} = sub{}; print 'Hello, world!',qq|\n|;")]
428);
429is( $r, "Hello, world!\n", "-E does not enable strictures" );
430
431# RT #30660
432
433$filename = tempfile();
434SKIP: {
435    open my $f, ">$filename" or skip( "Can't write temp file $filename: $!" );
436    print $f <<'SWTEST';
437#!perl -w    -iok
438print "$^I\n";
439SWTEST
440    close $f or die "Could not close: $!";
441    $r = runperl(
442	progfile    => $filename,
443    );
444    like( $r, qr/ok/, 'Spaces on the #! line (#30660)' );
445}
446