source: for-distributions/trunk/bin/windows/perl/bin/pl2bat.bat@ 14489

Last change on this file since 14489 was 14489, checked in by oranfry, 17 years ago

upgrading to perl 5.8

File size: 12.9 KB
Line 
1@rem = '--*-Perl-*--
2@echo off
3if "%OS%" == "Windows_NT" goto WinNT
4perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
5goto endofperl
6:WinNT
7perl -x -S %0 %*
8if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
9if %errorlevel% == 9009 echo You do not have Perl in your PATH.
10if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
11goto endofperl
12@rem ';
13#!perl
14#line 15
15 eval 'exec perl -x -S "$0" ${1+"$@"}'
16 if 0; # In case running under some shell
17
18require 5;
19use Getopt::Std;
20use Config;
21
22$0 =~ s|.*[/\\]||;
23
24my $usage = <<EOT;
25Usage: $0 [-h]
26 or: $0 [-w] [-u] [-a argstring] [-s stripsuffix] [files]
27 or: $0 [-w] [-u] [-n ntargs] [-o otherargs] [-s stripsuffix] [files]
28 -n ntargs arguments to invoke perl with in generated file
29 when run from Windows NT. Defaults to
30 '-x -S %0 %*'.
31 -o otherargs arguments to invoke perl with in generated file
32 other than when run from Windows NT. Defaults
33 to '-x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9'.
34 -a argstring arguments to invoke perl with in generated file
35 ignoring operating system (for compatibility
36 with previous pl2bat versions).
37 -u update files that may have already been processed
38 by (some version of) pl2bat.
39 -w include "-w" on the /^#!.*perl/ line (unless
40 a /^#!.*perl/ line was already present).
41 -s stripsuffix strip this suffix from file before appending ".bat"
42 Not case-sensitive
43 Can be a regex if it begins with `/'
44 Defaults to "/\.plx?/"
45 -h show this help
46EOT
47
48my %OPT = ();
49warn($usage), exit(0) if !getopts('whun:o:a:s:',\%OPT) or $OPT{'h'};
50# NOTE: %0 is already enclosed in doublequotes by cmd.exe, as appropriate
51$OPT{'n'} = '-x -S %0 %*' unless exists $OPT{'n'};
52$OPT{'o'} = '-x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9' unless exists $OPT{'o'};
53$OPT{'s'} = '/\\.plx?/' unless exists $OPT{'s'};
54$OPT{'s'} = ($OPT{'s'} =~ m#^/([^/]*[^/\$]|)\$?/?$# ? $1 : "\Q$OPT{'s'}\E");
55
56my $head;
57if( defined( $OPT{'a'} ) ) {
58 $head = <<EOT;
59 \@rem = '--*-Perl-*--
60 \@echo off
61 perl $OPT{'a'}
62 goto endofperl
63 \@rem ';
64EOT
65} else {
66 $head = <<EOT;
67 \@rem = '--*-Perl-*--
68 \@echo off
69 if "%OS%" == "Windows_NT" goto WinNT
70 perl $OPT{'o'}
71 goto endofperl
72 :WinNT
73 perl $OPT{'n'}
74 if NOT "%COMSPEC%" == "%SystemRoot%\\system32\\cmd.exe" goto endofperl
75 if %errorlevel% == 9009 echo You do not have Perl in your PATH.
76 if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
77 goto endofperl
78 \@rem ';
79EOT
80}
81$head =~ s/^\t//gm;
82my $headlines = 2 + ($head =~ tr/\n/\n/);
83my $tail = "\n__END__\n:endofperl\n";
84
85@ARGV = ('-') unless @ARGV;
86
87foreach ( @ARGV ) {
88 process($_);
89}
90
91sub process {
92 my( $file )= @_;
93 my $myhead = $head;
94 my $linedone = 0;
95 my $taildone = 0;
96 my $linenum = 0;
97 my $skiplines = 0;
98 my $line;
99 my $start= $Config{startperl};
100 $start= "#!perl" unless $start =~ /^#!.*perl/;
101 open( FILE, $file ) or die "$0: Can't open $file: $!";
102 @file = <FILE>;
103 foreach $line ( @file ) {
104 $linenum++;
105 if ( $line =~ /^:endofperl\b/ ) {
106 if( ! exists $OPT{'u'} ) {
107 warn "$0: $file has already been converted to a batch file!\n";
108 return;
109 }
110 $taildone++;
111 }
112 if ( not $linedone and $line =~ /^#!.*perl/ ) {
113 if( exists $OPT{'u'} ) {
114 $skiplines = $linenum - 1;
115 $line .= "#line ".(1+$headlines)."\n";
116 } else {
117 $line .= "#line ".($linenum+$headlines)."\n";
118 }
119 $linedone++;
120 }
121 if ( $line =~ /^#\s*line\b/ and $linenum == 2 + $skiplines ) {
122 $line = "";
123 }
124 }
125 close( FILE );
126 $file =~ s/$OPT{'s'}$//oi;
127 $file .= '.bat' unless $file =~ /\.bat$/i or $file =~ /^-$/;
128 open( FILE, ">$file" ) or die "Can't open $file: $!";
129 print FILE $myhead;
130 print FILE $start, ( $OPT{'w'} ? " -w" : "" ),
131 "\n#line ", ($headlines+1), "\n" unless $linedone;
132 print FILE @file[$skiplines..$#file];
133 print FILE $tail unless $taildone;
134 close( FILE );
135}
136__END__
137
138=head1 NAME
139
140pl2bat - wrap perl code into a batch file
141
142=head1 SYNOPSIS
143
144B<pl2bat> B<-h>
145
146B<pl2bat> [B<-w>] S<[B<-a> I<argstring>]> S<[B<-s> I<stripsuffix>]> [files]
147
148B<pl2bat> [B<-w>] S<[B<-n> I<ntargs>]> S<[B<-o> I<otherargs>]> S<[B<-s> I<stripsuffix>]> [files]
149
150=head1 DESCRIPTION
151
152This utility converts a perl script into a batch file that can be
153executed on DOS-like operating systems. This is intended to allow
154you to use a Perl script like regular programs and batch files where
155you just enter the name of the script [probably minus the extension]
156plus any command-line arguments and the script is found in your B<PATH>
157and run.
158
159=head2 ADVANTAGES
160
161There are several alternatives to this method of running a Perl script.
162They each have disadvantages that help you understand the motivation
163for using B<pl2bat>.
164
165=over
166
167=item 1
168
169 C:> perl x:/path/to/script.pl [args]
170
171=item 2
172
173 C:> perl -S script.pl [args]
174
175=item 3
176
177 C:> perl -S script [args]
178
179=item 4
180
181 C:> ftype Perl=perl.exe "%1" %*
182 C:> assoc .pl=Perl
183 then
184 C:> script.pl [args]
185
186=item 5
187
188 C:> ftype Perl=perl.exe "%1" %*
189 C:> assoc .pl=Perl
190 C:> set PathExt=%PathExt%;.PL
191 then
192 C:> script [args]
193
194=back
195
196B<1> and B<2> are the most basic invocation methods that should work on
197any system [DOS-like or not]. They require extra typing and require
198that the script user know that the script is written in Perl. This
199is a pain when you have lots of scripts, some written in Perl and some
200not. It can be quite difficult to keep track of which scripts need to
201be run through Perl and which do not. Even worse, scripts often get
202rewritten from simple batch files into more powerful Perl scripts in
203which case these methods would require all existing users of the scripts
204be updated.
205
206B<3> works on modern Win32 versions of Perl. It allows the user to
207omit the ".pl" or ".bat" file extension, which is a minor improvement.
208
209B<4> and B<5> work on some Win32 operating systems with some command
210shells. One major disadvantage with both is that you can't use them
211in pipelines nor with file redirection. For example, none of the
212following will work properly if you used method B<4> or B<5>:
213
214 C:> script.pl <infile
215 C:> script.pl >outfile
216 C:> echo y | script.pl
217 C:> script.pl | more
218
219This is due to a Win32 bug which Perl has no control over. This bug
220is the major motivation for B<pl2bat> [which was originally written
221for DOS] being used on Win32 systems.
222
223Note also that B<5> works on a smaller range of combinations of Win32
224systems and command shells while B<4> requires that the user know
225that the script is a Perl script [because the ".pl" extension must
226be entered]. This makes it hard to standardize on either of these
227methods.
228
229=head2 DISADVANTAGES
230
231There are several potential traps you should be aware of when you
232use B<pl2bat>.
233
234The generated batch file is initially processed as a batch file each
235time it is run. This means that, to use it from within another batch
236file you should precede it with C<call> or else the calling batch
237file will not run any commands after the script:
238
239 call script [args]
240
241Except under Windows NT, if you specify more than 9 arguments to
242the generated batch file then the 10th and subsequent arguments
243are silently ignored.
244
245Except when using F<CMD.EXE> under Windows NT, if F<perl.exe> is not
246in your B<PATH>, then trying to run the script will give you a generic
247"Command not found"-type of error message that will probably make you
248think that the script itself is not in your B<PATH>. When using
249F<CMD.EXE> under Windows NT, the generic error message is followed by
250"You do not have Perl in your PATH", to make this clearer.
251
252On most DOS-like operating systems, the only way to exit a batch file
253is to "fall off the end" of the file. B<pl2bat> implements this by
254doing C<goto :endofperl> and adding C<__END__> and C<:endofperl> as
255the last two lines of the generated batch file. This means:
256
257=over
258
259=item No line of your script should start with a colon.
260
261In particular, for this version of B<pl2bat>, C<:endofperl>,
262C<:WinNT>, and C<:script_failed_so_exit_with_non_zero_val> should not
263be used.
264
265=item Care must be taken when using C<__END__> and the C<DATA> file handle.
266
267One approach is:
268
269 . #!perl
270 . while( <DATA> ) {
271 . last if /^__END__$/;
272 . [...]
273 . }
274 . __END__
275 . lines of data
276 . to be processed
277 . __END__
278 . :endofperl
279
280The dots in the first column are only there to prevent F<cmd.exe> to interpret
281the C<:endofperl> line in this documentation. Otherwise F<pl2bat.bat> itself
282wouldn't work. See the previous item. :-)
283
284=item The batch file always "succeeds"
285
286The following commands illustrate the problem:
287
288 C:> echo exit(99); >fail.pl
289 C:> pl2bat fail.pl
290 C:> perl -e "print system('perl fail.pl')"
291 99
292 C:> perl -e "print system('fail.bat')"
293 0
294
295So F<fail.bat> always reports that it completed successfully. Actually,
296under Windows NT, we have:
297
298 C:> perl -e "print system('fail.bat')"
299 1
300
301So, for Windows NT, F<fail.bat> fails when the Perl script fails, but
302the return code is always C<1>, not the return code from the Perl script.
303
304=back
305
306=head2 FUNCTION
307
308By default, the ".pl" suffix will be stripped before adding a ".bat" suffix
309to the supplied file names. This can be controlled with the C<-s> option.
310
311The default behavior is to have the batch file compare the C<OS>
312environment variable against C<"Windows_NT">. If they match, it
313uses the C<%*> construct to refer to all the command line arguments
314that were given to it, so you'll need to make sure that works on your
315variant of the command shell. It is known to work in the F<CMD.EXE> shell
316under Windows NT. 4DOS/NT users will want to put a C<ParameterChar = *>
317line in their initialization file, or execute C<setdos /p*> in
318the shell startup file.
319
320On Windows95 and other platforms a nine-argument limit is imposed
321on command-line arguments given to the generated batch file, since
322they may not support C<%*> in batch files.
323
324These can be overridden using the C<-n> and C<-o> options or the
325deprecated C<-a> option.
326
327=head1 OPTIONS
328
329=over 8
330
331=item B<-n> I<ntargs>
332
333Arguments to invoke perl with in generated batch file when run from
334Windows NT (or Windows 98, probably). Defaults to S<'-x -S %0 %*'>.
335
336=item B<-o> I<otherargs>
337
338Arguments to invoke perl with in generated batch file except when
339run from Windows NT (ie. when run from DOS, Windows 3.1, or Windows 95).
340Defaults to S<'-x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9'>.
341
342=item B<-a> I<argstring>
343
344Arguments to invoke perl with in generated batch file. Specifying
345B<-a> prevents the batch file from checking the C<OS> environment
346variable to determine which operating system it is being run from.
347
348=item B<-s> I<stripsuffix>
349
350Strip a suffix string from file name before appending a ".bat"
351suffix. The suffix is not case-sensitive. It can be a regex if
352it begins with `/' (the trailing '/' is optional and a trailing
353C<$> is always assumed). Defaults to C</.plx?/>.
354
355=item B<-w>
356
357If no line matching C</^#!.*perl/> is found in the script, then such
358a line is inserted just after the new preamble. The exact line
359depends on C<$Config{startperl}> [see L<Config>]. With the B<-w>
360option, C<" -w"> is added after the value of C<$Config{startperl}>.
361If a line matching C</^#!.*perl/> already exists in the script,
362then it is not changed and the B<-w> option is ignored.
363
364=item B<-u>
365
366If the script appears to have already been processed by B<pl2bat>,
367then the script is skipped and not processed unless B<-u> was
368specified. If B<-u> is specified, the existing preamble is replaced.
369
370=item B<-h>
371
372Show command line usage.
373
374=back
375
376=head1 EXAMPLES
377
378 C:\> pl2bat foo.pl bar.PM
379 [..creates foo.bat, bar.PM.bat..]
380
381 C:\> pl2bat -s "/\.pl|\.pm/" foo.pl bar.PM
382 [..creates foo.bat, bar.bat..]
383
384 C:\> pl2bat < somefile > another.bat
385
386 C:\> pl2bat > another.bat
387 print scalar reverse "rekcah lrep rehtona tsuj\n";
388 ^Z
389 [..another.bat is now a certified japh application..]
390
391 C:\> ren *.bat *.pl
392 C:\> pl2bat -u *.pl
393 [..updates the wrapping of some previously wrapped scripts..]
394
395 C:\> pl2bat -u -s .bat *.bat
396 [..same as previous example except more dangerous..]
397
398=head1 BUGS
399
400C<$0> will contain the full name, including the ".bat" suffix
401when the generated batch file runs. If you don't like this,
402see runperl.bat for an alternative way to invoke perl scripts.
403
404Default behavior is to invoke Perl with the B<-S> flag, so Perl will
405search the B<PATH> to find the script. This may have undesirable
406effects.
407
408On really old versions of Win32 Perl, you can't run the script
409via
410
411 C:> script.bat [args]
412
413and must use
414
415 C:> script [args]
416
417A loop should be used to build up the argument list when not on
418Windows NT so more than 9 arguments can be processed.
419
420See also L</Disadvantages>.
421
422=head1 SEE ALSO
423
424perl, perlwin32, runperl.bat
425
426=cut
427
428
429__END__
430:endofperl
Note: See TracBrowser for help on using the repository browser.