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