This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
reference miscount in Devel::Peek that causes debugger to
[perl5.git] / utils / perldoc.PL
CommitLineData
4633a7c4
LW
1#!/usr/local/bin/perl
2
3use Config;
4use File::Basename qw(&basename &dirname);
8a5546a1 5use Cwd;
4633a7c4 6
85880f03 7# List explicitly here the variables you want Configure to
8# generate. Metaconfig only looks for shell variables, so you
9# have to mention them as if they were shell variables, not
10# %Config entries. Thus you write
4633a7c4 11# $startperl
85880f03 12# to ensure Configure will look for $Config{startperl}.
4633a7c4
LW
13
14# This forces PL files to create target in same directory as PL file.
15# This is so that make depend always knows where to find PL derivatives.
8a5546a1 16$origdir = cwd;
44a8e56a 17chdir dirname($0);
18$file = basename($0, '.PL');
774d564b 19$file .= '.com' if $^O eq 'VMS';
4633a7c4
LW
20
21open OUT,">$file" or die "Can't create $file: $!";
22
23print "Extracting $file (with variable substitutions)\n";
24
25# In this section, perl variables will be expanded during extraction.
26# You can use $Config{...} to use Configure variables.
27
85880f03 28print OUT <<"!GROK!THIS!";
5f05dabc 29$Config{startperl}
30 eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
c5ae3962 31 if 0;
55497cff 32
8167b455 33use warnings;
c5ae3962 34use strict;
8167b455
GS
35
36# make sure creat()s are neither too much nor too little
37INIT { eval { umask(0077) } } # doubtless someone has no mask
38
c5ae3962 39my \@pagers = ();
55497cff 40push \@pagers, "$Config{'pager'}" if -x "$Config{'pager'}";
8167b455 41
4633a7c4
LW
42!GROK!THIS!
43
44# In the following, perl variables are not expanded during extraction.
45
46print OUT <<'!NO!SUBS!';
47
8167b455
GS
48use Fcntl; # for sysopen
49use Getopt::Std;
50use Config '%Config';
51
4633a7c4
LW
52#
53# Perldoc revision #1 -- look up a piece of documentation in .pod format that
54# is embedded in the perl installation tree.
55#
8167b455 56# This is not to be confused with Tom Christiansen's perlman, which is a
4633a7c4
LW
57# man replacement, written in perl. This perldoc is strictly for reading
58# the perl manuals, though it too is written in perl.
8167b455
GS
59#
60# Massive security and correctness patches applied to this
61# noisome program by Tom Christiansen Sat Mar 11 15:22:33 MST 2000
4633a7c4 62
febd60db 63if (@ARGV<1) {
c5ae3962 64 my $me = $0; # Editing $0 is unportable
fb73857a 65 $me =~ s,.*/,,;
4633a7c4 66 die <<EOF;
a85d71bc 67Usage: $me [-h] [-r] [-i] [-v] [-t] [-u] [-m] [-n program] [-l] [-F] [-X] PageName|ModuleName|ProgramName
0b166b66 68 $me -f PerlFunc
a3cb178b 69 $me -q FAQKeywords
4633a7c4 70
89b8affa 71The -h option prints more help. Also try "perldoc perldoc" to get
54884818 72acquainted with the system.
4633a7c4
LW
73EOF
74}
75
c5ae3962
RB
76my @global_found = ();
77my $global_target = "";
fb73857a 78
c5ae3962
RB
79my $Is_VMS = $^O eq 'VMS';
80my $Is_MSWin32 = $^O eq 'MSWin32';
81my $Is_Dos = $^O eq 'dos';
4633a7c4 82
8167b455
GS
83# refuse to run if we should be tainting and aren't
84# (but regular users deserve protection too, though!)
85if (!($Is_VMS || $Is_MSWin32 || $Is_Dos) && ($> == 0 || $< == 0)
86 && !am_taint_checking())
87{
88 die "Superuser must not run $0 without security audit and taint checks.\n";
89}
90
4633a7c4 91sub usage{
ff0cee69 92 warn "@_\n" if @_;
93 # Erase evidence of previous errors (if any), so exit status is simple.
94 $! = 0;
4633a7c4 95 die <<EOF;
31bdbec1
GA
96perldoc [options] PageName|ModuleName|ProgramName...
97perldoc [options] -f BuiltinFunction
a3cb178b 98perldoc [options] -q FAQRegex
31bdbec1
GA
99
100Options:
137443ea 101 -h Display this help message
5315ba28 102 -r Recursive search (slow)
febd60db 103 -i Ignore case
137443ea 104 -t Display pod using pod2text instead of pod2man and nroff
105 (-t is the default on win32)
85880f03 106 -u Display unformatted pod text
a3cb178b 107 -m Display module's file in its entirety
a85d71bc 108 -n Specify replacement for nroff
a3cb178b 109 -l Display the module's file name
cce34969 110 -F Arguments are file names, not modules
137443ea 111 -v Verbosely describe what's going on
89b8affa 112 -X use index if present (looks for pod.idx at $Config{archlib})
54ac30b1 113 -q Search the text of questions (not answers) in perlfaq[1-9]
a3cb178b 114
4633a7c4 115PageName|ModuleName...
febd60db 116 is the name of a piece of documentation that you want to look at. You
4633a7c4 117 may either give a descriptive name of the page (as in the case of
febd60db
GS
118 `perlfunc') the name of a module, either like `Term::Info',
119 `Term/Info', the partial name of a module, like `info', or
4633a7c4 120 `makemaker', or the name of a program, like `perldoc'.
31bdbec1
GA
121
122BuiltinFunction
123 is the name of a perl function. Will extract documentation from
124 `perlfunc'.
a3cb178b
GS
125
126FAQRegex
127 is a regex. Will search perlfaq[1-9] for and extract any
128 questions that match.
129
febd60db 130Any switches in the PERLDOC environment variable will be used before the
89b8affa
GS
131command line arguments. The optional pod index file contains a list of
132filenames, one per line.
4633a7c4
LW
133
134EOF
135}
136
febd60db 137if (defined $ENV{"PERLDOC"}) {
c5ae3962
RB
138 require Text::ParseWords;
139 unshift(@ARGV, Text::ParseWords::shellwords($ENV{"PERLDOC"}));
140}
141!NO!SUBS!
142
a85d71bc 143my $getopts = "mhtluvriFf:Xq:n:";
c5ae3962 144print OUT <<"!GET!OPTS!";
4633a7c4 145
c5ae3962 146use vars qw( @{[map "\$opt_$_", ($getopts =~ /\w/g)]} );
4633a7c4 147
c5ae3962
RB
148getopts("$getopts") || usage;
149!GET!OPTS!
4633a7c4 150
c5ae3962 151print OUT <<'!NO!SUBS!';
85880f03 152
c5ae3962 153usage if $opt_h;
a85d71bc 154$opt_n = "nroff" if !$opt_n;
4633a7c4 155
c5ae3962 156my $podidx;
febd60db 157if ($opt_X) {
0d3da1c8
RB
158 $podidx = "$Config{'archlib'}/pod.idx";
159 $podidx = "" unless -f $podidx && -r _ && -M _ <= 7;
160}
89b8affa 161
8167b455 162if ((my $opts = do{ no warnings; $opt_t + $opt_u + $opt_m + $opt_l }) > 1) {
137443ea 163 usage("only one of -t, -u, -m or -l")
febd60db 164}
d49321e7
GS
165elsif ($Is_MSWin32
166 || $Is_Dos
8167b455 167 || !($ENV{TERM} && $ENV{TERM} !~ /dumb|emacs|none|unknown/i))
d49321e7 168{
8167b455 169 $opt_t = 1 unless $opts;
137443ea 170}
4633a7c4 171
7eda7aea 172if ($opt_t) { require Pod::Text; import Pod::Text; }
4633a7c4 173
c5ae3962 174my @pages;
31bdbec1 175if ($opt_f) {
febd60db
GS
176 @pages = ("perlfunc");
177}
178elsif ($opt_q) {
179 @pages = ("perlfaq1" .. "perlfaq9");
180}
181else {
182 @pages = @ARGV;
31bdbec1
GA
183}
184
fb73857a 185# Does this look like a module or extension directory?
186if (-f "Makefile.PL") {
8167b455
GS
187
188 # Add ., lib to @INC (if they exist)
189 eval q{ use lib qw(. lib); 1; } or die;
190
191 # don't add if superuser
192 if ($< && $>) { # don't be looking too hard now!
193 eval q{ use blib; 1 } or die;
194 }
fb73857a 195}
196
4633a7c4 197sub containspod {
fb73857a 198 my($file, $readit) = @_;
8167b455 199 return 1 if !$readit && $file =~ /\.pod\z/i;
fb73857a 200 local($_);
8167b455 201 open(TEST,"<", $file) or die "Can't open $file: $!";
febd60db
GS
202 while (<TEST>) {
203 if (/^=head/) {
8167b455 204 close(TEST) or die "Can't close $file: $!";
fb73857a 205 return 1;
4633a7c4 206 }
fb73857a 207 }
8167b455 208 close(TEST) or die "Can't close $file: $!";
fb73857a 209 return 0;
4633a7c4
LW
210}
211
84902520 212sub minus_f_nocase {
5315ba28 213 my($dir,$file) = @_;
8167b455 214 my $path = join('/',$dir,$file); # XXX: dirseps
5315ba28
NIS
215 return $path if -f $path and -r _;
216 if (!$opt_i or $Is_VMS or $Is_MSWin32 or $Is_Dos or $^O eq 'os2') {
febd60db 217 # on a case-forgiving file system or if case is important
5315ba28 218 # that is it all we can do
0cf744f2 219 warn "Ignored $path: unreadable\n" if -f _;
fb73857a 220 return '';
84902520 221 }
4633a7c4 222 local *DIR;
8167b455
GS
223 # this is completely wicked. don't mess with $", and if
224 # you do, don't assume / is the dirsep!
4633a7c4 225 local($")="/";
5315ba28
NIS
226 my @p = ($dir);
227 my($p,$cip);
8167b455 228 foreach $p (split(m!/!, $file)){ # XXX: dirseps
fb73857a 229 my $try = "@p/$p";
230 stat $try;
febd60db 231 if (-d _) {
4633a7c4 232 push @p, $p;
fb73857a 233 if ( $p eq $global_target) {
8167b455 234 my $tmp_path = join ('/', @p); # XXX: dirseps
fb73857a 235 my $path_f = 0;
236 for (@global_found) {
237 $path_f = 1 if $_ eq $tmp_path;
238 }
239 push (@global_found, $tmp_path) unless $path_f;
240 print STDERR "Found as @p but directory\n" if $opt_v;
241 }
febd60db
GS
242 }
243 elsif (-f _ && -r _) {
fb73857a 244 return $try;
febd60db
GS
245 }
246 elsif (-f _) {
fb73857a 247 warn "Ignored $try: unreadable\n";
febd60db 248 }
8167b455 249 elsif (-d "@p") {
4633a7c4
LW
250 my $found=0;
251 my $lcp = lc $p;
8167b455 252 opendir DIR, "@p" or die "opendir @p: $!";
4633a7c4
LW
253 while ($cip=readdir(DIR)) {
254 if (lc $cip eq $lcp){
255 $found++;
256 last;
257 }
258 }
8167b455 259 closedir DIR or die "closedir @p: $!";
4633a7c4
LW
260 return "" unless $found;
261 push @p, $cip;
fb73857a 262 return "@p" if -f "@p" and -r _;
0cf744f2 263 warn "Ignored @p: unreadable\n" if -f _;
4633a7c4
LW
264 }
265 }
5315ba28 266 return "";
fb73857a 267}
eb459f90 268
fb73857a 269
270sub check_file {
5315ba28 271 my($dir,$file) = @_;
7ec2cea4 272 return "" if length $dir and not -d $dir;
3046dd9f 273 if ($opt_m) {
5315ba28 274 return minus_f_nocase($dir,$file);
febd60db
GS
275 }
276 else {
5315ba28 277 my $path = minus_f_nocase($dir,$file);
249edfdf 278 return $path if length $path and containspod($path);
3046dd9f 279 }
5315ba28 280 return "";
fb73857a 281}
282
283
284sub searchfor {
285 my($recurse,$s,@dirs) = @_;
286 $s =~ s!::!/!g;
287 $s = VMS::Filespec::unixify($s) if $Is_VMS;
288 return $s if -f $s && containspod($s);
289 printf STDERR "Looking for $s in @dirs\n" if $opt_v;
290 my $ret;
291 my $i;
292 my $dir;
8167b455 293 $global_target = (split(m!/!, $s))[-1]; # XXX: dirseps
fb73857a 294 for ($i=0; $i<@dirs; $i++) {
295 $dir = $dirs[$i];
8167b455 296 ($dir = VMS::Filespec::unixpath($dir)) =~ s!/\z!! if $Is_VMS;
5315ba28
NIS
297 if ( ( $ret = check_file $dir,"$s.pod")
298 or ( $ret = check_file $dir,"$s.pm")
299 or ( $ret = check_file $dir,$s)
fb73857a 300 or ( $Is_VMS and
5315ba28 301 $ret = check_file $dir,"$s.com")
febd60db 302 or ( $^O eq 'os2' and
5315ba28 303 $ret = check_file $dir,"$s.cmd")
0151c6ef 304 or ( ($Is_MSWin32 or $Is_Dos or $^O eq 'os2') and
5315ba28
NIS
305 $ret = check_file $dir,"$s.bat")
306 or ( $ret = check_file "$dir/pod","$s.pod")
307 or ( $ret = check_file "$dir/pod",$s)
7ec2cea4
GS
308 or ( $ret = check_file "$dir/pods","$s.pod")
309 or ( $ret = check_file "$dir/pods",$s)
fb73857a 310 ) {
311 return $ret;
312 }
eb459f90 313
fb73857a 314 if ($recurse) {
8167b455
GS
315 opendir(D,$dir) or die "Can't opendir $dir: $!";
316 my @newdirs = map "$dir/$_", grep { # XXX: dirseps
317 not /^\.\.?\z/s and
318 not /^auto\z/s and # save time! don't search auto dirs
319 -d "$dir/$_" # XXX: dirseps
fb73857a 320 } readdir D;
8167b455 321 closedir(D) or die "Can't closedir $dir: $!";
fb73857a 322 next unless @newdirs;
8167b455
GS
323 # what a wicked map!
324 @newdirs = map((s/\.dir\z//,$_)[1],@newdirs) if $Is_VMS;
fb73857a 325 print STDERR "Also looking in @newdirs\n" if $opt_v;
326 push(@dirs,@newdirs);
327 }
328 }
329 return ();
330}
4633a7c4 331
eb459f90
IZ
332sub filter_nroff {
333 my @data = split /\n{2,}/, shift;
334 shift @data while @data and $data[0] !~ /\S/; # Go to header
335 shift @data if @data and $data[0] =~ /Contributed\s+Perl/; # Skip header
336 pop @data if @data and $data[-1] =~ /^\w/; # Skip footer, like
337 # 28/Jan/99 perl 5.005, patch 53 1
338 join "\n\n", @data;
339}
340
febd60db
GS
341sub printout {
342 my ($file, $tmp, $filter) = @_;
343 my $err;
344
345 if ($opt_t) {
8167b455
GS
346 # why was this append?
347 sysopen(OUT, $tmp, O_WRONLY | O_EXCL | O_CREAT, 0600)
348 or die ("Can't open $tmp: $!");
94e33e97 349 Pod::Text->new()->parse_from_file($file,\*OUT);
8167b455 350 close OUT or die "can't close $tmp: $!";
febd60db
GS
351 }
352 elsif (not $opt_u) {
8167b455 353 my $cmd = "pod2man --lax $file | $opt_n -man";
febd60db
GS
354 $cmd .= " | col -x" if $^O =~ /hpux/;
355 my $rslt = `$cmd`;
356 $rslt = filter_nroff($rslt) if $filter;
357 unless (($err = $?)) {
8167b455
GS
358 # why was this append?
359 sysopen(TMP, $tmp, O_WRONLY | O_EXCL | O_CREAT, 0600)
360 or die "Can't open $tmp: $!";
361 print TMP $rslt
362 or die "Can't print $tmp: $!";
363 close TMP
364 or die "Can't close $tmp: $!";
febd60db
GS
365 }
366 }
8167b455
GS
367 if ($opt_u or $err or -z $tmp) { # XXX: race with -z
368 # why was this append?
369 sysopen(OUT, $tmp, O_WRONLY | O_EXCL | O_CREAT, 0600)
370 or die "Can't open $tmp: $!";
371 open(IN,"<", $file) or die("Can't open $file: $!");
febd60db 372 my $cut = 1;
8167b455 373 local $_;
febd60db
GS
374 while (<IN>) {
375 $cut = $1 eq 'cut' if /^=(\w+)/;
376 next if $cut;
8167b455
GS
377 print OUT
378 or die "Can't print $tmp: $!";
febd60db 379 }
8167b455
GS
380 close IN or die "Can't close $file: $!";
381 close OUT or die "Can't close $tmp: $!";
febd60db
GS
382 }
383}
384
385sub page {
386 my ($tmp, $no_tty, @pagers) = @_;
387 if ($no_tty) {
8167b455
GS
388 open(TMP,"<", $tmp) or die "Can't open $tmp: $!";
389 local $_;
390 while (<TMP>) {
391 print or die "Can't print to stdout: $!";
392 }
393 close TMP or die "Can't close while $tmp: $!";
febd60db
GS
394 }
395 else {
396 foreach my $pager (@pagers) {
8167b455 397 last if system("$pager $tmp") == 0;
febd60db
GS
398 }
399 }
400}
401
402sub cleanup {
403 my @files = @_;
404 for (@files) {
8167b455
GS
405 if ($Is_VMS) {
406 1 while unlink($_); # XXX: expect failure
407 } else {
408 unlink($_); # or die "Can't unlink $_: $!";
409 }
febd60db
GS
410 }
411}
412
c5ae3962 413my @found;
4633a7c4 414foreach (@pages) {
febd60db
GS
415 if ($podidx && open(PODIDX, $podidx)) {
416 my $searchfor = $_;
8167b455 417 $searchfor =~ s,::,/,g; # XXX: dirseps
febd60db 418 print STDERR "Searching for '$searchfor' in $podidx\n" if $opt_v;
8167b455 419 local $_;
febd60db
GS
420 while (<PODIDX>) {
421 chomp;
8167b455 422 push(@found, $_) if m,/$searchfor(?:\.(?:pod|pm))?\z,i;
cce34969 423 }
8167b455 424 close(PODIDX) or die "Can't close $podidx: $!";
febd60db
GS
425 next;
426 }
427 print STDERR "Searching for $_\n" if $opt_v;
428 # We must look both in @INC for library modules and in PATH
429 # for executables, like h2xs or perldoc itself.
430 my @searchdirs = @INC;
431 if ($opt_F) {
432 next unless -r;
433 push @found, $_ if $opt_m or containspod($_);
434 next;
435 }
436 unless ($opt_m) {
437 if ($Is_VMS) {
438 my($i,$trn);
439 for ($i = 0; $trn = $ENV{'DCL$PATH;'.$i}; $i++) {
440 push(@searchdirs,$trn);
7eda7aea 441 }
febd60db
GS
442 push(@searchdirs,'perl_root:[lib.pod]') # installed pods
443 }
444 else {
445 push(@searchdirs, grep(-d, split($Config{path_sep},
446 $ENV{'PATH'})));
85880f03 447 }
febd60db
GS
448 }
449 my @files = searchfor(0,$_,@searchdirs);
450 if (@files) {
451 print STDERR "Found as @files\n" if $opt_v;
452 }
453 else {
454 # no match, try recursive search
8167b455 455 @searchdirs = grep(!/^\.\z/s,@INC);
febd60db
GS
456 @files= searchfor(1,$_,@searchdirs) if $opt_r;
457 if (@files) {
458 print STDERR "Loosely found as @files\n" if $opt_v;
459 }
460 else {
461 print STDERR "No documentation found for \"$_\".\n";
462 if (@global_found) {
463 print STDERR "However, try\n";
464 for my $dir (@global_found) {
8167b455 465 opendir(DIR, $dir) or die "opendir $dir: $!";
febd60db 466 while (my $file = readdir(DIR)) {
8167b455
GS
467 next if ($file =~ /^\./s);
468 $file =~ s/\.(pm|pod)\z//; # XXX: badfs
febd60db
GS
469 print STDERR "\tperldoc $_\::$file\n";
470 }
8167b455 471 closedir DIR or die "closedir $dir: $!";
4633a7c4 472 }
febd60db 473 }
4633a7c4 474 }
febd60db
GS
475 }
476 push(@found,@files);
4633a7c4
LW
477}
478
febd60db
GS
479if (!@found) {
480 exit ($Is_VMS ? 98962 : 1);
4633a7c4
LW
481}
482
44a8e56a 483if ($opt_l) {
484 print join("\n", @found), "\n";
485 exit;
486}
487
877622ba
RB
488my $lines = $ENV{LINES} || 24;
489
c5ae3962 490my $no_tty;
febd60db 491if (! -t STDOUT) { $no_tty = 1 }
8167b455 492END { close(STDOUT) || die "Can't close STDOUT: $!" }
febd60db
GS
493
494# until here we could simply exit or die
495# now we create temporary files that we have to clean up
496# namely $tmp, $buffer
8167b455 497# that's because you did it wrong, should be descriptor based --tchrist
4633a7c4 498
c5ae3962 499my $tmp;
febd60db 500my $buffer;
137443ea 501if ($Is_MSWin32) {
febd60db
GS
502 $tmp = "$ENV{TEMP}\\perldoc1.$$";
503 $buffer = "$ENV{TEMP}\\perldoc1.b$$";
504 push @pagers, qw( more< less notepad );
505 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
506 for (@found) { s,/,\\,g }
507}
508elsif ($Is_VMS) {
509 $tmp = 'Sys$Scratch:perldoc.tmp1_'.$$;
510 $buffer = 'Sys$Scratch:perldoc.tmp1_b'.$$;
511 push @pagers, qw( most more less type/page );
512}
513elsif ($Is_Dos) {
514 $tmp = "$ENV{TEMP}/perldoc1.$$";
515 $buffer = "$ENV{TEMP}/perldoc1.b$$";
516 $tmp =~ tr!\\/!//!s;
517 $buffer =~ tr!\\/!//!s;
518 push @pagers, qw( less.exe more.com< );
519 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
520}
521else {
522 if ($^O eq 'os2') {
523 require POSIX;
524 $tmp = POSIX::tmpnam();
525 $buffer = POSIX::tmpnam();
526 unshift @pagers, 'less', 'cmd /c more <';
527 }
528 else {
8167b455
GS
529 # XXX: this is not secure, because it doesn't open it
530 ($tmp, $buffer) = eval { require POSIX }
531 ? (POSIX::tmpnam(), POSIX::tmpnam() )
532 : ("/tmp/perldoc1.$$", "/tmp/perldoc1.b$$" );
febd60db
GS
533 }
534 push @pagers, qw( more less pg view cat );
535 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
4633a7c4 536}
44a8e56a 537unshift @pagers, $ENV{PERLDOC_PAGER} if $ENV{PERLDOC_PAGER};
4633a7c4 538
8167b455
GS
539# make sure cleanup called
540eval q{
541 sub END { cleanup($tmp, $buffer) }
542 1;
543} || die;
544eval q{ use sigtrap qw(die INT TERM HUP QUIT) };
febd60db 545
7eda7aea 546if ($opt_m) {
febd60db 547 foreach my $pager (@pagers) {
8167b455
GS
548 if (system($pager, @found) == 0) {
549 exit;
550 }
febd60db 551 }
8167b455
GS
552 if ($Is_VMS) {
553 eval q{
554 use vmsish qw(status exit);
555 exit $?;
556 1;
557 } or die;
558 }
559 exit(1);
eb459f90 560}
7eda7aea 561
eb459f90 562my @pod;
31bdbec1 563if ($opt_f) {
febd60db 564 my $perlfunc = shift @found;
8167b455
GS
565 open(PFUNC, "<", $perlfunc)
566 or die("Can't open $perlfunc: $!");
31bdbec1 567
febd60db
GS
568 # Functions like -r, -e, etc. are listed under `-X'.
569 my $search_string = ($opt_f =~ /^-[rwxoRWXOeszfdlpSbctugkTBMAC]$/)
570 ? 'I<-X' : $opt_f ;
a3cb178b 571
febd60db 572 # Skip introduction
8167b455 573 local $_;
febd60db
GS
574 while (<PFUNC>) {
575 last if /^=head2 Alphabetical Listing of Perl Functions/;
576 }
7eda7aea 577
febd60db
GS
578 # Look for our function
579 my $found = 0;
580 my $inlist = 0;
581 while (<PFUNC>) {
582 if (/^=item\s+\Q$search_string\E\b/o) {
583 $found = 1;
85880f03 584 }
febd60db
GS
585 elsif (/^=item/) {
586 last if $found > 1 and not $inlist;
587 }
588 next unless $found;
589 if (/^=over/) {
590 ++$inlist;
591 }
592 elsif (/^=back/) {
593 --$inlist;
4633a7c4 594 }
febd60db
GS
595 push @pod, $_;
596 ++$found if /^\w/; # found descriptive text
597 }
598 if (!@pod) {
599 die "No documentation for perl function `$opt_f' found\n";
600 }
8167b455 601 close PFUNC or die "Can't open $perlfunc: $!";
4633a7c4
LW
602}
603
febd60db
GS
604if ($opt_q) {
605 local @ARGV = @found; # I'm lazy, sue me.
606 my $found = 0;
607 my %found_in;
8167b455 608 my $rx = eval { qr/$opt_q/ } or die <<EOD;
b62b7eeb
GS
609Invalid regular expression '$opt_q' given as -q pattern:
610 $@
611Did you mean \\Q$opt_q ?
612
613EOD
febd60db 614
8167b455
GS
615 for (@found) { die "invalid file spec: $!" if /[<>|]/ }
616 local $_;
febd60db
GS
617 while (<>) {
618 if (/^=head2\s+.*(?:$opt_q)/oi) {
619 $found = 1;
620 push @pod, "=head1 Found in $ARGV\n\n" unless $found_in{$ARGV}++;
4633a7c4 621 }
febd60db
GS
622 elsif (/^=head2/) {
623 $found = 0;
624 }
625 next unless $found;
626 push @pod, $_;
627 }
628 if (!@pod) {
8167b455 629 die("No documentation for perl FAQ keyword `$opt_q' found\n");
febd60db
GS
630 }
631}
632
633my $filter;
634
635if (@pod) {
8167b455
GS
636 sysopen(TMP, $buffer, O_WRONLY | O_EXCL | O_CREAT)
637 or die("Can't open $buffer: $!");
febd60db 638 print TMP "=over 8\n\n";
8167b455 639 print TMP @pod or die "Can't print $buffer: $!";
febd60db 640 print TMP "=back\n";
8167b455 641 close TMP or die "Can't close $buffer: $!";
febd60db
GS
642 @found = $buffer;
643 $filter = 1;
4633a7c4
LW
644}
645
febd60db
GS
646foreach (@found) {
647 printout($_, $tmp, $filter);
eb459f90 648}
febd60db 649page($tmp, $no_tty, @pagers);
4633a7c4 650
8167b455
GS
651exit;
652
653sub is_tainted {
654 my $arg = shift;
655 my $nada = substr($arg, 0, 0); # zero-length
656 local $@; # preserve caller's version
657 eval { eval "# $nada" };
658 return length($@) != 0;
659}
660
661sub am_taint_checking {
662 my($k,$v) = each %ENV;
663 return is_tainted($v);
664}
665
7eda7aea 666
667__END__
668
669=head1 NAME
670
671perldoc - Look up Perl documentation in pod format.
672
673=head1 SYNOPSIS
674
89b8affa 675B<perldoc> [B<-h>] [B<-v>] [B<-t>] [B<-u>] [B<-m>] [B<-l>] [B<-F>] [B<-X>] PageName|ModuleName|ProgramName
7eda7aea 676
31bdbec1
GA
677B<perldoc> B<-f> BuiltinFunction
678
c8950503
DG
679B<perldoc> B<-q> FAQ Keyword
680
7eda7aea 681=head1 DESCRIPTION
682
40fc7247 683I<perldoc> looks up a piece of documentation in .pod format that is embedded
684in the perl installation tree or in a perl script, and displays it via
685C<pod2man | nroff -man | $PAGER>. (In addition, if running under HP-UX,
686C<col -x> will be used.) This is primarily used for the documentation for
687the perl library modules.
7eda7aea 688
689Your system may also have man pages installed for those modules, in
690which case you can probably just use the man(1) command.
691
692=head1 OPTIONS
693
694=over 5
695
696=item B<-h> help
697
698Prints out a brief help message.
699
700=item B<-v> verbose
701
702Describes search for the item in detail.
703
704=item B<-t> text output
705
706Display docs using plain text converter, instead of nroff. This may be faster,
707but it won't look as nice.
708
709=item B<-u> unformatted
710
711Find docs only; skip reformatting by pod2*
712
713=item B<-m> module
714
715Display the entire module: both code and unformatted pod documentation.
716This may be useful if the docs don't explain a function in the detail
717you need, and you'd like to inspect the code directly; perldoc will find
718the file for you and simply hand it off for display.
719
44a8e56a 720=item B<-l> file name only
721
722Display the file name of the module found.
723
cce34969
IZ
724=item B<-F> file names
725
89b8affa 726Consider arguments as file names, no search in directories will be performed.
cce34969 727
31bdbec1
GA
728=item B<-f> perlfunc
729
730The B<-f> option followed by the name of a perl built in function will
731extract the documentation of this function from L<perlfunc>.
732
c8950503
DG
733=item B<-q> perlfaq
734
735The B<-q> option takes a regular expression as an argument. It will search
736the question headings in perlfaq[1-9] and print the entries matching
737the regular expression.
738
89b8affa
GS
739=item B<-X> use an index if present
740
741The B<-X> option looks for a entry whose basename matches the name given on the
742command line in the file C<$Config{archlib}/pod.idx>. The pod.idx file should
743contain fully qualified filenames, one per line.
744
7eda7aea 745=item B<PageName|ModuleName|ProgramName>
746
747The item you want to look up. Nested modules (such as C<File::Basename>)
748are specified either as C<File::Basename> or C<File/Basename>. You may also
1b420867 749give a descriptive name of a page, such as C<perlfunc>. You may also give a
7eda7aea 750partial or wrong-case name, such as "basename" for "File::Basename", but
751this will be slower, if there is more then one page with the same partial
752name, you will only get the first one.
753
754=back
755
756=head1 ENVIRONMENT
757
febd60db 758Any switches in the C<PERLDOC> environment variable will be used before the
7eda7aea 759command line arguments. C<perldoc> also searches directories
760specified by the C<PERL5LIB> (or C<PERLLIB> if C<PERL5LIB> is not
761defined) and C<PATH> environment variables.
762(The latter is so that embedded pods for executables, such as
a3cb178b
GS
763C<perldoc> itself, are available.) C<perldoc> will use, in order of
764preference, the pager defined in C<PERLDOC_PAGER>, C<MANPAGER>, or
765C<PAGER> before trying to find a pager on its own. (C<MANPAGER> is not
766used if C<perldoc> was told to display plain text or unformatted pod.)
7eda7aea 767
eb459f90
IZ
768One useful value for C<PERLDOC_PAGER> is C<less -+C -E>.
769
febd60db
GS
770=head1 VERSION
771
8167b455 772This is perldoc v2.01.
febd60db 773
7eda7aea 774=head1 AUTHOR
775
776Kenneth Albanowski <kjahds@kjahds.com>
777
febd60db
GS
778Minor updates by Andy Dougherty <doughera@lafcol.lafayette.edu>,
779and others.
7eda7aea 780
7eda7aea 781=cut
782
783#
8167b455
GS
784# Version 2.01: Sat Mar 11 15:22:33 MST 2000
785# Tom Christiansen <tchrist@perl.com>, querulously.
786# Security and correctness patches.
787# What a twisted bit of distasteful spaghetti code.
788# Version 2.0: ????
7ec2cea4
GS
789# Version 1.15: Tue Aug 24 01:50:20 EST 1999
790# Charles Wilson <cwilson@ece.gatech.edu>
791# changed /pod/ directory to /pods/ for cygwin
792# to support cygwin/win32
c5ae3962
RB
793# Version 1.14: Wed Jul 15 01:50:20 EST 1998
794# Robin Barker <rmb1@cise.npl.co.uk>
795# -strict, -w cleanups
89b8affa 796# Version 1.13: Fri Feb 27 16:20:50 EST 1997
6e238990 797# Gurusamy Sarathy <gsar@activestate.com>
89b8affa 798# -doc tweaks for -F and -X options
137443ea 799# Version 1.12: Sat Apr 12 22:41:09 EST 1997
6e238990 800# Gurusamy Sarathy <gsar@activestate.com>
137443ea 801# -various fixes for win32
7eda7aea 802# Version 1.11: Tue Dec 26 09:54:33 EST 1995
803# Kenneth Albanowski <kjahds@kjahds.com>
804# -added Charles Bailey's further VMS patches, and -u switch
805# -added -t switch, with pod2text support
febd60db 806#
7eda7aea 807# Version 1.10: Thu Nov 9 07:23:47 EST 1995
808# Kenneth Albanowski <kjahds@kjahds.com>
809# -added VMS support
810# -added better error recognition (on no found pages, just exit. On
811# missing nroff/pod2man, just display raw pod.)
812# -added recursive/case-insensitive matching (thanks, Andreas). This
813# slows things down a bit, unfortunately. Give a precise name, and
814# it'll run faster.
815#
816# Version 1.01: Tue May 30 14:47:34 EDT 1995
817# Andy Dougherty <doughera@lafcol.lafayette.edu>
818# -added pod documentation.
819# -added PATH searching.
820# -added searching pod/ subdirectory (mainly to pick up perlfunc.pod
821# and friends.
822#
823#
824# TODO:
825#
826# Cache directories read during sloppy match
4633a7c4
LW
827!NO!SUBS!
828
829close OUT or die "Can't close $file: $!";
830chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
831exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
8a5546a1 832chdir $origdir;