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