Updated for Second Edition.
[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.
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 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 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 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) {
48 die <<EOF;
7eda7aea 49Usage: $0 [-h] [-v] [-t] [-u] [-m] PageName|ModuleName|ProgramName
4633a7c4 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 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 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 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 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 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 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 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 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 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 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 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 215}
216
4633a7c4 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 224} else {
a17cb150 225 require Config;
4633a7c4 226 $tmp = 'Sys$Scratch:perldoc.tmp1_'.$$;
a17cb150 227 @pagers = ($Config::Config{'pager'},qw( most more less type/page ));
85880f03 228 unshift(@pagers,$ENV{PERLDOC_PAGER}) if $ENV{PERLDOC_PAGER};
4633a7c4 229 $goodresult = 1;
230}
231
7eda7aea 232if ($opt_m) {
233 foreach $pager (@pagers) {
234 my($sts) = system("$pager @found");
235 exit 0 if ($Is_VMS ? ($sts & 1) : !$sts);
236 }
237 exit $Is_VMS ? $sts : 1;
238}
239
4633a7c4 240foreach (@found) {
7eda7aea 241
85880f03 242 if($opt_t) {
243 open(TMP,">>$tmp");
244 Pod::Text::pod2text($_,*TMP);
245 close(TMP);
246 } elsif(not $opt_u) {
247 open(TMP,">>$tmp");
40fc7247 248 if($^O =~ /hpux/) {
249 $rslt = `pod2man $_ | nroff -man | col -x`;
250 } else {
251 $rslt = `pod2man $_ | nroff -man`;
252 }
85880f03 253 if ($Is_VMS) { $err = !($? % 2) || $rslt =~ /IVVERB/; }
254 else { $err = $?; }
255 print TMP $rslt unless $err;
256 close TMP;
257 }
4633a7c4 258
85880f03 259 if( $opt_u or $err or -z $tmp) {
4633a7c4 260 open(OUT,">>$tmp");
261 open(IN,"<$_");
85880f03 262 $cut = 1;
263 while (<IN>) {
264 $cut = $1 eq 'cut' if /^=(\w+)/;
265 next if $cut;
266 print OUT;
267 }
4633a7c4 268 close(IN);
269 close(OUT);
270 }
271}
272
273if( $opt_f ) {
274 open(TMP,"<$tmp");
275 print while <TMP>;
276 close(TMP);
277} else {
85880f03 278 foreach $pager (@pagers) {
279 $sts = system("$pager $tmp");
280 last if $Is_VMS && ($sts & 1);
281 last unless $sts;
4633a7c4 282 }
283}
284
2851 while unlink($tmp); #Possibly pointless VMSism
286
287exit 0;
7eda7aea 288
289__END__
290
291=head1 NAME
292
293perldoc - Look up Perl documentation in pod format.
294
295=head1 SYNOPSIS
296
297B<perldoc> [B<-h>] [B<-v>] [B<-t>] [B<-u>] PageName|ModuleName|ProgramName
298
299=head1 DESCRIPTION
300
40fc7247 301I<perldoc> looks up a piece of documentation in .pod format that is embedded
302in the perl installation tree or in a perl script, and displays it via
303C<pod2man | nroff -man | $PAGER>. (In addition, if running under HP-UX,
304C<col -x> will be used.) This is primarily used for the documentation for
305the perl library modules.
7eda7aea 306
307Your system may also have man pages installed for those modules, in
308which case you can probably just use the man(1) command.
309
310=head1 OPTIONS
311
312=over 5
313
314=item B<-h> help
315
316Prints out a brief help message.
317
318=item B<-v> verbose
319
320Describes search for the item in detail.
321
322=item B<-t> text output
323
324Display docs using plain text converter, instead of nroff. This may be faster,
325but it won't look as nice.
326
327=item B<-u> unformatted
328
329Find docs only; skip reformatting by pod2*
330
331=item B<-m> module
332
333Display the entire module: both code and unformatted pod documentation.
334This may be useful if the docs don't explain a function in the detail
335you need, and you'd like to inspect the code directly; perldoc will find
336the file for you and simply hand it off for display.
337
338=item B<PageName|ModuleName|ProgramName>
339
340The item you want to look up. Nested modules (such as C<File::Basename>)
341are specified either as C<File::Basename> or C<File/Basename>. You may also
342give a descriptive name of a page, such as C<perlfunc>. You make also give a
343partial or wrong-case name, such as "basename" for "File::Basename", but
344this will be slower, if there is more then one page with the same partial
345name, you will only get the first one.
346
347=back
348
349=head1 ENVIRONMENT
350
351Any switches in the C<PERLDOC> environment variable will be used before the
352command line arguments. C<perldoc> also searches directories
353specified by the C<PERL5LIB> (or C<PERLLIB> if C<PERL5LIB> is not
354defined) and C<PATH> environment variables.
355(The latter is so that embedded pods for executables, such as
356C<perldoc> itself, are available.)
357
358=head1 AUTHOR
359
360Kenneth Albanowski <kjahds@kjahds.com>
361
362Minor updates by Andy Dougherty <doughera@lafcol.lafayette.edu>
363
364=head1 SEE ALSO
365
366=head1 DIAGNOSTICS
367
368=cut
369
370#
371# Version 1.11: Tue Dec 26 09:54:33 EST 1995
372# Kenneth Albanowski <kjahds@kjahds.com>
373# -added Charles Bailey's further VMS patches, and -u switch
374# -added -t switch, with pod2text support
375#
376# Version 1.10: Thu Nov 9 07:23:47 EST 1995
377# Kenneth Albanowski <kjahds@kjahds.com>
378# -added VMS support
379# -added better error recognition (on no found pages, just exit. On
380# missing nroff/pod2man, just display raw pod.)
381# -added recursive/case-insensitive matching (thanks, Andreas). This
382# slows things down a bit, unfortunately. Give a precise name, and
383# it'll run faster.
384#
385# Version 1.01: Tue May 30 14:47:34 EDT 1995
386# Andy Dougherty <doughera@lafcol.lafayette.edu>
387# -added pod documentation.
388# -added PATH searching.
389# -added searching pod/ subdirectory (mainly to pick up perlfunc.pod
390# and friends.
391#
392#
393# TODO:
394#
395# Cache directories read during sloppy match
4633a7c4 396!NO!SUBS!
397
398close OUT or die "Can't close $file: $!";
399chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
400exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';