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