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