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