summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rw-r--r--lib/Pod/Checker.pm18
-rw-r--r--lib/Pod/InputObjects.pm2
-rw-r--r--lib/Pod/ParseUtils.pm6
-rw-r--r--lib/Pod/Parser.pm56
-rw-r--r--lib/Pod/Select.pm4
-rw-r--r--lib/Pod/Usage.pm38
-rw-r--r--t/pod/find.t31
-rw-r--r--t/pod/pod2usage2.t178
-rw-r--r--t/pod/poderrs.xr2
10 files changed, 264 insertions, 72 deletions
diff --git a/MANIFEST b/MANIFEST
index dadb7163f1..8dd603c3f6 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -2976,6 +2976,7 @@ t/pod/oneline_cmds.t Test single paragraph ==cmds
t/pod/oneline_cmds.xr Expected results for oneline_cmds.t
t/pod/plainer.t Test Pod::Plainer
t/pod/pod2usage.t Test Pod::Usage
+t/pod/pod2usage2.t Test Pod::Usage
t/pod/pod2usage.xr Expected results for pod2usage.t
t/pod/poderrs.t Test POD errors
t/pod/poderrs.xr Expected results for poderrs.t
diff --git a/lib/Pod/Checker.pm b/lib/Pod/Checker.pm
index f20fe84c4c..49162da4a2 100644
--- a/lib/Pod/Checker.pm
+++ b/lib/Pod/Checker.pm
@@ -10,7 +10,7 @@
package Pod::Checker;
use vars qw($VERSION);
-$VERSION = 1.42; ## Current version of this package
+$VERSION = 1.43; ## Current version of this package
require 5.005; ## requires this Perl version or later
use Pod::ParseUtils; ## for hyperlinks and lists
@@ -57,7 +57,7 @@ Curious/ambitious users are welcome to propose additional features they wish
to see in B<Pod::Checker> and B<podchecker> and verify that the checks are
consistent with L<perlpod>.
-The following checks are currently preformed:
+The following checks are currently performed:
=over 4
@@ -142,7 +142,7 @@ There is no specification of the formatter after the C<=for> command.
=item * unresolved internal link I<NAME>
The given link to I<NAME> does not have a matching node in the current
-POD. This also happens when a single word node name is not enclosed in
+POD. This also happend when a single word node name is not enclosed in
C<"">.
=item * Unknown command "I<CMD>"
@@ -234,7 +234,7 @@ C<=over>/C<=back> block.
=item * =item type mismatch (I<one> vs. I<two>)
-A list started with e.g. a bulleted C<=item> and continued with a
+A list started with e.g. a bulletted C<=item> and continued with a
numbered one. This is obviously inconsistent. For most translators the
type of the I<first> C<=item> determines the type of the list.
@@ -623,9 +623,11 @@ sub poderror {
if(!%opts || ($opts{-severity} && $opts{-severity} eq 'ERROR'));
++($self->{_NUM_WARNINGS})
if(!%opts || ($opts{-severity} && $opts{-severity} eq 'WARNING'));
- my $out_fh = $self->output_handle() || \*STDERR;
- print $out_fh ($severity, $msg, $line, $file, "\n")
- if($self->{-warnings} || !%opts || $opts{-severity} ne 'WARNING');
+ unless($self->{-quiet}) {
+ my $out_fh = $self->output_handle() || \*STDERR;
+ print $out_fh ($severity, $msg, $line, $file, "\n")
+ if($self->{-warnings} || !%opts || $opts{-severity} ne 'WARNING');
+ }
}
##################################
@@ -1101,7 +1103,7 @@ sub _check_ptree {
}
if($nestlist =~ /$cmd/) {
$self->poderror({ -line => $line, -file => $file,
- -severity => 'ERROR',
+ -severity => 'WARNING',
-msg => "nested commands $cmd<...$cmd<...>...>"});
# _TODO_ should we add the contents anyway?
# expand it anyway, see below
diff --git a/lib/Pod/InputObjects.pm b/lib/Pod/InputObjects.pm
index 222061f55e..fa5f61f9a7 100644
--- a/lib/Pod/InputObjects.pm
+++ b/lib/Pod/InputObjects.pm
@@ -183,7 +183,7 @@ sub name {
my $handle = $pod_input->handle();
Returns a reference to the handle object from which input is read (the
-one used to construct this input source object).
+one used to contructed this input source object).
=end __PRIVATE__
diff --git a/lib/Pod/ParseUtils.pm b/lib/Pod/ParseUtils.pm
index 64c92b6da6..878860121d 100644
--- a/lib/Pod/ParseUtils.pm
+++ b/lib/Pod/ParseUtils.pm
@@ -10,7 +10,7 @@
package Pod::ParseUtils;
use vars qw($VERSION);
-$VERSION = 1.30; ## Current version of this package
+$VERSION = 1.33; ## Current version of this package
require 5.005; ## requires this Perl version or later
=head1 NAME
@@ -357,7 +357,7 @@ sub parse {
$type = 'item';
}
# non-standard: Hyperlink
- elsif(m!^((?:http|ftp|mailto|news):.+)$!i) {
+ elsif(m!^(\w+:[^:\s]\S*)$!i) {
$node = $1;
$type = 'hyperlink';
}
@@ -371,7 +371,7 @@ sub parse {
($alttext, $node) = ($1,$2);
}
# nonstandard: alttext and hyperlink
- elsif(m!^(.*?)\s*[|]\s*((?:http|ftp|mailto|news):.+)$!) {
+ elsif(m!^(.*?)\s*[|]\s*(\w+:[^:\s]\S*)$!) {
($alttext, $node) = ($1,$2);
$type = 'hyperlink';
}
diff --git a/lib/Pod/Parser.pm b/lib/Pod/Parser.pm
index 6c3f161815..a5fde84850 100644
--- a/lib/Pod/Parser.pm
+++ b/lib/Pod/Parser.pm
@@ -10,7 +10,7 @@
package Pod::Parser;
use vars qw($VERSION);
-$VERSION = 1.30; ## Current version of this package
+$VERSION = 1.32; ## Current version of this package
require 5.005; ## requires this Perl version or later
#############################################################################
@@ -118,7 +118,7 @@ You may also want to override the B<begin_input()> and B<end_input()>
methods for your subclass (to perform any needed per-file and/or
per-document initialization or cleanup).
-If you need to perform any preprocessing of input before it is parsed
+If you need to perform any preprocesssing of input before it is parsed
you may want to override one or more of B<preprocess_line()> and/or
B<preprocess_paragraph()>.
@@ -140,7 +140,7 @@ to avoid name collisions.
For the most part, the B<Pod::Parser> base class should be able to
do most of the input parsing for you and leave you free to worry about
-how to interpret the commands and translate the result.
+how to intepret the commands and translate the result.
Note that all we have described here in this quick overview is the
simplest most straightforward use of B<Pod::Parser> to do stream-based
@@ -651,7 +651,7 @@ them in simple bottom-up order.
The parameter C<$text> is a string or block of text to be parsed
for interior sequences; and the parameter C<$line_num> is the
-line number corresponding to the beginning of C<$text>.
+line number curresponding to the beginning of C<$text>.
B<parse_text()> will parse the given text into a parse-tree of "nodes."
and interior-sequences. Each "node" in the parse tree is either a
@@ -1066,7 +1066,6 @@ sub parse_from_filehandle {
while (defined ($textline = $tied_fh ? <$in_fh> : $in_fh->getline)) {
$textline = $self->preprocess_line($textline, ++$nlines);
next unless ((defined $textline) && (length $textline));
- $_ = $paragraph; ## save previous contents
if ((! length $paragraph) && ($textline =~ /^==/)) {
## '==' denotes a one-line command paragraph
@@ -1157,20 +1156,13 @@ sub parse_from_file {
my $self = shift;
my %opts = (ref $_[0] eq 'HASH') ? %{ shift() } : ();
my ($infile, $outfile) = @_;
- my ($in_fh, $out_fh) = (gensym, gensym) if ($] < 5.6);
+ my ($in_fh, $out_fh) = (gensym(), gensym()) if ($] < 5.006);
my ($close_input, $close_output) = (0, 0);
local *myData = $self;
local *_;
## Is $infile a filename or a (possibly implied) filehandle
- $infile = '-' unless ((defined $infile) && (length $infile));
- if (($infile eq '-') || ($infile =~ /^<&(STDIN|0)$/i)) {
- ## Not a filename, just a string implying STDIN
- $infile ||= '-';
- $myData{_INFILE} = "<standard input>";
- $in_fh = \*STDIN;
- }
- elsif (ref $infile) {
+ if (defined $infile && ref $infile) {
if (ref($infile) =~ /^(SCALAR|ARRAY|HASH|CODE|REF)$/) {
croak "Input from $1 reference not supported!\n";
}
@@ -1179,6 +1171,14 @@ sub parse_from_file {
$myData{_INFILE} = ${$infile};
$in_fh = $infile;
}
+ elsif (!defined($infile) || !length($infile) || ($infile eq '-')
+ || ($infile =~ /^<&(?:STDIN|0)$/i))
+ {
+ ## Not a filename, just a string implying STDIN
+ $infile ||= '-';
+ $myData{_INFILE} = "<standard input>";
+ $in_fh = \*STDIN;
+ }
else {
## We have a filename, open it for reading
$myData{_INFILE} = $infile;
@@ -1194,20 +1194,7 @@ sub parse_from_file {
## already
## Is $outfile a filename, a (possibly implied) filehandle, maybe a ref?
- if (!defined($outfile) || !length($outfile) || ($outfile eq '-')
- || ($outfile =~ /^>&?(?:STDOUT|1)$/i))
- {
- if (defined $myData{_TOP_STREAM}) {
- $out_fh = $myData{_OUTPUT};
- }
- else {
- ## Not a filename, just a string implying STDOUT
- $outfile ||= '-';
- $myData{_OUTFILE} = "<standard output>";
- $out_fh = \*STDOUT;
- }
- }
- elsif (ref $outfile) {
+ if (ref $outfile) {
## we need to check for ref() first, as other checks involve reading
if (ref($outfile) =~ /^(ARRAY|HASH|CODE)$/) {
croak "Output to $1 reference not supported!\n";
@@ -1227,6 +1214,19 @@ sub parse_from_file {
$out_fh = $outfile;
}
}
+ elsif (!defined($outfile) || !length($outfile) || ($outfile eq '-')
+ || ($outfile =~ /^>&?(?:STDOUT|1)$/i))
+ {
+ if (defined $myData{_TOP_STREAM}) {
+ $out_fh = $myData{_OUTPUT};
+ }
+ else {
+ ## Not a filename, just a string implying STDOUT
+ $outfile ||= '-';
+ $myData{_OUTFILE} = "<standard output>";
+ $out_fh = \*STDOUT;
+ }
+ }
elsif ($outfile =~ /^>&(STDERR|2)$/i) {
## Not a filename, just a string implying STDERR
$myData{_OUTFILE} = "<standard error>";
diff --git a/lib/Pod/Select.pm b/lib/Pod/Select.pm
index d0cbec6901..1cc14dff4b 100644
--- a/lib/Pod/Select.pm
+++ b/lib/Pod/Select.pm
@@ -428,7 +428,7 @@ sub clear_selections {
Returns a value of true if the given section and subsection heading
titles match any of the currently selected section specifications in
effect from prior calls to B<select()> and B<add_selection()> (or if
-there are no explicitly selected/deselected sections).
+there are no explictly selected/deselected sections).
The arguments C<$heading1>, C<$heading2>, etc. are the heading titles of
the corresponding sections, subsections, etc. to try and match. If
@@ -575,7 +575,7 @@ are used.
All other arguments should correspond to the names of input files
containing POD sections. A file name of "-" or "<&STDIN" will
-be interpreted to mean standard input (which is the default if no
+be interpeted to mean standard input (which is the default if no
filenames are given).
=cut
diff --git a/lib/Pod/Usage.pm b/lib/Pod/Usage.pm
index 0827dcc4d2..c298e941f2 100644
--- a/lib/Pod/Usage.pm
+++ b/lib/Pod/Usage.pm
@@ -10,7 +10,7 @@
package Pod::Usage;
use vars qw($VERSION);
-$VERSION = 1.30; ## Current version of this package
+$VERSION = 1.33; ## Current version of this package
require 5.005; ## requires this Perl version or later
=head1 NAME
@@ -40,6 +40,9 @@ Pod::Usage, pod2usage() - print a usage message from embedded pod documentation
-verbose => $verbose_level,
-output => $filehandle );
+ pod2usage( -verbose => 2,
+ -noperldoc => 1 )
+
=head1 ARGUMENTS
B<pod2usage> should be given either a single argument, or a list of
@@ -94,7 +97,8 @@ is 1, then the "SYNOPSIS" section, along with any section entitled
corresponding value is 2 or more then the entire manpage is printed.
The special verbosity level 99 requires to also specify the -section
-parameter; then these sections are extracted and printed.
+parameter; then these sections are extracted (see L<Pod::Select>)
+and printed.
=item C<-section>
@@ -123,6 +127,14 @@ to an array, or by a string of directory paths which use the same path
separator as C<$ENV{PATH}> on your system (e.g., C<:> for Unix, C<;> for
MSWin32 and DOS).
+=item C<-noperldoc>
+
+By default, Pod::Usage will call L<perldoc> when -verbose >= 2 is
+specified. This does not work well e.g. if the script was packed
+with L<PAR>. The -noperldoc option suppresses the external call to
+L<perldoc> and uses the simple text formatter (L<Pod::Text>) to
+output the POD.
+
=back
=head1 DESCRIPTION
@@ -200,8 +212,8 @@ to C<STDOUT>, just in case the user wants to pipe the output to a pager
=item *
If program usage has been explicitly requested by the user, it is often
-desirable to exit with a status of 1 (as opposed to 0) after issuing
-the user-requested usage message. It is also desirable to give a
+desireable to exit with a status of 1 (as opposed to 0) after issuing
+the user-requested usage message. It is also desireable to give a
more verbose description of program usage in this case.
=back
@@ -387,6 +399,11 @@ similar to the following:
pod2usage(-exitval => 2, -input => "/path/to/your/pod/docs");
+In the pathological case that a script is called via a relative path
+I<and> the script itself changes the current working directory
+(see L<perlfunc/chdir>) I<before> calling pod2usage, Pod::Usage will
+fail even on robust platforms. Don't do that.
+
=head1 AUTHOR
Please report bugs using L<http://rt.cpan.org>.
@@ -433,7 +450,7 @@ BEGIN {
##---------------------------------
sub pod2usage {
- local($_) = shift || "";
+ local($_) = shift;
my %opts;
## Collect arguments
if (@_ > 0) {
@@ -441,6 +458,9 @@ sub pod2usage {
## the user forgot to pass a reference to it.
%opts = ($_, @_);
}
+ elsif (!defined $_) {
+ $_ = "";
+ }
elsif (ref $_) {
## User passed a ref to a hash
%opts = %{$_} if (ref($_) eq 'HASH');
@@ -503,7 +523,7 @@ sub pod2usage {
## Now create a pod reader and constrain it to the desired sections.
my $parser = new Pod::Usage(USAGE_OPTIONS => \%opts);
if ($opts{"-verbose"} == 0) {
- $parser->select("SYNOPSIS");
+ $parser->select('SYNOPSIS\s*');
}
elsif ($opts{"-verbose"} == 1) {
my $opt_re = '(?i)' .
@@ -517,7 +537,8 @@ sub pod2usage {
}
## Now translate the pod document and then exit with the desired status
- if ( $opts{"-verbose"} >= 2
+ if ( !$opts{"-noperldoc"}
+ and $opts{"-verbose"} >= 2
and !ref($opts{"-input"})
and $opts{"-output"} == \*STDOUT )
{
@@ -562,6 +583,9 @@ sub select {
}
}
+# Override Pod::Text->seq_i to return just "arg", not "*arg*".
+sub seq_i { return $_[1] }
+
# This overrides the Pod::Text method to do something very akin to what
# Pod::Select did as well as the work done below by preprocess_paragraph.
# Note that the below is very, very specific to Pod::Text.
diff --git a/t/pod/find.t b/t/pod/find.t
index 20586014f1..66b65c5c39 100644
--- a/t/pod/find.t
+++ b/t/pod/find.t
@@ -88,7 +88,6 @@ print "### found $result\n";
require Config;
if ($^O eq 'VMS') { # privlib is perl_root:[lib] OK but not under mms
- $result = VMS::Filespec::vmsify($result); #if you want VMS you need to force it.
$compare = "lib.File]Find.pm";
$result =~ s/perl_root:\[\-?\.?//i;
$result =~ s/\[\-?\.?//i; # needed under `mms test`
@@ -102,31 +101,19 @@ else {
}
# Search for a documentation pod rather than a module
-my $searchpod = $ENV{PERL_CORE} ? 'Stuff' : 'perlfunc';
+my $searchpod = 'Stuff';
print "### searching for $searchpod.pod\n";
-$result = pod_where($ENV{PERL_CORE} ?
- { -dirs => [ File::Spec->catdir('pod', 'testpods', 'lib', 'Pod') ],
- -verbose => $VERBOSE }
- : { -inc => 1, -verbose => $VERBOSE }, $searchpod)
+$result = pod_where(
+ { -dirs => [ File::Spec->catdir(
+ $ENV{PERL_CORE} ? () : qw(t), 'pod', 'testpods', 'lib', 'Pod') ],
+ -verbose => $VERBOSE }, $searchpod)
|| "undef - $searchpod.pod not found!";
print "### found $result\n";
-if($ENV{PERL_CORE}) {
- $compare = File::Spec->catfile('pod', 'testpods', 'lib', 'Pod' ,'Stuff.pm');
- ok(_canon($result),_canon($compare));
-}
-elsif ($^O eq 'VMS') { # privlib is perl_root:[lib] unfortunately
- $compare = "/lib/pod/perlfunc.pod";
- $result = VMS::Filespec::unixify($result);
- $result =~ s/perl_root\///i;
- $result =~ s/^\.\.//; # needed under `mms test`
- ok($result,$compare);
-}
-else {
- $compare = File::Spec->catfile($Config::Config{privlib},
- ($^O =~ /macos|darwin|cygwin/i ? 'pods' : 'pod'),"perlfunc.pod");
- ok(_canon($result),_canon($compare));
-}
+$compare = File::Spec->catfile(
+ $ENV{PERL_CORE} ? () : qw(t),
+ 'pod', 'testpods', 'lib', 'Pod' ,'Stuff.pm');
+ok(_canon($result),_canon($compare));
# make the path as generic as possible
sub _canon
diff --git a/t/pod/pod2usage2.t b/t/pod/pod2usage2.t
new file mode 100644
index 0000000000..04890f207f
--- /dev/null
+++ b/t/pod/pod2usage2.t
@@ -0,0 +1,178 @@
+#!/usr/bin/perl -w
+
+use Test;
+
+BEGIN {
+ plan tests => 8;
+}
+
+eval "use Pod::Usage";
+
+ok($@ eq '');
+
+sub getoutput
+{
+ my ($code) = @_;
+ my $pid = open(IN, "-|");
+ unless(defined $pid) {
+ die "Cannot fork: $!";
+ }
+ if($pid) {
+ # parent
+ my @out = <IN>;
+ close(IN);
+ my $exit = $?>>8;
+ print "\nEXIT=$exit OUTPUT=+++\n@out+++\n";
+ return($exit, join("",@out));
+ }
+ # child
+ open(STDERR, ">&STDOUT");
+ &$code;
+ print "--NORMAL-RETURN--\n";
+ exit 0;
+}
+
+sub compare
+{
+ my ($left,$right) = @_;
+ $left =~ s/[ \n]+/\n/sg;
+ $right =~ s/[ \n]+/\n/sg;
+ $left =~ s/\s+/ /gm;
+ $right =~ s/\s+/ /gm;
+ $left eq $right;
+}
+
+# test 2
+my ($exit, $text) = getoutput( sub { pod2usage() } );
+ok($exit == 2 && compare($text, <<'EOT'));
+Usage:
+ frobnicate [ -r | --recursive ] [ -f | --force ] [ -n number ] file ...
+
+EOT
+
+# test 3
+($exit, $text) = getoutput( sub { pod2usage(
+ -message => 'You naughty person, what did you say?',
+ -verbose => 1 ) } );
+ok($exit == 1 && compare($text,<<'EOT'));
+You naughty person, what did you say?
+ Usage:
+ frobnicate [ -r | --recursive ] [ -f | --force ] [ -n number ] file ...
+
+ Options:
+ -r | --recursive
+ Run recursively.
+
+ -f | --force
+ Just do it!
+
+ -n number
+ Specify number of frobs, default is 42.
+
+EOT
+
+# test 4
+($exit, $text) = getoutput( sub { pod2usage(
+ -verbose => 2, -exit => 42 ) } );
+ok($exit == 42 && compare($text,<<'EOT'));
+NAME
+ frobnicate - do what I mean
+
+ SYNOPSIS
+ frobnicate [ -r | --recursive ] [ -f | --force ] [ -n number ] file ...
+
+ DESCRIPTION
+ frobnicate does foo and bar and what not.
+
+ OPTIONS
+ -r | --recursive
+ Run recursively.
+
+ -f | --force
+ Just do it!
+
+ -n number
+ Specify number of frobs, default is 42.
+
+EOT
+
+# test 5
+($exit, $text) = getoutput( sub { pod2usage(0) } );
+ok($exit == 0 && compare($text, <<'EOT'));
+Usage:
+ frobnicate [ -r | --recursive ] [ -f | --force ] [ -n number ] file ...
+
+ Options:
+ -r | --recursive
+ Run recursively.
+
+ -f | --force
+ Just do it!
+
+ -n number
+ Specify number of frobs, default is 42.
+
+EOT
+
+# test 6
+($exit, $text) = getoutput( sub { pod2usage(42) } );
+ok($exit == 42 && compare($text, <<'EOT'));
+Usage:
+ frobnicate [ -r | --recursive ] [ -f | --force ] [ -n number ] file ...
+
+EOT
+
+# test 7
+($exit, $text) = getoutput( sub { pod2usage(-verbose => 0, -exit => 'NOEXIT') } );
+ok($exit == 0 && compare($text, <<'EOT'));
+Usage:
+ frobnicate [ -r | --recursive ] [ -f | --force ] [ -n number ] file ...
+
+ --NORMAL-RETURN--
+EOT
+
+# test 8
+($exit, $text) = getoutput( sub { pod2usage(-verbose => 99, -sections => 'DESCRIPTION') } );
+ok($exit == 1 && compare($text, <<'EOT'));
+Description:
+ frobnicate does foo and bar and what not.
+
+EOT
+
+
+
+__END__
+
+=head1 NAME
+
+frobnicate - do what I mean
+
+=head1 SYNOPSIS
+
+B<frobnicate> S<[ B<-r> | B<--recursive> ]> S<[ B<-f> | B<--force> ]>
+ S<[ B<-n> I<number> ]> I<file> ...
+
+=head1 DESCRIPTION
+
+B<frobnicate> does foo and bar and what not.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-r> | B<--recursive>
+
+Run recursively.
+
+=item B<-f> | B<--force>
+
+Just do it!
+
+=item B<-n> I<number>
+
+Specify number of frobs, default is 42.
+
+=back
+
+=cut
+
diff --git a/t/pod/poderrs.xr b/t/pod/poderrs.xr
index a8ef58bfb5..5b40d7a138 100644
--- a/t/pod/poderrs.xr
+++ b/t/pod/poderrs.xr
@@ -17,7 +17,7 @@
*** ERROR: =end without =begin at line 77 in file t/pod/poderrs.t
*** ERROR: No argument for =begin at line 83 in file t/pod/poderrs.t
*** ERROR: =for without formatter specification at line 89 in file t/pod/poderrs.t
-*** ERROR: nested commands C<...C<...>...> at line 95 in file t/pod/poderrs.t
+*** WARNING: nested commands C<...C<...>...> at line 95 in file t/pod/poderrs.t
*** ERROR: garbled entity E<alea iacta est> at line 99 in file t/pod/poderrs.t
*** ERROR: garbled entity E<C<auml>> at line 100 in file t/pod/poderrs.t
*** ERROR: garbled entity E<abcI<bla>> at line 101 in file t/pod/poderrs.t