Be clean.
[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 = ();
ed6d8ea1 45push \@pagers, \$pager if -x \$pager;
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';
4633a7c4 97
98sub usage{
ff0cee69 99 warn "@_\n" if @_;
100 # Erase evidence of previous errors (if any), so exit status is simple.
101 $! = 0;
4633a7c4 102 die <<EOF;
31bdbec1 103perldoc [options] PageName|ModuleName|ProgramName...
104perldoc [options] -f BuiltinFunction
a3cb178b 105perldoc [options] -q FAQRegex
31bdbec1 106
107Options:
137443ea 108 -h Display this help message
5315ba28 109 -r Recursive search (slow)
febd60db 110 -i Ignore case
137443ea 111 -t Display pod using pod2text instead of pod2man and nroff
112 (-t is the default on win32)
85880f03 113 -u Display unformatted pod text
a3cb178b 114 -m Display module's file in its entirety
a85d71bc 115 -n Specify replacement for nroff
a3cb178b 116 -l Display the module's file name
cce34969 117 -F Arguments are file names, not modules
137443ea 118 -v Verbosely describe what's going on
89b8affa 119 -X use index if present (looks for pod.idx at $Config{archlib})
54ac30b1 120 -q Search the text of questions (not answers) in perlfaq[1-9]
c185d8c4 121 -U Run in insecure mode (superuser only)
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
febd60db 126 `perlfunc') the name of a module, either like `Term::Info',
127 `Term/Info', the partial name of a module, like `info', or
4633a7c4 128 `makemaker', or the name of a program, like `perldoc'.
31bdbec1 129
130BuiltinFunction
131 is the name of a perl function. Will extract documentation from
132 `perlfunc'.
a3cb178b 133
134FAQRegex
135 is a regex. Will search perlfaq[1-9] for and extract any
136 questions that match.
137
febd60db 138Any switches in the PERLDOC environment variable will be used before the
89b8affa 139command line arguments. The optional pod index file contains a list of
140filenames, one per line.
4633a7c4 141
142EOF
143}
144
febd60db 145if (defined $ENV{"PERLDOC"}) {
c5ae3962 146 require Text::ParseWords;
147 unshift(@ARGV, Text::ParseWords::shellwords($ENV{"PERLDOC"}));
148}
149!NO!SUBS!
150
c185d8c4 151my $getopts = "mhtluvriFf:Xq:n:U";
c5ae3962 152print OUT <<"!GET!OPTS!";
4633a7c4 153
c5ae3962 154use vars qw( @{[map "\$opt_$_", ($getopts =~ /\w/g)]} );
4633a7c4 155
c5ae3962 156getopts("$getopts") || usage;
157!GET!OPTS!
4633a7c4 158
c5ae3962 159print OUT <<'!NO!SUBS!';
85880f03 160
c5ae3962 161usage if $opt_h;
c185d8c4 162
163# refuse to run if we should be tainting and aren't
164# (but regular users deserve protection too, though!)
6dbadf30 165if (!($Is_VMS || $Is_MSWin32 || $Is_Dos || $Is_OS2) && ($> == 0 || $< == 0)
c185d8c4 166 && !am_taint_checking())
167{{
168 if ($opt_U) {
169 my $id = eval { getpwnam("nobody") };
170 $id = eval { getpwnam("nouser") } unless defined $id;
171 $id = -2 unless defined $id;
c8d2171d 172 #
173 # According to Stevens' APUE and various
174 # (BSD, Solaris, HP-UX) man pages setting
175 # the real uid first and effective uid second
176 # is the way to go if one wants to drop privileges,
177 # because if one changes into an effective uid of
178 # non-zero, one cannot change the real uid any more.
179 #
180 # Actually, it gets even messier. There is
181 # a third uid, called the saved uid, and as
182 # long as that is zero, one can get back to
183 # uid of zero. Setting the real-effective *twice*
184 # helps in *most* systems (FreeBSD and Solaris)
185 # but apparently in HP-UX even this doesn't help:
186 # the saved uid stays zero (apparently the only way
187 # in HP-UX to change saved uid is to call setuid()
188 # when the effective uid is zero).
189 #
c185d8c4 190 eval {
c8d2171d 191 $< = $id; # real uid
192 $> = $id; # effective uid
996aae18 193 $< = $id; # real uid
194 $> = $id; # effective uid
c185d8c4 195 };
196 last if !$@ && $< && $>;
197 }
198 die "Superuser must not run $0 without security audit and taint checks.\n";
199}}
200
a85d71bc 201$opt_n = "nroff" if !$opt_n;
4633a7c4 202
c5ae3962 203my $podidx;
febd60db 204if ($opt_X) {
0d3da1c8 205 $podidx = "$Config{'archlib'}/pod.idx";
206 $podidx = "" unless -f $podidx && -r _ && -M _ <= 7;
207}
89b8affa 208
8167b455 209if ((my $opts = do{ no warnings; $opt_t + $opt_u + $opt_m + $opt_l }) > 1) {
137443ea 210 usage("only one of -t, -u, -m or -l")
febd60db 211}
d49321e7 212elsif ($Is_MSWin32
213 || $Is_Dos
8167b455 214 || !($ENV{TERM} && $ENV{TERM} !~ /dumb|emacs|none|unknown/i))
d49321e7 215{
8167b455 216 $opt_t = 1 unless $opts;
137443ea 217}
4633a7c4 218
7eda7aea 219if ($opt_t) { require Pod::Text; import Pod::Text; }
4633a7c4 220
c5ae3962 221my @pages;
31bdbec1 222if ($opt_f) {
febd60db 223 @pages = ("perlfunc");
224}
225elsif ($opt_q) {
226 @pages = ("perlfaq1" .. "perlfaq9");
227}
228else {
229 @pages = @ARGV;
31bdbec1 230}
231
fb73857a 232# Does this look like a module or extension directory?
233if (-f "Makefile.PL") {
8167b455 234
235 # Add ., lib to @INC (if they exist)
236 eval q{ use lib qw(. lib); 1; } or die;
237
238 # don't add if superuser
aafed681 239 if ($< && $> && -f "blib") { # don't be looking too hard now!
6d0835e5 240 eval q{ use blib; 1 };
241 warn $@ if $@ && $opt_v;
8167b455 242 }
fb73857a 243}
244
4633a7c4 245sub containspod {
fb73857a 246 my($file, $readit) = @_;
8167b455 247 return 1 if !$readit && $file =~ /\.pod\z/i;
fb73857a 248 local($_);
8167b455 249 open(TEST,"<", $file) or die "Can't open $file: $!";
febd60db 250 while (<TEST>) {
251 if (/^=head/) {
8167b455 252 close(TEST) or die "Can't close $file: $!";
fb73857a 253 return 1;
4633a7c4 254 }
fb73857a 255 }
8167b455 256 close(TEST) or die "Can't close $file: $!";
fb73857a 257 return 0;
4633a7c4 258}
259
84902520 260sub minus_f_nocase {
5315ba28 261 my($dir,$file) = @_;
14178d34 262 my $path = catfile($dir,$file);
5315ba28 263 return $path if -f $path and -r _;
264 if (!$opt_i or $Is_VMS or $Is_MSWin32 or $Is_Dos or $^O eq 'os2') {
febd60db 265 # on a case-forgiving file system or if case is important
5315ba28 266 # that is it all we can do
0cf744f2 267 warn "Ignored $path: unreadable\n" if -f _;
fb73857a 268 return '';
84902520 269 }
4633a7c4 270 local *DIR;
8167b455 271 # this is completely wicked. don't mess with $", and if
272 # you do, don't assume / is the dirsep!
4633a7c4 273 local($")="/";
5315ba28 274 my @p = ($dir);
275 my($p,$cip);
14178d34 276 foreach $p (splitdir $file){
277 my $try = catfile @p, $p;
fb73857a 278 stat $try;
febd60db 279 if (-d _) {
4633a7c4 280 push @p, $p;
fb73857a 281 if ( $p eq $global_target) {
14178d34 282 my $tmp_path = catfile @p;
fb73857a 283 my $path_f = 0;
284 for (@global_found) {
285 $path_f = 1 if $_ eq $tmp_path;
286 }
287 push (@global_found, $tmp_path) unless $path_f;
288 print STDERR "Found as @p but directory\n" if $opt_v;
289 }
febd60db 290 }
291 elsif (-f _ && -r _) {
fb73857a 292 return $try;
febd60db 293 }
294 elsif (-f _) {
fb73857a 295 warn "Ignored $try: unreadable\n";
febd60db 296 }
8167b455 297 elsif (-d "@p") {
4633a7c4 298 my $found=0;
299 my $lcp = lc $p;
8167b455 300 opendir DIR, "@p" or die "opendir @p: $!";
4633a7c4 301 while ($cip=readdir(DIR)) {
302 if (lc $cip eq $lcp){
303 $found++;
304 last;
305 }
306 }
8167b455 307 closedir DIR or die "closedir @p: $!";
4633a7c4 308 return "" unless $found;
309 push @p, $cip;
fb73857a 310 return "@p" if -f "@p" and -r _;
0cf744f2 311 warn "Ignored @p: unreadable\n" if -f _;
4633a7c4 312 }
313 }
5315ba28 314 return "";
fb73857a 315}
eb459f90 316
fb73857a 317
318sub check_file {
5315ba28 319 my($dir,$file) = @_;
7ec2cea4 320 return "" if length $dir and not -d $dir;
3046dd9f 321 if ($opt_m) {
5315ba28 322 return minus_f_nocase($dir,$file);
febd60db 323 }
324 else {
5315ba28 325 my $path = minus_f_nocase($dir,$file);
249edfdf 326 return $path if length $path and containspod($path);
3046dd9f 327 }
5315ba28 328 return "";
fb73857a 329}
330
331
332sub searchfor {
333 my($recurse,$s,@dirs) = @_;
334 $s =~ s!::!/!g;
335 $s = VMS::Filespec::unixify($s) if $Is_VMS;
336 return $s if -f $s && containspod($s);
337 printf STDERR "Looking for $s in @dirs\n" if $opt_v;
338 my $ret;
339 my $i;
340 my $dir;
14178d34 341 $global_target = (splitdir $s)[-1]; # XXX: why not use File::Basename?
fb73857a 342 for ($i=0; $i<@dirs; $i++) {
343 $dir = $dirs[$i];
8167b455 344 ($dir = VMS::Filespec::unixpath($dir)) =~ s!/\z!! if $Is_VMS;
f1cdc2b6 345 if ( (! $opt_m && ( $ret = check_file $dir,"$s.pod"))
5315ba28 346 or ( $ret = check_file $dir,"$s.pm")
347 or ( $ret = check_file $dir,$s)
fb73857a 348 or ( $Is_VMS and
5315ba28 349 $ret = check_file $dir,"$s.com")
febd60db 350 or ( $^O eq 'os2' and
5315ba28 351 $ret = check_file $dir,"$s.cmd")
0151c6ef 352 or ( ($Is_MSWin32 or $Is_Dos or $^O eq 'os2') and
5315ba28 353 $ret = check_file $dir,"$s.bat")
354 or ( $ret = check_file "$dir/pod","$s.pod")
355 or ( $ret = check_file "$dir/pod",$s)
7ec2cea4 356 or ( $ret = check_file "$dir/pods","$s.pod")
357 or ( $ret = check_file "$dir/pods",$s)
fb73857a 358 ) {
359 return $ret;
360 }
eb459f90 361
fb73857a 362 if ($recurse) {
8167b455 363 opendir(D,$dir) or die "Can't opendir $dir: $!";
14178d34 364 my @newdirs = map catfile($dir, $_), grep {
8167b455 365 not /^\.\.?\z/s and
366 not /^auto\z/s and # save time! don't search auto dirs
14178d34 367 -d catfile($dir, $_)
fb73857a 368 } readdir D;
8167b455 369 closedir(D) or die "Can't closedir $dir: $!";
fb73857a 370 next unless @newdirs;
8167b455 371 # what a wicked map!
372 @newdirs = map((s/\.dir\z//,$_)[1],@newdirs) if $Is_VMS;
fb73857a 373 print STDERR "Also looking in @newdirs\n" if $opt_v;
374 push(@dirs,@newdirs);
375 }
376 }
377 return ();
378}
4633a7c4 379
eb459f90 380sub filter_nroff {
381 my @data = split /\n{2,}/, shift;
382 shift @data while @data and $data[0] !~ /\S/; # Go to header
383 shift @data if @data and $data[0] =~ /Contributed\s+Perl/; # Skip header
384 pop @data if @data and $data[-1] =~ /^\w/; # Skip footer, like
385 # 28/Jan/99 perl 5.005, patch 53 1
386 join "\n\n", @data;
387}
388
febd60db 389sub page {
390 my ($tmp, $no_tty, @pagers) = @_;
391 if ($no_tty) {
8167b455 392 open(TMP,"<", $tmp) or die "Can't open $tmp: $!";
393 local $_;
394 while (<TMP>) {
395 print or die "Can't print to stdout: $!";
396 }
397 close TMP or die "Can't close while $tmp: $!";
febd60db 398 }
399 else {
f3298698 400 # On VMS, quoting prevents logical expansion, and temp files with no
401 # extension get the wrong default extension (such as .LIS for TYPE)
402
403 $tmp = VMS::Filespec::rmsexpand($tmp, '.') if ($Is_VMS);
404 foreach my $pager (@pagers) {
e0d5f7b4 405 if ($Is_VMS) {
f3298698 406 last if system("$pager $tmp") == 0;
e0d5f7b4 407 } else {
a79ff105 408 last if system("$pager \"$tmp\"") == 0;
e0d5f7b4 409 }
febd60db 410 }
411 }
412}
413
c5ae3962 414my @found;
4633a7c4 415foreach (@pages) {
febd60db 416 if ($podidx && open(PODIDX, $podidx)) {
14178d34 417 my $searchfor = catfile split '::';
febd60db 418 print STDERR "Searching for '$searchfor' in $podidx\n" if $opt_v;
8167b455 419 local $_;
febd60db 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 425 next;
426 }
427 print STDERR "Searching for $_\n" if $opt_v;
febd60db 428 if ($opt_F) {
429 next unless -r;
430 push @found, $_ if $opt_m or containspod($_);
431 next;
432 }
6a43d2f9 433 # We must look both in @INC for library modules and in $bindir
434 # for executables, like h2xs or perldoc itself.
435 my @searchdirs = ($bindir, @INC);
febd60db 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 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 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 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 {
f1cdc2b6 461 print STDERR "No " .
462 ($opt_m ? "module" : "documentation") . " found for \"$_\".\n";
febd60db 463 if (@global_found) {
464 print STDERR "However, try\n";
465 for my $dir (@global_found) {
8167b455 466 opendir(DIR, $dir) or die "opendir $dir: $!";
febd60db 467 while (my $file = readdir(DIR)) {
8167b455 468 next if ($file =~ /^\./s);
469 $file =~ s/\.(pm|pod)\z//; # XXX: badfs
febd60db 470 print STDERR "\tperldoc $_\::$file\n";
471 }
8167b455 472 closedir DIR or die "closedir $dir: $!";
4633a7c4 473 }
febd60db 474 }
4633a7c4 475 }
febd60db 476 }
477 push(@found,@files);
4633a7c4 478}
479
febd60db 480if (!@found) {
481 exit ($Is_VMS ? 98962 : 1);
4633a7c4 482}
483
44a8e56a 484if ($opt_l) {
485 print join("\n", @found), "\n";
486 exit;
487}
488
877622ba 489my $lines = $ENV{LINES} || 24;
490
c5ae3962 491my $no_tty;
febd60db 492if (! -t STDOUT) { $no_tty = 1 }
8167b455 493END { close(STDOUT) || die "Can't close STDOUT: $!" }
febd60db 494
137443ea 495if ($Is_MSWin32) {
febd60db 496 push @pagers, qw( more< less notepad );
497 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
498 for (@found) { s,/,\\,g }
499}
500elsif ($Is_VMS) {
febd60db 501 push @pagers, qw( most more less type/page );
502}
503elsif ($Is_Dos) {
febd60db 504 push @pagers, qw( less.exe more.com< );
505 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
506}
507else {
508 if ($^O eq 'os2') {
febd60db 509 unshift @pagers, 'less', 'cmd /c more <';
510 }
febd60db 511 push @pagers, qw( more less pg view cat );
512 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
4633a7c4 513}
44a8e56a 514unshift @pagers, $ENV{PERLDOC_PAGER} if $ENV{PERLDOC_PAGER};
4633a7c4 515
7eda7aea 516if ($opt_m) {
febd60db 517 foreach my $pager (@pagers) {
8167b455 518 if (system($pager, @found) == 0) {
519 exit;
520 }
febd60db 521 }
8167b455 522 if ($Is_VMS) {
523 eval q{
524 use vmsish qw(status exit);
525 exit $?;
526 1;
527 } or die;
528 }
529 exit(1);
eb459f90 530}
7eda7aea 531
eb459f90 532my @pod;
31bdbec1 533if ($opt_f) {
febd60db 534 my $perlfunc = shift @found;
8167b455 535 open(PFUNC, "<", $perlfunc)
536 or die("Can't open $perlfunc: $!");
31bdbec1 537
febd60db 538 # Functions like -r, -e, etc. are listed under `-X'.
539 my $search_string = ($opt_f =~ /^-[rwxoRWXOeszfdlpSbctugkTBMAC]$/)
540 ? 'I<-X' : $opt_f ;
a3cb178b 541
febd60db 542 # Skip introduction
8167b455 543 local $_;
febd60db 544 while (<PFUNC>) {
545 last if /^=head2 Alphabetical Listing of Perl Functions/;
546 }
7eda7aea 547
febd60db 548 # Look for our function
549 my $found = 0;
550 my $inlist = 0;
551 while (<PFUNC>) {
552 if (/^=item\s+\Q$search_string\E\b/o) {
553 $found = 1;
85880f03 554 }
febd60db 555 elsif (/^=item/) {
556 last if $found > 1 and not $inlist;
557 }
558 next unless $found;
559 if (/^=over/) {
560 ++$inlist;
561 }
562 elsif (/^=back/) {
563 --$inlist;
4633a7c4 564 }
febd60db 565 push @pod, $_;
566 ++$found if /^\w/; # found descriptive text
567 }
568 if (!@pod) {
569 die "No documentation for perl function `$opt_f' found\n";
570 }
8167b455 571 close PFUNC or die "Can't open $perlfunc: $!";
4633a7c4 572}
573
febd60db 574if ($opt_q) {
575 local @ARGV = @found; # I'm lazy, sue me.
576 my $found = 0;
577 my %found_in;
8167b455 578 my $rx = eval { qr/$opt_q/ } or die <<EOD;
b62b7eeb 579Invalid regular expression '$opt_q' given as -q pattern:
580 $@
581Did you mean \\Q$opt_q ?
582
583EOD
febd60db 584
8167b455 585 for (@found) { die "invalid file spec: $!" if /[<>|]/ }
586 local $_;
febd60db 587 while (<>) {
588 if (/^=head2\s+.*(?:$opt_q)/oi) {
589 $found = 1;
590 push @pod, "=head1 Found in $ARGV\n\n" unless $found_in{$ARGV}++;
4633a7c4 591 }
a5396746 592 elsif (/^=head[12]/) {
febd60db 593 $found = 0;
594 }
595 next unless $found;
596 push @pod, $_;
597 }
598 if (!@pod) {
8167b455 599 die("No documentation for perl FAQ keyword `$opt_q' found\n");
febd60db 600 }
601}
602
6a43d2f9 603require File::Temp;
604
008d9c33 605my ($tmpfd, $tmp) = File::Temp::tempfile(UNLINK => 1);
6a43d2f9 606
febd60db 607my $filter;
608
609if (@pod) {
008d9c33 610 my ($buffd, $buffer) = File::Temp::tempfile(UNLINK => 1);
6a43d2f9 611 print $buffd "=over 8\n\n";
612 print $buffd @pod or die "Can't print $buffer: $!";
613 print $buffd "=back\n";
614 close $buffd or die "Can't close $buffer: $!";
febd60db 615 @found = $buffer;
616 $filter = 1;
4633a7c4 617}
618
febd60db 619foreach (@found) {
6a43d2f9 620 my $file = $_;
621 my $err;
622
623 if ($opt_t) {
624 Pod::Text->new()->parse_from_file($file, $tmpfd);
625 }
626 elsif (not $opt_u) {
c6a5b0b7 627 my $cmd = catfile($bindir, $pod2man) . " --lax $file | $opt_n -man";
6a43d2f9 628 $cmd .= " | col -x" if $^O =~ /hpux/;
629 my $rslt = `$cmd`;
630 $rslt = filter_nroff($rslt) if $filter;
631 unless (($err = $?)) {
632 print $tmpfd $rslt
633 or die "Can't print $tmp: $!";
634 }
635 }
636 if ($opt_u or $err) {
637 open(IN,"<", $file) or die("Can't open $file: $!");
638 my $cut = 1;
639 local $_;
640 while (<IN>) {
641 $cut = $1 eq 'cut' if /^=(\w+)/;
642 next if $cut;
643 print $tmpfd $_
644 or die "Can't print $tmp: $!";
645 }
646 close IN or die "Can't close $file: $!";
647 }
eb459f90 648}
6a43d2f9 649close $tmpfd
650 or die "Can't close $tmp: $!";
febd60db 651page($tmp, $no_tty, @pagers);
4633a7c4 652
8167b455 653exit;
654
655sub is_tainted {
656 my $arg = shift;
657 my $nada = substr($arg, 0, 0); # zero-length
658 local $@; # preserve caller's version
659 eval { eval "# $nada" };
660 return length($@) != 0;
661}
662
663sub am_taint_checking {
664 my($k,$v) = each %ENV;
665 return is_tainted($v);
666}
667
7eda7aea 668
669__END__
670
671=head1 NAME
672
673perldoc - Look up Perl documentation in pod format.
674
675=head1 SYNOPSIS
676
89b8affa 677B<perldoc> [B<-h>] [B<-v>] [B<-t>] [B<-u>] [B<-m>] [B<-l>] [B<-F>] [B<-X>] PageName|ModuleName|ProgramName
7eda7aea 678
31bdbec1 679B<perldoc> B<-f> BuiltinFunction
680
c8950503 681B<perldoc> B<-q> FAQ Keyword
682
7eda7aea 683=head1 DESCRIPTION
684
40fc7247 685I<perldoc> looks up a piece of documentation in .pod format that is embedded
686in the perl installation tree or in a perl script, and displays it via
687C<pod2man | nroff -man | $PAGER>. (In addition, if running under HP-UX,
688C<col -x> will be used.) This is primarily used for the documentation for
689the perl library modules.
7eda7aea 690
691Your system may also have man pages installed for those modules, in
692which case you can probably just use the man(1) command.
693
694=head1 OPTIONS
695
696=over 5
697
698=item B<-h> help
699
700Prints out a brief help message.
701
702=item B<-v> verbose
703
704Describes search for the item in detail.
705
706=item B<-t> text output
707
708Display docs using plain text converter, instead of nroff. This may be faster,
709but it won't look as nice.
710
711=item B<-u> unformatted
712
713Find docs only; skip reformatting by pod2*
714
715=item B<-m> module
716
717Display the entire module: both code and unformatted pod documentation.
718This may be useful if the docs don't explain a function in the detail
719you need, and you'd like to inspect the code directly; perldoc will find
720the file for you and simply hand it off for display.
721
44a8e56a 722=item B<-l> file name only
723
724Display the file name of the module found.
725
cce34969 726=item B<-F> file names
727
89b8affa 728Consider arguments as file names, no search in directories will be performed.
cce34969 729
31bdbec1 730=item B<-f> perlfunc
731
732The B<-f> option followed by the name of a perl built in function will
733extract the documentation of this function from L<perlfunc>.
734
c8950503 735=item B<-q> perlfaq
736
737The B<-q> option takes a regular expression as an argument. It will search
738the question headings in perlfaq[1-9] and print the entries matching
739the regular expression.
740
89b8affa 741=item B<-X> use an index if present
742
d1be9408 743The B<-X> option looks for an entry whose basename matches the name given on the
89b8affa 744command line in the file C<$Config{archlib}/pod.idx>. The pod.idx file should
745contain fully qualified filenames, one per line.
746
c185d8c4 747=item B<-U> run insecurely
748
749Because B<perldoc> does not run properly tainted, and is known to
750have security issues, it will not normally execute as the superuser.
751If you use the B<-U> flag, it will do so, but only after setting
752the effective and real IDs to nobody's or nouser's account, or -2
d1be9408 753if unavailable. If it cannot relinquish its privileges, it will not
c185d8c4 754run.
755
7eda7aea 756=item B<PageName|ModuleName|ProgramName>
757
758The item you want to look up. Nested modules (such as C<File::Basename>)
759are specified either as C<File::Basename> or C<File/Basename>. You may also
1b420867 760give a descriptive name of a page, such as C<perlfunc>. You may also give a
7eda7aea 761partial or wrong-case name, such as "basename" for "File::Basename", but
762this will be slower, if there is more then one page with the same partial
763name, you will only get the first one.
764
765=back
766
767=head1 ENVIRONMENT
768
febd60db 769Any switches in the C<PERLDOC> environment variable will be used before the
7eda7aea 770command line arguments. C<perldoc> also searches directories
771specified by the C<PERL5LIB> (or C<PERLLIB> if C<PERL5LIB> is not
772defined) and C<PATH> environment variables.
773(The latter is so that embedded pods for executables, such as
a3cb178b 774C<perldoc> itself, are available.) C<perldoc> will use, in order of
775preference, the pager defined in C<PERLDOC_PAGER>, C<MANPAGER>, or
776C<PAGER> before trying to find a pager on its own. (C<MANPAGER> is not
777used if C<perldoc> was told to display plain text or unformatted pod.)
7eda7aea 778
eb459f90 779One useful value for C<PERLDOC_PAGER> is C<less -+C -E>.
780
febd60db 781=head1 VERSION
782
6d0835e5 783This is perldoc v2.03.
febd60db 784
7eda7aea 785=head1 AUTHOR
786
787Kenneth Albanowski <kjahds@kjahds.com>
788
febd60db 789Minor updates by Andy Dougherty <doughera@lafcol.lafayette.edu>,
790and others.
7eda7aea 791
7eda7aea 792=cut
793
794#
6d0835e5 795# Version 2.03: Sun Apr 23 16:56:34 BST 2000
796# Hugo van der Sanden <hv@crypt0.demon.co.uk>
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;