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