Decommission Encode::Tcl HZ testing for now.
[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;
5315ba28 345 if ( ( $ret = check_file $dir,"$s.pod")
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 {
461 print STDERR "No documentation found for \"$_\".\n";
462 if (@global_found) {
463 print STDERR "However, try\n";
464 for my $dir (@global_found) {
8167b455 465 opendir(DIR, $dir) or die "opendir $dir: $!";
febd60db 466 while (my $file = readdir(DIR)) {
8167b455 467 next if ($file =~ /^\./s);
468 $file =~ s/\.(pm|pod)\z//; # XXX: badfs
febd60db 469 print STDERR "\tperldoc $_\::$file\n";
470 }
8167b455 471 closedir DIR or die "closedir $dir: $!";
4633a7c4 472 }
febd60db 473 }
4633a7c4 474 }
febd60db 475 }
476 push(@found,@files);
4633a7c4 477}
478
febd60db 479if (!@found) {
480 exit ($Is_VMS ? 98962 : 1);
4633a7c4 481}
482
44a8e56a 483if ($opt_l) {
484 print join("\n", @found), "\n";
485 exit;
486}
487
877622ba 488my $lines = $ENV{LINES} || 24;
489
c5ae3962 490my $no_tty;
febd60db 491if (! -t STDOUT) { $no_tty = 1 }
8167b455 492END { close(STDOUT) || die "Can't close STDOUT: $!" }
febd60db 493
137443ea 494if ($Is_MSWin32) {
febd60db 495 push @pagers, qw( more< less notepad );
496 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
497 for (@found) { s,/,\\,g }
498}
499elsif ($Is_VMS) {
febd60db 500 push @pagers, qw( most more less type/page );
501}
502elsif ($Is_Dos) {
febd60db 503 push @pagers, qw( less.exe more.com< );
504 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
505}
506else {
507 if ($^O eq 'os2') {
febd60db 508 unshift @pagers, 'less', 'cmd /c more <';
509 }
febd60db 510 push @pagers, qw( more less pg view cat );
511 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
4633a7c4 512}
44a8e56a 513unshift @pagers, $ENV{PERLDOC_PAGER} if $ENV{PERLDOC_PAGER};
4633a7c4 514
7eda7aea 515if ($opt_m) {
febd60db 516 foreach my $pager (@pagers) {
8167b455 517 if (system($pager, @found) == 0) {
518 exit;
519 }
febd60db 520 }
8167b455 521 if ($Is_VMS) {
522 eval q{
523 use vmsish qw(status exit);
524 exit $?;
525 1;
526 } or die;
527 }
528 exit(1);
eb459f90 529}
7eda7aea 530
eb459f90 531my @pod;
31bdbec1 532if ($opt_f) {
febd60db 533 my $perlfunc = shift @found;
8167b455 534 open(PFUNC, "<", $perlfunc)
535 or die("Can't open $perlfunc: $!");
31bdbec1 536
febd60db 537 # Functions like -r, -e, etc. are listed under `-X'.
538 my $search_string = ($opt_f =~ /^-[rwxoRWXOeszfdlpSbctugkTBMAC]$/)
539 ? 'I<-X' : $opt_f ;
a3cb178b 540
febd60db 541 # Skip introduction
8167b455 542 local $_;
febd60db 543 while (<PFUNC>) {
544 last if /^=head2 Alphabetical Listing of Perl Functions/;
545 }
7eda7aea 546
febd60db 547 # Look for our function
548 my $found = 0;
549 my $inlist = 0;
550 while (<PFUNC>) {
551 if (/^=item\s+\Q$search_string\E\b/o) {
552 $found = 1;
85880f03 553 }
febd60db 554 elsif (/^=item/) {
555 last if $found > 1 and not $inlist;
556 }
557 next unless $found;
558 if (/^=over/) {
559 ++$inlist;
560 }
561 elsif (/^=back/) {
562 --$inlist;
4633a7c4 563 }
febd60db 564 push @pod, $_;
565 ++$found if /^\w/; # found descriptive text
566 }
567 if (!@pod) {
568 die "No documentation for perl function `$opt_f' found\n";
569 }
8167b455 570 close PFUNC or die "Can't open $perlfunc: $!";
4633a7c4 571}
572
febd60db 573if ($opt_q) {
574 local @ARGV = @found; # I'm lazy, sue me.
575 my $found = 0;
576 my %found_in;
8167b455 577 my $rx = eval { qr/$opt_q/ } or die <<EOD;
b62b7eeb 578Invalid regular expression '$opt_q' given as -q pattern:
579 $@
580Did you mean \\Q$opt_q ?
581
582EOD
febd60db 583
8167b455 584 for (@found) { die "invalid file spec: $!" if /[<>|]/ }
585 local $_;
febd60db 586 while (<>) {
587 if (/^=head2\s+.*(?:$opt_q)/oi) {
588 $found = 1;
589 push @pod, "=head1 Found in $ARGV\n\n" unless $found_in{$ARGV}++;
4633a7c4 590 }
a5396746 591 elsif (/^=head[12]/) {
febd60db 592 $found = 0;
593 }
594 next unless $found;
595 push @pod, $_;
596 }
597 if (!@pod) {
8167b455 598 die("No documentation for perl FAQ keyword `$opt_q' found\n");
febd60db 599 }
600}
601
6a43d2f9 602require File::Temp;
603
008d9c33 604my ($tmpfd, $tmp) = File::Temp::tempfile(UNLINK => 1);
6a43d2f9 605
febd60db 606my $filter;
607
608if (@pod) {
008d9c33 609 my ($buffd, $buffer) = File::Temp::tempfile(UNLINK => 1);
6a43d2f9 610 print $buffd "=over 8\n\n";
611 print $buffd @pod or die "Can't print $buffer: $!";
612 print $buffd "=back\n";
613 close $buffd or die "Can't close $buffer: $!";
febd60db 614 @found = $buffer;
615 $filter = 1;
4633a7c4 616}
617
febd60db 618foreach (@found) {
6a43d2f9 619 my $file = $_;
620 my $err;
621
622 if ($opt_t) {
623 Pod::Text->new()->parse_from_file($file, $tmpfd);
624 }
625 elsif (not $opt_u) {
c6a5b0b7 626 my $cmd = catfile($bindir, $pod2man) . " --lax $file | $opt_n -man";
6a43d2f9 627 $cmd .= " | col -x" if $^O =~ /hpux/;
628 my $rslt = `$cmd`;
629 $rslt = filter_nroff($rslt) if $filter;
630 unless (($err = $?)) {
631 print $tmpfd $rslt
632 or die "Can't print $tmp: $!";
633 }
634 }
635 if ($opt_u or $err) {
636 open(IN,"<", $file) or die("Can't open $file: $!");
637 my $cut = 1;
638 local $_;
639 while (<IN>) {
640 $cut = $1 eq 'cut' if /^=(\w+)/;
641 next if $cut;
642 print $tmpfd $_
643 or die "Can't print $tmp: $!";
644 }
645 close IN or die "Can't close $file: $!";
646 }
eb459f90 647}
6a43d2f9 648close $tmpfd
649 or die "Can't close $tmp: $!";
febd60db 650page($tmp, $no_tty, @pagers);
4633a7c4 651
8167b455 652exit;
653
654sub is_tainted {
655 my $arg = shift;
656 my $nada = substr($arg, 0, 0); # zero-length
657 local $@; # preserve caller's version
658 eval { eval "# $nada" };
659 return length($@) != 0;
660}
661
662sub am_taint_checking {
663 my($k,$v) = each %ENV;
664 return is_tainted($v);
665}
666
7eda7aea 667
668__END__
669
670=head1 NAME
671
672perldoc - Look up Perl documentation in pod format.
673
674=head1 SYNOPSIS
675
89b8affa 676B<perldoc> [B<-h>] [B<-v>] [B<-t>] [B<-u>] [B<-m>] [B<-l>] [B<-F>] [B<-X>] PageName|ModuleName|ProgramName
7eda7aea 677
31bdbec1 678B<perldoc> B<-f> BuiltinFunction
679
c8950503 680B<perldoc> B<-q> FAQ Keyword
681
7eda7aea 682=head1 DESCRIPTION
683
40fc7247 684I<perldoc> looks up a piece of documentation in .pod format that is embedded
685in the perl installation tree or in a perl script, and displays it via
686C<pod2man | nroff -man | $PAGER>. (In addition, if running under HP-UX,
687C<col -x> will be used.) This is primarily used for the documentation for
688the perl library modules.
7eda7aea 689
690Your system may also have man pages installed for those modules, in
691which case you can probably just use the man(1) command.
692
693=head1 OPTIONS
694
695=over 5
696
697=item B<-h> help
698
699Prints out a brief help message.
700
701=item B<-v> verbose
702
703Describes search for the item in detail.
704
705=item B<-t> text output
706
707Display docs using plain text converter, instead of nroff. This may be faster,
708but it won't look as nice.
709
710=item B<-u> unformatted
711
712Find docs only; skip reformatting by pod2*
713
714=item B<-m> module
715
716Display the entire module: both code and unformatted pod documentation.
717This may be useful if the docs don't explain a function in the detail
718you need, and you'd like to inspect the code directly; perldoc will find
719the file for you and simply hand it off for display.
720
44a8e56a 721=item B<-l> file name only
722
723Display the file name of the module found.
724
cce34969 725=item B<-F> file names
726
89b8affa 727Consider arguments as file names, no search in directories will be performed.
cce34969 728
31bdbec1 729=item B<-f> perlfunc
730
731The B<-f> option followed by the name of a perl built in function will
732extract the documentation of this function from L<perlfunc>.
733
c8950503 734=item B<-q> perlfaq
735
736The B<-q> option takes a regular expression as an argument. It will search
737the question headings in perlfaq[1-9] and print the entries matching
738the regular expression.
739
89b8affa 740=item B<-X> use an index if present
741
d1be9408 742The B<-X> option looks for an entry whose basename matches the name given on the
89b8affa 743command line in the file C<$Config{archlib}/pod.idx>. The pod.idx file should
744contain fully qualified filenames, one per line.
745
c185d8c4 746=item B<-U> run insecurely
747
748Because B<perldoc> does not run properly tainted, and is known to
749have security issues, it will not normally execute as the superuser.
750If you use the B<-U> flag, it will do so, but only after setting
751the effective and real IDs to nobody's or nouser's account, or -2
d1be9408 752if unavailable. If it cannot relinquish its privileges, it will not
c185d8c4 753run.
754
7eda7aea 755=item B<PageName|ModuleName|ProgramName>
756
757The item you want to look up. Nested modules (such as C<File::Basename>)
758are specified either as C<File::Basename> or C<File/Basename>. You may also
1b420867 759give a descriptive name of a page, such as C<perlfunc>. You may also give a
7eda7aea 760partial or wrong-case name, such as "basename" for "File::Basename", but
761this will be slower, if there is more then one page with the same partial
762name, you will only get the first one.
763
764=back
765
766=head1 ENVIRONMENT
767
febd60db 768Any switches in the C<PERLDOC> environment variable will be used before the
7eda7aea 769command line arguments. C<perldoc> also searches directories
770specified by the C<PERL5LIB> (or C<PERLLIB> if C<PERL5LIB> is not
771defined) and C<PATH> environment variables.
772(The latter is so that embedded pods for executables, such as
a3cb178b 773C<perldoc> itself, are available.) C<perldoc> will use, in order of
774preference, the pager defined in C<PERLDOC_PAGER>, C<MANPAGER>, or
775C<PAGER> before trying to find a pager on its own. (C<MANPAGER> is not
776used if C<perldoc> was told to display plain text or unformatted pod.)
7eda7aea 777
eb459f90 778One useful value for C<PERLDOC_PAGER> is C<less -+C -E>.
779
febd60db 780=head1 VERSION
781
6d0835e5 782This is perldoc v2.03.
febd60db 783
7eda7aea 784=head1 AUTHOR
785
786Kenneth Albanowski <kjahds@kjahds.com>
787
febd60db 788Minor updates by Andy Dougherty <doughera@lafcol.lafayette.edu>,
789and others.
7eda7aea 790
7eda7aea 791=cut
792
793#
6d0835e5 794# Version 2.03: Sun Apr 23 16:56:34 BST 2000
795# Hugo van der Sanden <hv@crypt0.demon.co.uk>
796# don't die when 'use blib' fails
c185d8c4 797# Version 2.02: Mon Mar 13 18:03:04 MST 2000
798# Tom Christiansen <tchrist@perl.com>
799# Added -U insecurity option
8167b455 800# Version 2.01: Sat Mar 11 15:22:33 MST 2000
801# Tom Christiansen <tchrist@perl.com>, querulously.
802# Security and correctness patches.
803# What a twisted bit of distasteful spaghetti code.
804# Version 2.0: ????
7ec2cea4 805# Version 1.15: Tue Aug 24 01:50:20 EST 1999
806# Charles Wilson <cwilson@ece.gatech.edu>
807# changed /pod/ directory to /pods/ for cygwin
808# to support cygwin/win32
c5ae3962 809# Version 1.14: Wed Jul 15 01:50:20 EST 1998
810# Robin Barker <rmb1@cise.npl.co.uk>
811# -strict, -w cleanups
89b8affa 812# Version 1.13: Fri Feb 27 16:20:50 EST 1997
6e238990 813# Gurusamy Sarathy <gsar@activestate.com>
89b8affa 814# -doc tweaks for -F and -X options
137443ea 815# Version 1.12: Sat Apr 12 22:41:09 EST 1997
6e238990 816# Gurusamy Sarathy <gsar@activestate.com>
137443ea 817# -various fixes for win32
7eda7aea 818# Version 1.11: Tue Dec 26 09:54:33 EST 1995
819# Kenneth Albanowski <kjahds@kjahds.com>
820# -added Charles Bailey's further VMS patches, and -u switch
821# -added -t switch, with pod2text support
febd60db 822#
7eda7aea 823# Version 1.10: Thu Nov 9 07:23:47 EST 1995
824# Kenneth Albanowski <kjahds@kjahds.com>
825# -added VMS support
826# -added better error recognition (on no found pages, just exit. On
827# missing nroff/pod2man, just display raw pod.)
828# -added recursive/case-insensitive matching (thanks, Andreas). This
829# slows things down a bit, unfortunately. Give a precise name, and
830# it'll run faster.
831#
832# Version 1.01: Tue May 30 14:47:34 EDT 1995
833# Andy Dougherty <doughera@lafcol.lafayette.edu>
834# -added pod documentation.
835# -added PATH searching.
836# -added searching pod/ subdirectory (mainly to pick up perlfunc.pod
837# and friends.
838#
839#
840# TODO:
841#
842# Cache directories read during sloppy match
4633a7c4 843!NO!SUBS!
844
845close OUT or die "Can't close $file: $!";
846chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
847exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
8a5546a1 848chdir $origdir;