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