This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 5.003_03: [patch introduction and re-organisation]
[perl5.git] / utils / perldoc.PL
CommitLineData
4633a7c4
LW
1#!/usr/local/bin/perl
2
3use Config;
4use File::Basename qw(&basename &dirname);
5
85880f03 6# List explicitly here the variables you want Configure to
7# generate. Metaconfig only looks for shell variables, so you
8# have to mention them as if they were shell variables, not
9# %Config entries. Thus you write
4633a7c4 10# $startperl
85880f03 11# to ensure Configure will look for $Config{startperl}.
4633a7c4
LW
12
13# This forces PL files to create target in same directory as PL file.
14# This is so that make depend always knows where to find PL derivatives.
15chdir(dirname($0));
16($file = basename($0)) =~ s/\.PL$//;
17$file =~ s/\.pl$//
7eda7aea 18 if ($^O eq 'VMS' or $^O eq 'os2'); # "case-forgiving"
4633a7c4
LW
19
20open OUT,">$file" or die "Can't create $file: $!";
21
22print "Extracting $file (with variable substitutions)\n";
23
24# In this section, perl variables will be expanded during extraction.
25# You can use $Config{...} to use Configure variables.
26
85880f03 27print OUT <<"!GROK!THIS!";
4633a7c4
LW
28$Config{'startperl'}
29 eval 'exec perl -S \$0 "\$@"'
30 if 0;
31!GROK!THIS!
32
33# In the following, perl variables are not expanded during extraction.
34
35print OUT <<'!NO!SUBS!';
85880f03 36 eval 'exec perl -S $0 "$@"'
37 if 0;
4633a7c4
LW
38
39#
40# Perldoc revision #1 -- look up a piece of documentation in .pod format that
41# is embedded in the perl installation tree.
42#
43# This is not to be confused with Tom Christianson's perlman, which is a
44# man replacement, written in perl. This perldoc is strictly for reading
45# the perl manuals, though it too is written in perl.
4633a7c4
LW
46
47if(@ARGV<1) {
48 die <<EOF;
7eda7aea 49Usage: $0 [-h] [-v] [-t] [-u] [-m] PageName|ModuleName|ProgramName
4633a7c4
LW
50
51We suggest you use "perldoc perldoc" to get aquainted
52with the system.
53EOF
54}
55
56use Getopt::Std;
7eda7aea 57$Is_VMS = $^O eq 'VMS';
4633a7c4
LW
58
59sub usage{
60 warn "@_\n" if @_;
61 die <<EOF;
85880f03 62perldoc [-h] [-v] [-u] PageName|ModuleName|ProgramName...
4633a7c4 63 -h Display this help message.
85880f03 64 -t Display pod using pod2text instead of pod2man and nroff.
65 -u Display unformatted pod text
7eda7aea 66 -m Display modules file in its entirety
4633a7c4
LW
67 -v Verbosely describe what's going on.
68PageName|ModuleName...
69 is the name of a piece of documentation that you want to look at. You
70 may either give a descriptive name of the page (as in the case of
71 `perlfunc') the name of a module, either like `Term::Info',
72 `Term/Info', the partial name of a module, like `info', or
73 `makemaker', or the name of a program, like `perldoc'.
74
75Any switches in the PERLDOC environment variable will be used before the
76command line arguments.
77
78EOF
79}
80
81use Text::ParseWords;
82
83
84unshift(@ARGV,shellwords($ENV{"PERLDOC"}));
85
7eda7aea 86getopts("mhtuv") || usage;
85880f03 87
88usage if $opt_h || $opt_h; # avoid -w warning
4633a7c4 89
7eda7aea 90usage("only one of -t, -u, or -m") if $opt_t + $opt_u + $opt_m > 1;
4633a7c4 91
7eda7aea 92if ($opt_t) { require Pod::Text; import Pod::Text; }
4633a7c4 93
7eda7aea 94@pages = @ARGV;
85880f03 95
4633a7c4
LW
96sub containspod {
97 my($file) = @_;
98 local($_);
99 open(TEST,"<$file");
100 while(<TEST>) {
101 if(/^=head/) {
102 close(TEST);
103 return 1;
104 }
105 }
106 close(TEST);
107 return 0;
108}
109
110 sub minus_f_nocase {
111 my($file) = @_;
112 local *DIR;
113 local($")="/";
114 my(@p,$p,$cip);
115 foreach $p (split(/\//, $file)){
85880f03 116 if ($Is_VMS and not scalar @p) {
117 # VMS filesystems don't begin at '/'
118 push(@p,$p);
119 next;
120 }
4633a7c4
LW
121 if (-d ("@p/$p")){
122 push @p, $p;
123 } elsif (-f ("@p/$p")) {
124 return "@p/$p";
125 } else {
126 my $found=0;
127 my $lcp = lc $p;
128 opendir DIR, "@p";
129 while ($cip=readdir(DIR)) {
85880f03 130 $cip =~ s/\.dir$// if $Is_VMS;
4633a7c4
LW
131 if (lc $cip eq $lcp){
132 $found++;
133 last;
134 }
135 }
136 closedir DIR;
137 return "" unless $found;
138 push @p, $cip;
139 return "@p" if -f "@p";
140 }
141 }
142 return; # is not a file
143 }
144
145 sub searchfor {
146 my($recurse,$s,@dirs) = @_;
147 $s =~ s!::!/!g;
85880f03 148 $s = VMS::Filespec::unixify($s) if $Is_VMS;
4633a7c4
LW
149 printf STDERR "looking for $s in @dirs\n" if $opt_v;
150 my $ret;
151 my $i;
152 my $dir;
153 for ($i=0;$i<@dirs;$i++) {
154 $dir = $dirs[$i];
85880f03 155 ($dir = VMS::Filespec::unixpath($dir)) =~ s!/$!! if $Is_VMS;
4633a7c4
LW
156 if (( $ret = minus_f_nocase "$dir/$s.pod")
157 or ( $ret = minus_f_nocase "$dir/$s.pm" and containspod($ret))
158 or ( $ret = minus_f_nocase "$dir/$s" and containspod($ret))
85880f03 159 or ( $Is_VMS and
160 $ret = minus_f_nocase "$dir/$s.com" and containspod($ret))
4633a7c4
LW
161 or ( $ret = minus_f_nocase "$dir/pod/$s.pod")
162 or ( $ret = minus_f_nocase "$dir/pod/$s" and containspod($ret)))
163 { return $ret; }
164
165 if($recurse) {
166 opendir(D,$dir);
167 my(@newdirs) = grep(-d,map("$dir/$_",grep(!/^\.\.?$/,readdir(D))));
168 closedir(D);
85880f03 169 @newdirs = map((s/.dir$//,$_)[1],@newdirs) if $Is_VMS;
7eda7aea 170 next unless @newdirs;
4633a7c4
LW
171 print STDERR "Also looking in @newdirs\n" if $opt_v;
172 push(@dirs,@newdirs);
173 }
174 }
175 return ();
176 }
177
178
179foreach (@pages) {
180 print STDERR "Searching for $_\n" if $opt_v;
181 # We must look both in @INC for library modules and in PATH
182 # for executables, like h2xs or perldoc itself.
183 @searchdirs = @INC;
7eda7aea 184 unless ($opt_m) {
185 if ($Is_VMS) {
186 my($i,$trn);
187 for ($i = 0; $trn = $ENV{'DCL$PATH'.$i}; $i++) {
188 push(@searchdirs,$trn);
189 }
190 } else {
191 push(@searchdirs, grep(-d, split(':', $ENV{'PATH'})));
192 }
193 @files= searchfor(0,$_,@searchdirs);
85880f03 194 }
4633a7c4
LW
195 if( @files ) {
196 print STDERR "Found as @files\n" if $opt_v;
197 } else {
198 # no match, try recursive search
199
200 @searchdirs = grep(!/^\.$/,@INC);
201
202
203 @files= searchfor(1,$_,@searchdirs);
204 if( @files ) {
85880f03 205 print STDERR "Loosely found as @files\n" if $opt_v;
4633a7c4
LW
206 } else {
207 print STDERR "No documentation found for '$_'\n";
208 }
209 }
210 push(@found,@files);
211}
212
213if(!@found) {
85880f03 214 exit ($Is_VMS ? 98962 : 1);
4633a7c4
LW
215}
216
4633a7c4
LW
217if( ! -t STDOUT ) { $opt_f = 1 }
218
85880f03 219unless($Is_VMS) {
4633a7c4 220 $tmp = "/tmp/perldoc1.$$";
4633a7c4 221 $goodresult = 0;
85880f03 222 @pagers = qw( more less pg view cat );
223 unshift(@pagers,$ENV{PAGER}) if $ENV{PAGER};
4633a7c4
LW
224} else {
225 $tmp = 'Sys$Scratch:perldoc.tmp1_'.$$;
85880f03 226 @pagers = qw( most more less type/page );
227 unshift(@pagers,$ENV{PERLDOC_PAGER}) if $ENV{PERLDOC_PAGER};
4633a7c4
LW
228 $goodresult = 1;
229}
230
7eda7aea 231if ($opt_m) {
232 foreach $pager (@pagers) {
233 my($sts) = system("$pager @found");
234 exit 0 if ($Is_VMS ? ($sts & 1) : !$sts);
235 }
236 exit $Is_VMS ? $sts : 1;
237}
238
4633a7c4 239foreach (@found) {
7eda7aea 240
85880f03 241 if($opt_t) {
242 open(TMP,">>$tmp");
243 Pod::Text::pod2text($_,*TMP);
244 close(TMP);
245 } elsif(not $opt_u) {
246 open(TMP,">>$tmp");
247 $rslt = `pod2man $_ | nroff -man`;
248 if ($Is_VMS) { $err = !($? % 2) || $rslt =~ /IVVERB/; }
249 else { $err = $?; }
250 print TMP $rslt unless $err;
251 close TMP;
252 }
4633a7c4 253
85880f03 254 if( $opt_u or $err or -z $tmp) {
4633a7c4
LW
255 open(OUT,">>$tmp");
256 open(IN,"<$_");
85880f03 257 $cut = 1;
258 while (<IN>) {
259 $cut = $1 eq 'cut' if /^=(\w+)/;
260 next if $cut;
261 print OUT;
262 }
4633a7c4
LW
263 close(IN);
264 close(OUT);
265 }
266}
267
268if( $opt_f ) {
269 open(TMP,"<$tmp");
270 print while <TMP>;
271 close(TMP);
272} else {
85880f03 273 foreach $pager (@pagers) {
274 $sts = system("$pager $tmp");
275 last if $Is_VMS && ($sts & 1);
276 last unless $sts;
4633a7c4
LW
277 }
278}
279
2801 while unlink($tmp); #Possibly pointless VMSism
281
282exit 0;
7eda7aea 283
284__END__
285
286=head1 NAME
287
288perldoc - Look up Perl documentation in pod format.
289
290=head1 SYNOPSIS
291
292B<perldoc> [B<-h>] [B<-v>] [B<-t>] [B<-u>] PageName|ModuleName|ProgramName
293
294=head1 DESCRIPTION
295
296I<perldoc> looks up a piece of documentation in .pod format that is
297embedded in the perl installation tree or in a perl script, and displays
298it via pod2man | nroff -man | $PAGER. This is primarily used for the
299documentation for the perl library modules.
300
301Your system may also have man pages installed for those modules, in
302which case you can probably just use the man(1) command.
303
304=head1 OPTIONS
305
306=over 5
307
308=item B<-h> help
309
310Prints out a brief help message.
311
312=item B<-v> verbose
313
314Describes search for the item in detail.
315
316=item B<-t> text output
317
318Display docs using plain text converter, instead of nroff. This may be faster,
319but it won't look as nice.
320
321=item B<-u> unformatted
322
323Find docs only; skip reformatting by pod2*
324
325=item B<-m> module
326
327Display the entire module: both code and unformatted pod documentation.
328This may be useful if the docs don't explain a function in the detail
329you need, and you'd like to inspect the code directly; perldoc will find
330the file for you and simply hand it off for display.
331
332=item B<PageName|ModuleName|ProgramName>
333
334The item you want to look up. Nested modules (such as C<File::Basename>)
335are specified either as C<File::Basename> or C<File/Basename>. You may also
336give a descriptive name of a page, such as C<perlfunc>. You make also give a
337partial or wrong-case name, such as "basename" for "File::Basename", but
338this will be slower, if there is more then one page with the same partial
339name, you will only get the first one.
340
341=back
342
343=head1 ENVIRONMENT
344
345Any switches in the C<PERLDOC> environment variable will be used before the
346command line arguments. C<perldoc> also searches directories
347specified by the C<PERL5LIB> (or C<PERLLIB> if C<PERL5LIB> is not
348defined) and C<PATH> environment variables.
349(The latter is so that embedded pods for executables, such as
350C<perldoc> itself, are available.)
351
352=head1 AUTHOR
353
354Kenneth Albanowski <kjahds@kjahds.com>
355
356Minor updates by Andy Dougherty <doughera@lafcol.lafayette.edu>
357
358=head1 SEE ALSO
359
360=head1 DIAGNOSTICS
361
362=cut
363
364#
365# Version 1.11: Tue Dec 26 09:54:33 EST 1995
366# Kenneth Albanowski <kjahds@kjahds.com>
367# -added Charles Bailey's further VMS patches, and -u switch
368# -added -t switch, with pod2text support
369#
370# Version 1.10: Thu Nov 9 07:23:47 EST 1995
371# Kenneth Albanowski <kjahds@kjahds.com>
372# -added VMS support
373# -added better error recognition (on no found pages, just exit. On
374# missing nroff/pod2man, just display raw pod.)
375# -added recursive/case-insensitive matching (thanks, Andreas). This
376# slows things down a bit, unfortunately. Give a precise name, and
377# it'll run faster.
378#
379# Version 1.01: Tue May 30 14:47:34 EDT 1995
380# Andy Dougherty <doughera@lafcol.lafayette.edu>
381# -added pod documentation.
382# -added PATH searching.
383# -added searching pod/ subdirectory (mainly to pick up perlfunc.pod
384# and friends.
385#
386#
387# TODO:
388#
389# Cache directories read during sloppy match
4633a7c4
LW
390!NO!SUBS!
391
392close OUT or die "Can't close $file: $!";
393chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
394exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';