This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: Inline PI function
[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.
44a8e56a 15chdir dirname($0);
16$file = basename($0, '.PL');
774d564b 17$file .= '.com' if $^O eq 'VMS';
4633a7c4
LW
18
19open OUT,">$file" or die "Can't create $file: $!";
20
21print "Extracting $file (with variable substitutions)\n";
22
23# In this section, perl variables will be expanded during extraction.
24# You can use $Config{...} to use Configure variables.
25
85880f03 26print OUT <<"!GROK!THIS!";
5f05dabc 27$Config{startperl}
28 eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
29 if \$running_under_some_shell;
55497cff 30
31\@pagers = ();
32push \@pagers, "$Config{'pager'}" if -x "$Config{'pager'}";
4633a7c4
LW
33!GROK!THIS!
34
35# In the following, perl variables are not expanded during extraction.
36
37print OUT <<'!NO!SUBS!';
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) {
31bdbec1 48 $0 =~ s,.*/,,;
4633a7c4 49 die <<EOF;
44a8e56a 50Usage: $0 [-h] [-v] [-t] [-u] [-m] [-l] PageName|ModuleName|ProgramName
31bdbec1 51 $0 -f PerlFunc
4633a7c4
LW
52
53We suggest you use "perldoc perldoc" to get aquainted
54with the system.
55EOF
56}
57
58use Getopt::Std;
7eda7aea 59$Is_VMS = $^O eq 'VMS';
4633a7c4
LW
60
61sub usage{
ff0cee69 62 warn "@_\n" if @_;
63 # Erase evidence of previous errors (if any), so exit status is simple.
64 $! = 0;
4633a7c4 65 die <<EOF;
31bdbec1
GA
66perldoc [options] PageName|ModuleName|ProgramName...
67perldoc [options] -f BuiltinFunction
68
69Options:
4633a7c4 70 -h Display this help message.
85880f03 71 -t Display pod using pod2text instead of pod2man and nroff.
72 -u Display unformatted pod text
7eda7aea 73 -m Display modules file in its entirety
44a8e56a 74 -l Display the modules file name
4633a7c4 75 -v Verbosely describe what's going on.
31bdbec1 76
4633a7c4
LW
77PageName|ModuleName...
78 is the name of a piece of documentation that you want to look at. You
79 may either give a descriptive name of the page (as in the case of
80 `perlfunc') the name of a module, either like `Term::Info',
81 `Term/Info', the partial name of a module, like `info', or
82 `makemaker', or the name of a program, like `perldoc'.
31bdbec1
GA
83
84BuiltinFunction
85 is the name of a perl function. Will extract documentation from
86 `perlfunc'.
4633a7c4
LW
87
88Any switches in the PERLDOC environment variable will be used before the
89command line arguments.
90
91EOF
92}
93
94use Text::ParseWords;
95
96
97unshift(@ARGV,shellwords($ENV{"PERLDOC"}));
98
31bdbec1 99getopts("mhtluvf:") || usage;
85880f03 100
101usage if $opt_h || $opt_h; # avoid -w warning
4633a7c4 102
44a8e56a 103usage("only one of -t, -u, -m or -l") if $opt_t + $opt_u + $opt_m + $opt_l > 1;
4633a7c4 104
7eda7aea 105if ($opt_t) { require Pod::Text; import Pod::Text; }
4633a7c4 106
31bdbec1
GA
107if ($opt_f) {
108 @pages = ("perlfunc");
109} else {
110 @pages = @ARGV;
111}
112
113
85880f03 114
4633a7c4
LW
115sub containspod {
116 my($file) = @_;
117 local($_);
118 open(TEST,"<$file");
119 while(<TEST>) {
120 if(/^=head/) {
121 close(TEST);
122 return 1;
123 }
124 }
125 close(TEST);
126 return 0;
127}
128
129 sub minus_f_nocase {
130 my($file) = @_;
131 local *DIR;
132 local($")="/";
133 my(@p,$p,$cip);
134 foreach $p (split(/\//, $file)){
9c9e9fb7
KA
135 if (($Is_VMS or $^O eq 'os2') and not scalar @p) {
136 # VMSish filesystems don't begin at '/'
85880f03 137 push(@p,$p);
138 next;
139 }
4633a7c4
LW
140 if (-d ("@p/$p")){
141 push @p, $p;
142 } elsif (-f ("@p/$p")) {
143 return "@p/$p";
144 } else {
145 my $found=0;
146 my $lcp = lc $p;
147 opendir DIR, "@p";
148 while ($cip=readdir(DIR)) {
85880f03 149 $cip =~ s/\.dir$// if $Is_VMS;
4633a7c4
LW
150 if (lc $cip eq $lcp){
151 $found++;
152 last;
153 }
154 }
155 closedir DIR;
156 return "" unless $found;
157 push @p, $cip;
158 return "@p" if -f "@p";
159 }
160 }
161 return; # is not a file
162 }
163
164 sub searchfor {
165 my($recurse,$s,@dirs) = @_;
166 $s =~ s!::!/!g;
85880f03 167 $s = VMS::Filespec::unixify($s) if $Is_VMS;
44a8e56a 168 return $s if -f $s && containspod($s);
4633a7c4
LW
169 printf STDERR "looking for $s in @dirs\n" if $opt_v;
170 my $ret;
171 my $i;
172 my $dir;
173 for ($i=0;$i<@dirs;$i++) {
174 $dir = $dirs[$i];
85880f03 175 ($dir = VMS::Filespec::unixpath($dir)) =~ s!/$!! if $Is_VMS;
4633a7c4
LW
176 if (( $ret = minus_f_nocase "$dir/$s.pod")
177 or ( $ret = minus_f_nocase "$dir/$s.pm" and containspod($ret))
178 or ( $ret = minus_f_nocase "$dir/$s" and containspod($ret))
85880f03 179 or ( $Is_VMS and
180 $ret = minus_f_nocase "$dir/$s.com" and containspod($ret))
4633a7c4
LW
181 or ( $ret = minus_f_nocase "$dir/pod/$s.pod")
182 or ( $ret = minus_f_nocase "$dir/pod/$s" and containspod($ret)))
183 { return $ret; }
184
185 if($recurse) {
186 opendir(D,$dir);
187 my(@newdirs) = grep(-d,map("$dir/$_",grep(!/^\.\.?$/,readdir(D))));
188 closedir(D);
85880f03 189 @newdirs = map((s/.dir$//,$_)[1],@newdirs) if $Is_VMS;
7eda7aea 190 next unless @newdirs;
4633a7c4
LW
191 print STDERR "Also looking in @newdirs\n" if $opt_v;
192 push(@dirs,@newdirs);
193 }
194 }
195 return ();
196 }
197
198
199foreach (@pages) {
200 print STDERR "Searching for $_\n" if $opt_v;
201 # We must look both in @INC for library modules and in PATH
202 # for executables, like h2xs or perldoc itself.
203 @searchdirs = @INC;
7eda7aea 204 unless ($opt_m) {
205 if ($Is_VMS) {
206 my($i,$trn);
207 for ($i = 0; $trn = $ENV{'DCL$PATH'.$i}; $i++) {
208 push(@searchdirs,$trn);
209 }
210 } else {
211 push(@searchdirs, grep(-d, split(':', $ENV{'PATH'})));
212 }
213 @files= searchfor(0,$_,@searchdirs);
85880f03 214 }
4633a7c4
LW
215 if( @files ) {
216 print STDERR "Found as @files\n" if $opt_v;
217 } else {
218 # no match, try recursive search
219
220 @searchdirs = grep(!/^\.$/,@INC);
221
222
223 @files= searchfor(1,$_,@searchdirs);
224 if( @files ) {
85880f03 225 print STDERR "Loosely found as @files\n" if $opt_v;
4633a7c4
LW
226 } else {
227 print STDERR "No documentation found for '$_'\n";
228 }
229 }
230 push(@found,@files);
231}
232
233if(!@found) {
85880f03 234 exit ($Is_VMS ? 98962 : 1);
4633a7c4
LW
235}
236
44a8e56a 237if ($opt_l) {
238 print join("\n", @found), "\n";
239 exit;
240}
241
31bdbec1 242if( ! -t STDOUT ) { $no_tty = 1 }
4633a7c4 243
85880f03 244unless($Is_VMS) {
4633a7c4 245 $tmp = "/tmp/perldoc1.$$";
55497cff 246 push @pagers, qw( more less pg view cat );
247 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
4633a7c4
LW
248} else {
249 $tmp = 'Sys$Scratch:perldoc.tmp1_'.$$;
55497cff 250 push @pagers, qw( most more less type/page );
4633a7c4 251}
44a8e56a 252unshift @pagers, $ENV{PERLDOC_PAGER} if $ENV{PERLDOC_PAGER};
4633a7c4 253
7eda7aea 254if ($opt_m) {
1e422769 255 foreach $pager (@pagers) {
256 system("$pager @found") or exit;
257 }
258 if ($Is_VMS) { eval 'use vmsish qw(status exit); exit $?' }
259 exit 1;
7eda7aea 260}
261
31bdbec1
GA
262if ($opt_f) {
263 my $perlfunc = shift @found;
264 open(PFUNC, $perlfunc) or die "Can't open $perlfunc: $!";
265
266 # Skip introduction
267 while (<PFUNC>) {
268 last if /^=head2 Alphabetical Listing of Perl Functions/;
269 }
270
271 # Look for our function
272 my $found = 0;
273 while (<PFUNC>) {
274 if (/^=item\s+\Q$opt_f\E\b/o) {
275 $found++;
276 } elsif (/^=item/) {
277 last if $found;
278 }
279 push(@pod, $_) if $found;
280 }
281 if (@pod) {
282 if ($opt_t) {
283 open(FORMATTER, "| pod2text") || die "Can't start filter";
284 print FORMATTER "=over 8\n\n";
285 print FORMATTER @pod;
286 print FORMATTER "=back\n";
287 close(FORMATTER);
288 } else {
289 print @pod;
290 }
291 } else {
292 die "No documentation for perl function `$func' found\n";
293 }
294 exit;
295}
296
4633a7c4 297foreach (@found) {
7eda7aea 298
85880f03 299 if($opt_t) {
300 open(TMP,">>$tmp");
301 Pod::Text::pod2text($_,*TMP);
302 close(TMP);
303 } elsif(not $opt_u) {
1e422769 304 my $cmd = "pod2man --lax $_ | nroff -man";
305 $cmd .= " | col -x" if $^O =~ /hpux/;
306 $rslt = `$cmd`;
307 unless(($err = $?)) {
308 open(TMP,">>$tmp");
309 print TMP $rslt;
310 close TMP;
40fc7247 311 }
85880f03 312 }
4633a7c4 313
85880f03 314 if( $opt_u or $err or -z $tmp) {
4633a7c4
LW
315 open(OUT,">>$tmp");
316 open(IN,"<$_");
85880f03 317 $cut = 1;
318 while (<IN>) {
319 $cut = $1 eq 'cut' if /^=(\w+)/;
320 next if $cut;
321 print OUT;
322 }
4633a7c4
LW
323 close(IN);
324 close(OUT);
325 }
326}
327
31bdbec1 328if( $no_tty ) {
4633a7c4
LW
329 open(TMP,"<$tmp");
330 print while <TMP>;
331 close(TMP);
332} else {
85880f03 333 foreach $pager (@pagers) {
1e422769 334 system("$pager $tmp") or last;
4633a7c4
LW
335 }
336}
337
3381 while unlink($tmp); #Possibly pointless VMSism
339
340exit 0;
7eda7aea 341
342__END__
343
344=head1 NAME
345
346perldoc - Look up Perl documentation in pod format.
347
348=head1 SYNOPSIS
349
44a8e56a 350B<perldoc> [B<-h>] [B<-v>] [B<-t>] [B<-u>] [B<-m>] [B<-l>] PageName|ModuleName|ProgramName
7eda7aea 351
31bdbec1
GA
352B<perldoc> B<-f> BuiltinFunction
353
7eda7aea 354=head1 DESCRIPTION
355
40fc7247 356I<perldoc> looks up a piece of documentation in .pod format that is embedded
357in the perl installation tree or in a perl script, and displays it via
358C<pod2man | nroff -man | $PAGER>. (In addition, if running under HP-UX,
359C<col -x> will be used.) This is primarily used for the documentation for
360the perl library modules.
7eda7aea 361
362Your system may also have man pages installed for those modules, in
363which case you can probably just use the man(1) command.
364
365=head1 OPTIONS
366
367=over 5
368
369=item B<-h> help
370
371Prints out a brief help message.
372
373=item B<-v> verbose
374
375Describes search for the item in detail.
376
377=item B<-t> text output
378
379Display docs using plain text converter, instead of nroff. This may be faster,
380but it won't look as nice.
381
382=item B<-u> unformatted
383
384Find docs only; skip reformatting by pod2*
385
386=item B<-m> module
387
388Display the entire module: both code and unformatted pod documentation.
389This may be useful if the docs don't explain a function in the detail
390you need, and you'd like to inspect the code directly; perldoc will find
391the file for you and simply hand it off for display.
392
44a8e56a 393=item B<-l> file name only
394
395Display the file name of the module found.
396
31bdbec1
GA
397=item B<-f> perlfunc
398
399The B<-f> option followed by the name of a perl built in function will
400extract the documentation of this function from L<perlfunc>.
401
7eda7aea 402=item B<PageName|ModuleName|ProgramName>
403
404The item you want to look up. Nested modules (such as C<File::Basename>)
405are specified either as C<File::Basename> or C<File/Basename>. You may also
406give a descriptive name of a page, such as C<perlfunc>. You make also give a
407partial or wrong-case name, such as "basename" for "File::Basename", but
408this will be slower, if there is more then one page with the same partial
409name, you will only get the first one.
410
411=back
412
413=head1 ENVIRONMENT
414
415Any switches in the C<PERLDOC> environment variable will be used before the
416command line arguments. C<perldoc> also searches directories
417specified by the C<PERL5LIB> (or C<PERLLIB> if C<PERL5LIB> is not
418defined) and C<PATH> environment variables.
419(The latter is so that embedded pods for executables, such as
420C<perldoc> itself, are available.)
421
422=head1 AUTHOR
423
424Kenneth Albanowski <kjahds@kjahds.com>
425
426Minor updates by Andy Dougherty <doughera@lafcol.lafayette.edu>
427
7eda7aea 428=cut
429
430#
431# Version 1.11: Tue Dec 26 09:54:33 EST 1995
432# Kenneth Albanowski <kjahds@kjahds.com>
433# -added Charles Bailey's further VMS patches, and -u switch
434# -added -t switch, with pod2text support
435#
436# Version 1.10: Thu Nov 9 07:23:47 EST 1995
437# Kenneth Albanowski <kjahds@kjahds.com>
438# -added VMS support
439# -added better error recognition (on no found pages, just exit. On
440# missing nroff/pod2man, just display raw pod.)
441# -added recursive/case-insensitive matching (thanks, Andreas). This
442# slows things down a bit, unfortunately. Give a precise name, and
443# it'll run faster.
444#
445# Version 1.01: Tue May 30 14:47:34 EDT 1995
446# Andy Dougherty <doughera@lafcol.lafayette.edu>
447# -added pod documentation.
448# -added PATH searching.
449# -added searching pod/ subdirectory (mainly to pick up perlfunc.pod
450# and friends.
451#
452#
453# TODO:
454#
455# Cache directories read during sloppy match
4633a7c4
LW
456!NO!SUBS!
457
458close OUT or die "Can't close $file: $!";
459chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
460exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';