xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/lib/Pod/Usage.pm (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#############################################################################
2*0Sstevel@tonic-gate# Pod/Usage.pm -- print usage messages for the running script.
3*0Sstevel@tonic-gate#
4*0Sstevel@tonic-gate# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved.
5*0Sstevel@tonic-gate# This file is part of "PodParser". PodParser is free software;
6*0Sstevel@tonic-gate# you can redistribute it and/or modify it under the same terms
7*0Sstevel@tonic-gate# as Perl itself.
8*0Sstevel@tonic-gate#############################################################################
9*0Sstevel@tonic-gate
10*0Sstevel@tonic-gatepackage Pod::Usage;
11*0Sstevel@tonic-gate
12*0Sstevel@tonic-gateuse vars qw($VERSION);
13*0Sstevel@tonic-gate$VERSION = 1.16;  ## Current version of this package
14*0Sstevel@tonic-gaterequire  5.005;    ## requires this Perl version or later
15*0Sstevel@tonic-gate
16*0Sstevel@tonic-gate=head1 NAME
17*0Sstevel@tonic-gate
18*0Sstevel@tonic-gatePod::Usage, pod2usage() - print a usage message from embedded pod documentation
19*0Sstevel@tonic-gate
20*0Sstevel@tonic-gate=head1 SYNOPSIS
21*0Sstevel@tonic-gate
22*0Sstevel@tonic-gate  use Pod::Usage
23*0Sstevel@tonic-gate
24*0Sstevel@tonic-gate  my $message_text  = "This text precedes the usage message.";
25*0Sstevel@tonic-gate  my $exit_status   = 2;          ## The exit status to use
26*0Sstevel@tonic-gate  my $verbose_level = 0;          ## The verbose level to use
27*0Sstevel@tonic-gate  my $filehandle    = \*STDERR;   ## The filehandle to write to
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate  pod2usage($message_text);
30*0Sstevel@tonic-gate
31*0Sstevel@tonic-gate  pod2usage($exit_status);
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gate  pod2usage( { -message => $message_text ,
34*0Sstevel@tonic-gate               -exitval => $exit_status  ,
35*0Sstevel@tonic-gate               -verbose => $verbose_level,
36*0Sstevel@tonic-gate               -output  => $filehandle } );
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gate  pod2usage(   -msg     => $message_text ,
39*0Sstevel@tonic-gate               -exitval => $exit_status  ,
40*0Sstevel@tonic-gate               -verbose => $verbose_level,
41*0Sstevel@tonic-gate               -output  => $filehandle   );
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate=head1 ARGUMENTS
44*0Sstevel@tonic-gate
45*0Sstevel@tonic-gateB<pod2usage> should be given either a single argument, or a list of
46*0Sstevel@tonic-gatearguments corresponding to an associative array (a "hash"). When a single
47*0Sstevel@tonic-gateargument is given, it should correspond to exactly one of the following:
48*0Sstevel@tonic-gate
49*0Sstevel@tonic-gate=over 4
50*0Sstevel@tonic-gate
51*0Sstevel@tonic-gate=item *
52*0Sstevel@tonic-gate
53*0Sstevel@tonic-gateA string containing the text of a message to print I<before> printing
54*0Sstevel@tonic-gatethe usage message
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate=item *
57*0Sstevel@tonic-gate
58*0Sstevel@tonic-gateA numeric value corresponding to the desired exit status
59*0Sstevel@tonic-gate
60*0Sstevel@tonic-gate=item *
61*0Sstevel@tonic-gate
62*0Sstevel@tonic-gateA reference to a hash
63*0Sstevel@tonic-gate
64*0Sstevel@tonic-gate=back
65*0Sstevel@tonic-gate
66*0Sstevel@tonic-gateIf more than one argument is given then the entire argument list is
67*0Sstevel@tonic-gateassumed to be a hash.  If a hash is supplied (either as a reference or
68*0Sstevel@tonic-gateas a list) it should contain one or more elements with the following
69*0Sstevel@tonic-gatekeys:
70*0Sstevel@tonic-gate
71*0Sstevel@tonic-gate=over 4
72*0Sstevel@tonic-gate
73*0Sstevel@tonic-gate=item C<-message>
74*0Sstevel@tonic-gate
75*0Sstevel@tonic-gate=item C<-msg>
76*0Sstevel@tonic-gate
77*0Sstevel@tonic-gateThe text of a message to print immediately prior to printing the
78*0Sstevel@tonic-gateprogram's usage message.
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate=item C<-exitval>
81*0Sstevel@tonic-gate
82*0Sstevel@tonic-gateThe desired exit status to pass to the B<exit()> function.
83*0Sstevel@tonic-gateThis should be an integer, or else the string "NOEXIT" to
84*0Sstevel@tonic-gateindicate that control should simply be returned without
85*0Sstevel@tonic-gateterminating the invoking process.
86*0Sstevel@tonic-gate
87*0Sstevel@tonic-gate=item C<-verbose>
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gateThe desired level of "verboseness" to use when printing the usage
90*0Sstevel@tonic-gatemessage. If the corresponding value is 0, then only the "SYNOPSIS"
91*0Sstevel@tonic-gatesection of the pod documentation is printed. If the corresponding value
92*0Sstevel@tonic-gateis 1, then the "SYNOPSIS" section, along with any section entitled
93*0Sstevel@tonic-gate"OPTIONS", "ARGUMENTS", or "OPTIONS AND ARGUMENTS" is printed.  If the
94*0Sstevel@tonic-gatecorresponding value is 2 or more then the entire manpage is printed.
95*0Sstevel@tonic-gate
96*0Sstevel@tonic-gate=item C<-output>
97*0Sstevel@tonic-gate
98*0Sstevel@tonic-gateA reference to a filehandle, or the pathname of a file to which the
99*0Sstevel@tonic-gateusage message should be written. The default is C<\*STDERR> unless the
100*0Sstevel@tonic-gateexit value is less than 2 (in which case the default is C<\*STDOUT>).
101*0Sstevel@tonic-gate
102*0Sstevel@tonic-gate=item C<-input>
103*0Sstevel@tonic-gate
104*0Sstevel@tonic-gateA reference to a filehandle, or the pathname of a file from which the
105*0Sstevel@tonic-gateinvoking script's pod documentation should be read.  It defaults to the
106*0Sstevel@tonic-gatefile indicated by C<$0> (C<$PROGRAM_NAME> for users of F<English.pm>).
107*0Sstevel@tonic-gate
108*0Sstevel@tonic-gate=item C<-pathlist>
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gateA list of directory paths. If the input file does not exist, then it
111*0Sstevel@tonic-gatewill be searched for in the given directory list (in the order the
112*0Sstevel@tonic-gatedirectories appear in the list). It defaults to the list of directories
113*0Sstevel@tonic-gateimplied by C<$ENV{PATH}>. The list may be specified either by a reference
114*0Sstevel@tonic-gateto an array, or by a string of directory paths which use the same path
115*0Sstevel@tonic-gateseparator as C<$ENV{PATH}> on your system (e.g., C<:> for Unix, C<;> for
116*0Sstevel@tonic-gateMSWin32 and DOS).
117*0Sstevel@tonic-gate
118*0Sstevel@tonic-gate=back
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gate=head1 DESCRIPTION
121*0Sstevel@tonic-gate
122*0Sstevel@tonic-gateB<pod2usage> will print a usage message for the invoking script (using
123*0Sstevel@tonic-gateits embedded pod documentation) and then exit the script with the
124*0Sstevel@tonic-gatedesired exit status. The usage message printed may have any one of three
125*0Sstevel@tonic-gatelevels of "verboseness": If the verbose level is 0, then only a synopsis
126*0Sstevel@tonic-gateis printed. If the verbose level is 1, then the synopsis is printed
127*0Sstevel@tonic-gatealong with a description (if present) of the command line options and
128*0Sstevel@tonic-gatearguments. If the verbose level is 2, then the entire manual page is
129*0Sstevel@tonic-gateprinted.
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gateUnless they are explicitly specified, the default values for the exit
132*0Sstevel@tonic-gatestatus, verbose level, and output stream to use are determined as
133*0Sstevel@tonic-gatefollows:
134*0Sstevel@tonic-gate
135*0Sstevel@tonic-gate=over 4
136*0Sstevel@tonic-gate
137*0Sstevel@tonic-gate=item *
138*0Sstevel@tonic-gate
139*0Sstevel@tonic-gateIf neither the exit status nor the verbose level is specified, then the
140*0Sstevel@tonic-gatedefault is to use an exit status of 2 with a verbose level of 0.
141*0Sstevel@tonic-gate
142*0Sstevel@tonic-gate=item *
143*0Sstevel@tonic-gate
144*0Sstevel@tonic-gateIf an exit status I<is> specified but the verbose level is I<not>, then the
145*0Sstevel@tonic-gateverbose level will default to 1 if the exit status is less than 2 and
146*0Sstevel@tonic-gatewill default to 0 otherwise.
147*0Sstevel@tonic-gate
148*0Sstevel@tonic-gate=item *
149*0Sstevel@tonic-gate
150*0Sstevel@tonic-gateIf an exit status is I<not> specified but verbose level I<is> given, then
151*0Sstevel@tonic-gatethe exit status will default to 2 if the verbose level is 0 and will
152*0Sstevel@tonic-gatedefault to 1 otherwise.
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate=item *
155*0Sstevel@tonic-gate
156*0Sstevel@tonic-gateIf the exit status used is less than 2, then output is printed on
157*0Sstevel@tonic-gateC<STDOUT>.  Otherwise output is printed on C<STDERR>.
158*0Sstevel@tonic-gate
159*0Sstevel@tonic-gate=back
160*0Sstevel@tonic-gate
161*0Sstevel@tonic-gateAlthough the above may seem a bit confusing at first, it generally does
162*0Sstevel@tonic-gate"the right thing" in most situations.  This determination of the default
163*0Sstevel@tonic-gatevalues to use is based upon the following typical Unix conventions:
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate=over 4
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gate=item *
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gateAn exit status of 0 implies "success". For example, B<diff(1)> exits
170*0Sstevel@tonic-gatewith a status of 0 if the two files have the same contents.
171*0Sstevel@tonic-gate
172*0Sstevel@tonic-gate=item *
173*0Sstevel@tonic-gate
174*0Sstevel@tonic-gateAn exit status of 1 implies possibly abnormal, but non-defective, program
175*0Sstevel@tonic-gatetermination.  For example, B<grep(1)> exits with a status of 1 if
176*0Sstevel@tonic-gateit did I<not> find a matching line for the given regular expression.
177*0Sstevel@tonic-gate
178*0Sstevel@tonic-gate=item *
179*0Sstevel@tonic-gate
180*0Sstevel@tonic-gateAn exit status of 2 or more implies a fatal error. For example, B<ls(1)>
181*0Sstevel@tonic-gateexits with a status of 2 if you specify an illegal (unknown) option on
182*0Sstevel@tonic-gatethe command line.
183*0Sstevel@tonic-gate
184*0Sstevel@tonic-gate=item *
185*0Sstevel@tonic-gate
186*0Sstevel@tonic-gateUsage messages issued as a result of bad command-line syntax should go
187*0Sstevel@tonic-gateto C<STDERR>.  However, usage messages issued due to an explicit request
188*0Sstevel@tonic-gateto print usage (like specifying B<-help> on the command line) should go
189*0Sstevel@tonic-gateto C<STDOUT>, just in case the user wants to pipe the output to a pager
190*0Sstevel@tonic-gate(such as B<more(1)>).
191*0Sstevel@tonic-gate
192*0Sstevel@tonic-gate=item *
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gateIf program usage has been explicitly requested by the user, it is often
195*0Sstevel@tonic-gatedesireable to exit with a status of 1 (as opposed to 0) after issuing
196*0Sstevel@tonic-gatethe user-requested usage message.  It is also desireable to give a
197*0Sstevel@tonic-gatemore verbose description of program usage in this case.
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate=back
200*0Sstevel@tonic-gate
201*0Sstevel@tonic-gateB<pod2usage> doesn't force the above conventions upon you, but it will
202*0Sstevel@tonic-gateuse them by default if you don't expressly tell it to do otherwise.  The
203*0Sstevel@tonic-gateability of B<pod2usage()> to accept a single number or a string makes it
204*0Sstevel@tonic-gateconvenient to use as an innocent looking error message handling function:
205*0Sstevel@tonic-gate
206*0Sstevel@tonic-gate    use Pod::Usage;
207*0Sstevel@tonic-gate    use Getopt::Long;
208*0Sstevel@tonic-gate
209*0Sstevel@tonic-gate    ## Parse options
210*0Sstevel@tonic-gate    GetOptions("help", "man", "flag1")  ||  pod2usage(2);
211*0Sstevel@tonic-gate    pod2usage(1)  if ($opt_help);
212*0Sstevel@tonic-gate    pod2usage(-verbose => 2)  if ($opt_man);
213*0Sstevel@tonic-gate
214*0Sstevel@tonic-gate    ## Check for too many filenames
215*0Sstevel@tonic-gate    pod2usage("$0: Too many files given.\n")  if (@ARGV > 1);
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gateSome user's however may feel that the above "economy of expression" is
218*0Sstevel@tonic-gatenot particularly readable nor consistent and may instead choose to do
219*0Sstevel@tonic-gatesomething more like the following:
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate    use Pod::Usage;
222*0Sstevel@tonic-gate    use Getopt::Long;
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gate    ## Parse options
225*0Sstevel@tonic-gate    GetOptions("help", "man", "flag1")  ||  pod2usage(-verbose => 0);
226*0Sstevel@tonic-gate    pod2usage(-verbose => 1)  if ($opt_help);
227*0Sstevel@tonic-gate    pod2usage(-verbose => 2)  if ($opt_man);
228*0Sstevel@tonic-gate
229*0Sstevel@tonic-gate    ## Check for too many filenames
230*0Sstevel@tonic-gate    pod2usage(-verbose => 2, -message => "$0: Too many files given.\n")
231*0Sstevel@tonic-gate        if (@ARGV > 1);
232*0Sstevel@tonic-gate
233*0Sstevel@tonic-gateAs with all things in Perl, I<there's more than one way to do it>, and
234*0Sstevel@tonic-gateB<pod2usage()> adheres to this philosophy.  If you are interested in
235*0Sstevel@tonic-gateseeing a number of different ways to invoke B<pod2usage> (although by no
236*0Sstevel@tonic-gatemeans exhaustive), please refer to L<"EXAMPLES">.
237*0Sstevel@tonic-gate
238*0Sstevel@tonic-gate=head1 EXAMPLES
239*0Sstevel@tonic-gate
240*0Sstevel@tonic-gateEach of the following invocations of C<pod2usage()> will print just the
241*0Sstevel@tonic-gate"SYNOPSIS" section to C<STDERR> and will exit with a status of 2:
242*0Sstevel@tonic-gate
243*0Sstevel@tonic-gate    pod2usage();
244*0Sstevel@tonic-gate
245*0Sstevel@tonic-gate    pod2usage(2);
246*0Sstevel@tonic-gate
247*0Sstevel@tonic-gate    pod2usage(-verbose => 0);
248*0Sstevel@tonic-gate
249*0Sstevel@tonic-gate    pod2usage(-exitval => 2);
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate    pod2usage({-exitval => 2, -output => \*STDERR});
252*0Sstevel@tonic-gate
253*0Sstevel@tonic-gate    pod2usage({-verbose => 0, -output  => \*STDERR});
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gate    pod2usage(-exitval => 2, -verbose => 0);
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gate    pod2usage(-exitval => 2, -verbose => 0, -output => \*STDERR);
258*0Sstevel@tonic-gate
259*0Sstevel@tonic-gateEach of the following invocations of C<pod2usage()> will print a message
260*0Sstevel@tonic-gateof "Syntax error." (followed by a newline) to C<STDERR>, immediately
261*0Sstevel@tonic-gatefollowed by just the "SYNOPSIS" section (also printed to C<STDERR>) and
262*0Sstevel@tonic-gatewill exit with a status of 2:
263*0Sstevel@tonic-gate
264*0Sstevel@tonic-gate    pod2usage("Syntax error.");
265*0Sstevel@tonic-gate
266*0Sstevel@tonic-gate    pod2usage(-message => "Syntax error.", -verbose => 0);
267*0Sstevel@tonic-gate
268*0Sstevel@tonic-gate    pod2usage(-msg  => "Syntax error.", -exitval => 2);
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate    pod2usage({-msg => "Syntax error.", -exitval => 2, -output => \*STDERR});
271*0Sstevel@tonic-gate
272*0Sstevel@tonic-gate    pod2usage({-msg => "Syntax error.", -verbose => 0, -output => \*STDERR});
273*0Sstevel@tonic-gate
274*0Sstevel@tonic-gate    pod2usage(-msg  => "Syntax error.", -exitval => 2, -verbose => 0);
275*0Sstevel@tonic-gate
276*0Sstevel@tonic-gate    pod2usage(-message => "Syntax error.",
277*0Sstevel@tonic-gate              -exitval => 2,
278*0Sstevel@tonic-gate              -verbose => 0,
279*0Sstevel@tonic-gate              -output  => \*STDERR);
280*0Sstevel@tonic-gate
281*0Sstevel@tonic-gateEach of the following invocations of C<pod2usage()> will print the
282*0Sstevel@tonic-gate"SYNOPSIS" section and any "OPTIONS" and/or "ARGUMENTS" sections to
283*0Sstevel@tonic-gateC<STDOUT> and will exit with a status of 1:
284*0Sstevel@tonic-gate
285*0Sstevel@tonic-gate    pod2usage(1);
286*0Sstevel@tonic-gate
287*0Sstevel@tonic-gate    pod2usage(-verbose => 1);
288*0Sstevel@tonic-gate
289*0Sstevel@tonic-gate    pod2usage(-exitval => 1);
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gate    pod2usage({-exitval => 1, -output => \*STDOUT});
292*0Sstevel@tonic-gate
293*0Sstevel@tonic-gate    pod2usage({-verbose => 1, -output => \*STDOUT});
294*0Sstevel@tonic-gate
295*0Sstevel@tonic-gate    pod2usage(-exitval => 1, -verbose => 1);
296*0Sstevel@tonic-gate
297*0Sstevel@tonic-gate    pod2usage(-exitval => 1, -verbose => 1, -output => \*STDOUT});
298*0Sstevel@tonic-gate
299*0Sstevel@tonic-gateEach of the following invocations of C<pod2usage()> will print the
300*0Sstevel@tonic-gateentire manual page to C<STDOUT> and will exit with a status of 1:
301*0Sstevel@tonic-gate
302*0Sstevel@tonic-gate    pod2usage(-verbose  => 2);
303*0Sstevel@tonic-gate
304*0Sstevel@tonic-gate    pod2usage({-verbose => 2, -output => \*STDOUT});
305*0Sstevel@tonic-gate
306*0Sstevel@tonic-gate    pod2usage(-exitval  => 1, -verbose => 2);
307*0Sstevel@tonic-gate
308*0Sstevel@tonic-gate    pod2usage({-exitval => 1, -verbose => 2, -output => \*STDOUT});
309*0Sstevel@tonic-gate
310*0Sstevel@tonic-gate=head2 Recommended Use
311*0Sstevel@tonic-gate
312*0Sstevel@tonic-gateMost scripts should print some type of usage message to C<STDERR> when a
313*0Sstevel@tonic-gatecommand line syntax error is detected. They should also provide an
314*0Sstevel@tonic-gateoption (usually C<-H> or C<-help>) to print a (possibly more verbose)
315*0Sstevel@tonic-gateusage message to C<STDOUT>. Some scripts may even wish to go so far as to
316*0Sstevel@tonic-gateprovide a means of printing their complete documentation to C<STDOUT>
317*0Sstevel@tonic-gate(perhaps by allowing a C<-man> option). The following complete example
318*0Sstevel@tonic-gateuses B<Pod::Usage> in combination with B<Getopt::Long> to do all of these
319*0Sstevel@tonic-gatethings:
320*0Sstevel@tonic-gate
321*0Sstevel@tonic-gate    use Getopt::Long;
322*0Sstevel@tonic-gate    use Pod::Usage;
323*0Sstevel@tonic-gate
324*0Sstevel@tonic-gate    my $man = 0;
325*0Sstevel@tonic-gate    my $help = 0;
326*0Sstevel@tonic-gate    ## Parse options and print usage if there is a syntax error,
327*0Sstevel@tonic-gate    ## or if usage was explicitly requested.
328*0Sstevel@tonic-gate    GetOptions('help|?' => \$help, man => \$man) or pod2usage(2);
329*0Sstevel@tonic-gate    pod2usage(1) if $help;
330*0Sstevel@tonic-gate    pod2usage(-verbose => 2) if $man;
331*0Sstevel@tonic-gate
332*0Sstevel@tonic-gate    ## If no arguments were given, then allow STDIN to be used only
333*0Sstevel@tonic-gate    ## if it's not connected to a terminal (otherwise print usage)
334*0Sstevel@tonic-gate    pod2usage("$0: No files given.")  if ((@ARGV == 0) && (-t STDIN));
335*0Sstevel@tonic-gate    __END__
336*0Sstevel@tonic-gate
337*0Sstevel@tonic-gate    =head1 NAME
338*0Sstevel@tonic-gate
339*0Sstevel@tonic-gate    sample - Using GetOpt::Long and Pod::Usage
340*0Sstevel@tonic-gate
341*0Sstevel@tonic-gate    =head1 SYNOPSIS
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gate    sample [options] [file ...]
344*0Sstevel@tonic-gate
345*0Sstevel@tonic-gate     Options:
346*0Sstevel@tonic-gate       -help            brief help message
347*0Sstevel@tonic-gate       -man             full documentation
348*0Sstevel@tonic-gate
349*0Sstevel@tonic-gate    =head1 OPTIONS
350*0Sstevel@tonic-gate
351*0Sstevel@tonic-gate    =over 8
352*0Sstevel@tonic-gate
353*0Sstevel@tonic-gate    =item B<-help>
354*0Sstevel@tonic-gate
355*0Sstevel@tonic-gate    Print a brief help message and exits.
356*0Sstevel@tonic-gate
357*0Sstevel@tonic-gate    =item B<-man>
358*0Sstevel@tonic-gate
359*0Sstevel@tonic-gate    Prints the manual page and exits.
360*0Sstevel@tonic-gate
361*0Sstevel@tonic-gate    =back
362*0Sstevel@tonic-gate
363*0Sstevel@tonic-gate    =head1 DESCRIPTION
364*0Sstevel@tonic-gate
365*0Sstevel@tonic-gate    B<This program> will read the given input file(s) and do something
366*0Sstevel@tonic-gate    useful with the contents thereof.
367*0Sstevel@tonic-gate
368*0Sstevel@tonic-gate    =cut
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate=head1 CAVEATS
371*0Sstevel@tonic-gate
372*0Sstevel@tonic-gateBy default, B<pod2usage()> will use C<$0> as the path to the pod input
373*0Sstevel@tonic-gatefile.  Unfortunately, not all systems on which Perl runs will set C<$0>
374*0Sstevel@tonic-gateproperly (although if C<$0> isn't found, B<pod2usage()> will search
375*0Sstevel@tonic-gateC<$ENV{PATH}> or else the list specified by the C<-pathlist> option).
376*0Sstevel@tonic-gateIf this is the case for your system, you may need to explicitly specify
377*0Sstevel@tonic-gatethe path to the pod docs for the invoking script using something
378*0Sstevel@tonic-gatesimilar to the following:
379*0Sstevel@tonic-gate
380*0Sstevel@tonic-gate    pod2usage(-exitval => 2, -input => "/path/to/your/pod/docs");
381*0Sstevel@tonic-gate
382*0Sstevel@tonic-gate=head1 AUTHOR
383*0Sstevel@tonic-gate
384*0Sstevel@tonic-gatePlease report bugs using L<http://rt.cpan.org>.
385*0Sstevel@tonic-gate
386*0Sstevel@tonic-gateBrad Appleton E<lt>bradapp@enteract.comE<gt>
387*0Sstevel@tonic-gate
388*0Sstevel@tonic-gateBased on code for B<Pod::Text::pod2text()> written by
389*0Sstevel@tonic-gateTom Christiansen E<lt>tchrist@mox.perl.comE<gt>
390*0Sstevel@tonic-gate
391*0Sstevel@tonic-gate=head1 ACKNOWLEDGEMENTS
392*0Sstevel@tonic-gate
393*0Sstevel@tonic-gateSteven McDougall E<lt>swmcd@world.std.comE<gt> for his help and patience
394*0Sstevel@tonic-gatewith re-writing this manpage.
395*0Sstevel@tonic-gate
396*0Sstevel@tonic-gate=cut
397*0Sstevel@tonic-gate
398*0Sstevel@tonic-gate#############################################################################
399*0Sstevel@tonic-gate
400*0Sstevel@tonic-gateuse strict;
401*0Sstevel@tonic-gate#use diagnostics;
402*0Sstevel@tonic-gateuse Carp;
403*0Sstevel@tonic-gateuse Config;
404*0Sstevel@tonic-gateuse Exporter;
405*0Sstevel@tonic-gateuse File::Spec;
406*0Sstevel@tonic-gate
407*0Sstevel@tonic-gateuse vars qw(@ISA @EXPORT);
408*0Sstevel@tonic-gate@EXPORT = qw(&pod2usage);
409*0Sstevel@tonic-gateBEGIN {
410*0Sstevel@tonic-gate    if ( $] >= 5.005_58 ) {
411*0Sstevel@tonic-gate       require Pod::Text;
412*0Sstevel@tonic-gate       @ISA = qw( Pod::Text );
413*0Sstevel@tonic-gate    }
414*0Sstevel@tonic-gate    else {
415*0Sstevel@tonic-gate       require Pod::PlainText;
416*0Sstevel@tonic-gate       @ISA = qw( Pod::PlainText );
417*0Sstevel@tonic-gate    }
418*0Sstevel@tonic-gate}
419*0Sstevel@tonic-gate
420*0Sstevel@tonic-gate
421*0Sstevel@tonic-gate##---------------------------------------------------------------------------
422*0Sstevel@tonic-gate
423*0Sstevel@tonic-gate##---------------------------------
424*0Sstevel@tonic-gate## Function definitions begin here
425*0Sstevel@tonic-gate##---------------------------------
426*0Sstevel@tonic-gate
427*0Sstevel@tonic-gatesub pod2usage {
428*0Sstevel@tonic-gate    local($_) = shift || "";
429*0Sstevel@tonic-gate    my %opts;
430*0Sstevel@tonic-gate    ## Collect arguments
431*0Sstevel@tonic-gate    if (@_ > 0) {
432*0Sstevel@tonic-gate        ## Too many arguments - assume that this is a hash and
433*0Sstevel@tonic-gate        ## the user forgot to pass a reference to it.
434*0Sstevel@tonic-gate        %opts = ($_, @_);
435*0Sstevel@tonic-gate    }
436*0Sstevel@tonic-gate    elsif (ref $_) {
437*0Sstevel@tonic-gate        ## User passed a ref to a hash
438*0Sstevel@tonic-gate        %opts = %{$_}  if (ref($_) eq 'HASH');
439*0Sstevel@tonic-gate    }
440*0Sstevel@tonic-gate    elsif (/^[-+]?\d+$/) {
441*0Sstevel@tonic-gate        ## User passed in the exit value to use
442*0Sstevel@tonic-gate        $opts{"-exitval"} =  $_;
443*0Sstevel@tonic-gate    }
444*0Sstevel@tonic-gate    else {
445*0Sstevel@tonic-gate        ## User passed in a message to print before issuing usage.
446*0Sstevel@tonic-gate        $_  and  $opts{"-message"} = $_;
447*0Sstevel@tonic-gate    }
448*0Sstevel@tonic-gate
449*0Sstevel@tonic-gate    ## Need this for backward compatibility since we formerly used
450*0Sstevel@tonic-gate    ## options that were all uppercase words rather than ones that
451*0Sstevel@tonic-gate    ## looked like Unix command-line options.
452*0Sstevel@tonic-gate    ## to be uppercase keywords)
453*0Sstevel@tonic-gate    %opts = map {
454*0Sstevel@tonic-gate        my $val = $opts{$_};
455*0Sstevel@tonic-gate        s/^(?=\w)/-/;
456*0Sstevel@tonic-gate        /^-msg/i   and  $_ = '-message';
457*0Sstevel@tonic-gate        /^-exit/i  and  $_ = '-exitval';
458*0Sstevel@tonic-gate        lc($_) => $val;
459*0Sstevel@tonic-gate    } (keys %opts);
460*0Sstevel@tonic-gate
461*0Sstevel@tonic-gate    ## Now determine default -exitval and -verbose values to use
462*0Sstevel@tonic-gate    if ((! defined $opts{"-exitval"}) && (! defined $opts{"-verbose"})) {
463*0Sstevel@tonic-gate        $opts{"-exitval"} = 2;
464*0Sstevel@tonic-gate        $opts{"-verbose"} = 0;
465*0Sstevel@tonic-gate    }
466*0Sstevel@tonic-gate    elsif (! defined $opts{"-exitval"}) {
467*0Sstevel@tonic-gate        $opts{"-exitval"} = ($opts{"-verbose"} > 0) ? 1 : 2;
468*0Sstevel@tonic-gate    }
469*0Sstevel@tonic-gate    elsif (! defined $opts{"-verbose"}) {
470*0Sstevel@tonic-gate        $opts{"-verbose"} = ($opts{"-exitval"} < 2);
471*0Sstevel@tonic-gate    }
472*0Sstevel@tonic-gate
473*0Sstevel@tonic-gate    ## Default the output file
474*0Sstevel@tonic-gate    $opts{"-output"} = (lc($opts{"-exitval"}) eq "noexit" ||
475*0Sstevel@tonic-gate                        $opts{"-exitval"} < 2) ? \*STDOUT : \*STDERR
476*0Sstevel@tonic-gate            unless (defined $opts{"-output"});
477*0Sstevel@tonic-gate    ## Default the input file
478*0Sstevel@tonic-gate    $opts{"-input"} = $0  unless (defined $opts{"-input"});
479*0Sstevel@tonic-gate
480*0Sstevel@tonic-gate    ## Look up input file in path if it doesnt exist.
481*0Sstevel@tonic-gate    unless ((ref $opts{"-input"}) || (-e $opts{"-input"})) {
482*0Sstevel@tonic-gate        my ($dirname, $basename) = ('', $opts{"-input"});
483*0Sstevel@tonic-gate        my $pathsep = ($^O =~ /^(?:dos|os2|MSWin32)$/) ? ";"
484*0Sstevel@tonic-gate                            : (($^O eq 'MacOS' || $^O eq 'VMS') ? ',' :  ":");
485*0Sstevel@tonic-gate        my $pathspec = $opts{"-pathlist"} || $ENV{PATH} || $ENV{PERL5LIB};
486*0Sstevel@tonic-gate
487*0Sstevel@tonic-gate        my @paths = (ref $pathspec) ? @$pathspec : split($pathsep, $pathspec);
488*0Sstevel@tonic-gate        for $dirname (@paths) {
489*0Sstevel@tonic-gate            $_ = File::Spec->catfile($dirname, $basename)  if length;
490*0Sstevel@tonic-gate            last if (-e $_) && ($opts{"-input"} = $_);
491*0Sstevel@tonic-gate        }
492*0Sstevel@tonic-gate    }
493*0Sstevel@tonic-gate
494*0Sstevel@tonic-gate    ## Now create a pod reader and constrain it to the desired sections.
495*0Sstevel@tonic-gate    my $parser = new Pod::Usage(USAGE_OPTIONS => \%opts);
496*0Sstevel@tonic-gate    if ($opts{"-verbose"} == 0) {
497*0Sstevel@tonic-gate        $parser->select("SYNOPSIS");
498*0Sstevel@tonic-gate    }
499*0Sstevel@tonic-gate    elsif ($opts{"-verbose"} == 1) {
500*0Sstevel@tonic-gate        my $opt_re = '(?i)' .
501*0Sstevel@tonic-gate                     '(?:OPTIONS|ARGUMENTS)' .
502*0Sstevel@tonic-gate                     '(?:\s*(?:AND|\/)\s*(?:OPTIONS|ARGUMENTS))?';
503*0Sstevel@tonic-gate        $parser->select( 'SYNOPSIS', $opt_re, "DESCRIPTION/$opt_re" );
504*0Sstevel@tonic-gate    }
505*0Sstevel@tonic-gate
506*0Sstevel@tonic-gate    ## Now translate the pod document and then exit with the desired status
507*0Sstevel@tonic-gate    if ( $opts{"-verbose"} >= 2
508*0Sstevel@tonic-gate             and  !ref($opts{"-input"})
509*0Sstevel@tonic-gate             and  $opts{"-output"} == \*STDOUT )
510*0Sstevel@tonic-gate    {
511*0Sstevel@tonic-gate       ## spit out the entire PODs. Might as well invoke perldoc
512*0Sstevel@tonic-gate       my $progpath = File::Spec->catfile($Config{scriptdir}, "perldoc");
513*0Sstevel@tonic-gate       system($progpath, $opts{"-input"});
514*0Sstevel@tonic-gate    }
515*0Sstevel@tonic-gate    else {
516*0Sstevel@tonic-gate       $parser->parse_from_file($opts{"-input"}, $opts{"-output"});
517*0Sstevel@tonic-gate    }
518*0Sstevel@tonic-gate
519*0Sstevel@tonic-gate    exit($opts{"-exitval"})  unless (lc($opts{"-exitval"}) eq 'noexit');
520*0Sstevel@tonic-gate}
521*0Sstevel@tonic-gate
522*0Sstevel@tonic-gate##---------------------------------------------------------------------------
523*0Sstevel@tonic-gate
524*0Sstevel@tonic-gate##-------------------------------
525*0Sstevel@tonic-gate## Method definitions begin here
526*0Sstevel@tonic-gate##-------------------------------
527*0Sstevel@tonic-gate
528*0Sstevel@tonic-gatesub new {
529*0Sstevel@tonic-gate    my $this = shift;
530*0Sstevel@tonic-gate    my $class = ref($this) || $this;
531*0Sstevel@tonic-gate    my %params = @_;
532*0Sstevel@tonic-gate    my $self = {%params};
533*0Sstevel@tonic-gate    bless $self, $class;
534*0Sstevel@tonic-gate    $self->initialize();
535*0Sstevel@tonic-gate    return $self;
536*0Sstevel@tonic-gate}
537*0Sstevel@tonic-gate
538*0Sstevel@tonic-gatesub begin_pod {
539*0Sstevel@tonic-gate    my $self = shift;
540*0Sstevel@tonic-gate    $self->SUPER::begin_pod();  ## Have to call superclass
541*0Sstevel@tonic-gate    my $msg = $self->{USAGE_OPTIONS}->{-message}  or  return 1;
542*0Sstevel@tonic-gate    my $out_fh = $self->output_handle();
543*0Sstevel@tonic-gate    print $out_fh "$msg\n";
544*0Sstevel@tonic-gate}
545*0Sstevel@tonic-gate
546*0Sstevel@tonic-gatesub preprocess_paragraph {
547*0Sstevel@tonic-gate    my $self = shift;
548*0Sstevel@tonic-gate    local $_ = shift;
549*0Sstevel@tonic-gate    my $line = shift;
550*0Sstevel@tonic-gate    ## See if this is a heading and we arent printing the entire manpage.
551*0Sstevel@tonic-gate    if (($self->{USAGE_OPTIONS}->{-verbose} < 2) && /^=head/) {
552*0Sstevel@tonic-gate        ## Change the title of the SYNOPSIS section to USAGE
553*0Sstevel@tonic-gate        s/^=head1\s+SYNOPSIS\s*$/=head1 USAGE/;
554*0Sstevel@tonic-gate        ## Try to do some lowercasing instead of all-caps in headings
555*0Sstevel@tonic-gate        s{([A-Z])([A-Z]+)}{((length($2) > 2) ? $1 : lc($1)) . lc($2)}ge;
556*0Sstevel@tonic-gate        ## Use a colon to end all headings
557*0Sstevel@tonic-gate        s/\s*$/:/  unless (/:\s*$/);
558*0Sstevel@tonic-gate        $_ .= "\n";
559*0Sstevel@tonic-gate    }
560*0Sstevel@tonic-gate    return  $self->SUPER::preprocess_paragraph($_);
561*0Sstevel@tonic-gate}
562*0Sstevel@tonic-gate
563*0Sstevel@tonic-gate1; # keep require happy
564