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