[inseparable changes from patch from perl5.003_26 to perl5.003_27]
[p5sagit/p5-mst-13.2.git] / utils / perldoc.PL
CommitLineData
4633a7c4 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 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 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 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 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 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 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 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 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 83
84BuiltinFunction
85 is the name of a perl function. Will extract documentation from
86 `perlfunc'.
4633a7c4 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 107if ($opt_f) {
108 @pages = ("perlfunc");
109} else {
110 @pages = @ARGV;
111}
112
113
85880f03 114
4633a7c4 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 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 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 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 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 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 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 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 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 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 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 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) {
255 foreach $pager (@pagers) {
256 my($sts) = system("$pager @found");
257 exit 0 if ($Is_VMS ? ($sts & 1) : !$sts);
258 }
259 exit $Is_VMS ? $sts : 1;
260}
261
31bdbec1 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) {
304 open(TMP,">>$tmp");
40fc7247 305 if($^O =~ /hpux/) {
306 $rslt = `pod2man $_ | nroff -man | col -x`;
307 } else {
308 $rslt = `pod2man $_ | nroff -man`;
309 }
85880f03 310 if ($Is_VMS) { $err = !($? % 2) || $rslt =~ /IVVERB/; }
311 else { $err = $?; }
312 print TMP $rslt unless $err;
313 close TMP;
314 }
4633a7c4 315
85880f03 316 if( $opt_u or $err or -z $tmp) {
4633a7c4 317 open(OUT,">>$tmp");
318 open(IN,"<$_");
85880f03 319 $cut = 1;
320 while (<IN>) {
321 $cut = $1 eq 'cut' if /^=(\w+)/;
322 next if $cut;
323 print OUT;
324 }
4633a7c4 325 close(IN);
326 close(OUT);
327 }
328}
329
31bdbec1 330if( $no_tty ) {
4633a7c4 331 open(TMP,"<$tmp");
332 print while <TMP>;
333 close(TMP);
334} else {
85880f03 335 foreach $pager (@pagers) {
336 $sts = system("$pager $tmp");
337 last if $Is_VMS && ($sts & 1);
338 last unless $sts;
4633a7c4 339 }
340}
341
3421 while unlink($tmp); #Possibly pointless VMSism
343
344exit 0;
7eda7aea 345
346__END__
347
348=head1 NAME
349
350perldoc - Look up Perl documentation in pod format.
351
352=head1 SYNOPSIS
353
44a8e56a 354B<perldoc> [B<-h>] [B<-v>] [B<-t>] [B<-u>] [B<-m>] [B<-l>] PageName|ModuleName|ProgramName
7eda7aea 355
31bdbec1 356B<perldoc> B<-f> BuiltinFunction
357
7eda7aea 358=head1 DESCRIPTION
359
40fc7247 360I<perldoc> looks up a piece of documentation in .pod format that is embedded
361in the perl installation tree or in a perl script, and displays it via
362C<pod2man | nroff -man | $PAGER>. (In addition, if running under HP-UX,
363C<col -x> will be used.) This is primarily used for the documentation for
364the perl library modules.
7eda7aea 365
366Your system may also have man pages installed for those modules, in
367which case you can probably just use the man(1) command.
368
369=head1 OPTIONS
370
371=over 5
372
373=item B<-h> help
374
375Prints out a brief help message.
376
377=item B<-v> verbose
378
379Describes search for the item in detail.
380
381=item B<-t> text output
382
383Display docs using plain text converter, instead of nroff. This may be faster,
384but it won't look as nice.
385
386=item B<-u> unformatted
387
388Find docs only; skip reformatting by pod2*
389
390=item B<-m> module
391
392Display the entire module: both code and unformatted pod documentation.
393This may be useful if the docs don't explain a function in the detail
394you need, and you'd like to inspect the code directly; perldoc will find
395the file for you and simply hand it off for display.
396
44a8e56a 397=item B<-l> file name only
398
399Display the file name of the module found.
400
31bdbec1 401=item B<-f> perlfunc
402
403The B<-f> option followed by the name of a perl built in function will
404extract the documentation of this function from L<perlfunc>.
405
7eda7aea 406=item B<PageName|ModuleName|ProgramName>
407
408The item you want to look up. Nested modules (such as C<File::Basename>)
409are specified either as C<File::Basename> or C<File/Basename>. You may also
410give a descriptive name of a page, such as C<perlfunc>. You make also give a
411partial or wrong-case name, such as "basename" for "File::Basename", but
412this will be slower, if there is more then one page with the same partial
413name, you will only get the first one.
414
415=back
416
417=head1 ENVIRONMENT
418
419Any switches in the C<PERLDOC> environment variable will be used before the
420command line arguments. C<perldoc> also searches directories
421specified by the C<PERL5LIB> (or C<PERLLIB> if C<PERL5LIB> is not
422defined) and C<PATH> environment variables.
423(The latter is so that embedded pods for executables, such as
424C<perldoc> itself, are available.)
425
426=head1 AUTHOR
427
428Kenneth Albanowski <kjahds@kjahds.com>
429
430Minor updates by Andy Dougherty <doughera@lafcol.lafayette.edu>
431
7eda7aea 432=cut
433
434#
435# Version 1.11: Tue Dec 26 09:54:33 EST 1995
436# Kenneth Albanowski <kjahds@kjahds.com>
437# -added Charles Bailey's further VMS patches, and -u switch
438# -added -t switch, with pod2text support
439#
440# Version 1.10: Thu Nov 9 07:23:47 EST 1995
441# Kenneth Albanowski <kjahds@kjahds.com>
442# -added VMS support
443# -added better error recognition (on no found pages, just exit. On
444# missing nroff/pod2man, just display raw pod.)
445# -added recursive/case-insensitive matching (thanks, Andreas). This
446# slows things down a bit, unfortunately. Give a precise name, and
447# it'll run faster.
448#
449# Version 1.01: Tue May 30 14:47:34 EDT 1995
450# Andy Dougherty <doughera@lafcol.lafayette.edu>
451# -added pod documentation.
452# -added PATH searching.
453# -added searching pod/ subdirectory (mainly to pick up perlfunc.pod
454# and friends.
455#
456#
457# TODO:
458#
459# Cache directories read during sloppy match
4633a7c4 460!NO!SUBS!
461
462close OUT or die "Can't close $file: $!";
463chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
464exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';