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