4 use File::Basename qw(&basename &dirname);
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
12 # to ensure Configure will look for $Config{startperl}.
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.
18 $file = basename($0, '.PL');
19 $file .= '.com' if $^O eq 'VMS';
21 open OUT,">$file" or die "Can't create $file: $!";
23 print "Extracting $file (with variable substitutions)\n";
25 # In this section, perl variables will be expanded during extraction.
26 # You can use $Config{...} to use Configure variables.
28 print OUT <<"!GROK!THIS!";
30 eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
36 # make sure creat()s are neither too much nor too little
37 INIT { eval { umask(0077) } } # doubtless someone has no mask
40 push \@pagers, "$Config{'pager'}" if -x "$Config{'pager'}";
41 my \$bindir = "$Config{installscript}";
45 # In the following, perl variables are not expanded during extraction.
47 print OUT <<'!NO!SUBS!';
49 use Fcntl; # for sysopen
52 use File::Spec::Functions qw(catfile splitdir);
55 # Perldoc revision #1 -- look up a piece of documentation in .pod format that
56 # is embedded in the perl installation tree.
58 # This is not to be confused with Tom Christiansen's perlman, which is a
59 # man replacement, written in perl. This perldoc is strictly for reading
60 # the perl manuals, though it too is written in perl.
62 # Massive security and correctness patches applied to this
63 # noisome program by Tom Christiansen Sat Mar 11 15:22:33 MST 2000
66 my $me = $0; # Editing $0 is unportable
69 Usage: $me [-h] [-r] [-i] [-v] [-t] [-u] [-m] [-n program] [-l] [-F] [-X] PageName|ModuleName|ProgramName
73 The -h option prints more help. Also try "perldoc perldoc" to get
74 acquainted with the system.
78 my @global_found = ();
79 my $global_target = "";
81 my $Is_VMS = $^O eq 'VMS';
82 my $Is_MSWin32 = $^O eq 'MSWin32';
83 my $Is_Dos = $^O eq 'dos';
87 # Erase evidence of previous errors (if any), so exit status is simple.
90 perldoc [options] PageName|ModuleName|ProgramName...
91 perldoc [options] -f BuiltinFunction
92 perldoc [options] -q FAQRegex
95 -h Display this help message
96 -r Recursive search (slow)
98 -t Display pod using pod2text instead of pod2man and nroff
99 (-t is the default on win32)
100 -u Display unformatted pod text
101 -m Display module's file in its entirety
102 -n Specify replacement for nroff
103 -l Display the module's file name
104 -F Arguments are file names, not modules
105 -v Verbosely describe what's going on
106 -X use index if present (looks for pod.idx at $Config{archlib})
107 -q Search the text of questions (not answers) in perlfaq[1-9]
108 -U Run in insecure mode (superuser only)
110 PageName|ModuleName...
111 is the name of a piece of documentation that you want to look at. You
112 may either give a descriptive name of the page (as in the case of
113 `perlfunc') the name of a module, either like `Term::Info',
114 `Term/Info', the partial name of a module, like `info', or
115 `makemaker', or the name of a program, like `perldoc'.
118 is the name of a perl function. Will extract documentation from
122 is a regex. Will search perlfaq[1-9] for and extract any
123 questions that match.
125 Any switches in the PERLDOC environment variable will be used before the
126 command line arguments. The optional pod index file contains a list of
127 filenames, one per line.
132 if (defined $ENV{"PERLDOC"}) {
133 require Text::ParseWords;
134 unshift(@ARGV, Text::ParseWords::shellwords($ENV{"PERLDOC"}));
138 my $getopts = "mhtluvriFf:Xq:n:U";
139 print OUT <<"!GET!OPTS!";
141 use vars qw( @{[map "\$opt_$_", ($getopts =~ /\w/g)]} );
143 getopts("$getopts") || usage;
146 print OUT <<'!NO!SUBS!';
150 # refuse to run if we should be tainting and aren't
151 # (but regular users deserve protection too, though!)
152 if (!($Is_VMS || $Is_MSWin32 || $Is_Dos) && ($> == 0 || $< == 0)
153 && !am_taint_checking())
156 my $id = eval { getpwnam("nobody") };
157 $id = eval { getpwnam("nouser") } unless defined $id;
158 $id = -2 unless defined $id;
160 $> = $id; # must do this one first!
163 last if !$@ && $< && $>;
165 die "Superuser must not run $0 without security audit and taint checks.\n";
168 $opt_n = "nroff" if !$opt_n;
172 $podidx = "$Config{'archlib'}/pod.idx";
173 $podidx = "" unless -f $podidx && -r _ && -M _ <= 7;
176 if ((my $opts = do{ no warnings; $opt_t + $opt_u + $opt_m + $opt_l }) > 1) {
177 usage("only one of -t, -u, -m or -l")
181 || !($ENV{TERM} && $ENV{TERM} !~ /dumb|emacs|none|unknown/i))
183 $opt_t = 1 unless $opts;
186 if ($opt_t) { require Pod::Text; import Pod::Text; }
190 @pages = ("perlfunc");
193 @pages = ("perlfaq1" .. "perlfaq9");
199 # Does this look like a module or extension directory?
200 if (-f "Makefile.PL") {
202 # Add ., lib to @INC (if they exist)
203 eval q{ use lib qw(. lib); 1; } or die;
205 # don't add if superuser
206 if ($< && $>) { # don't be looking too hard now!
207 eval q{ use blib; 1 } or die;
212 my($file, $readit) = @_;
213 return 1 if !$readit && $file =~ /\.pod\z/i;
215 open(TEST,"<", $file) or die "Can't open $file: $!";
218 close(TEST) or die "Can't close $file: $!";
222 close(TEST) or die "Can't close $file: $!";
228 my $path = catfile($dir,$file);
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') {
231 # on a case-forgiving file system or if case is important
232 # that is it all we can do
233 warn "Ignored $path: unreadable\n" if -f _;
237 # this is completely wicked. don't mess with $", and if
238 # you do, don't assume / is the dirsep!
242 foreach $p (splitdir $file){
243 my $try = catfile @p, $p;
247 if ( $p eq $global_target) {
248 my $tmp_path = catfile @p;
250 for (@global_found) {
251 $path_f = 1 if $_ eq $tmp_path;
253 push (@global_found, $tmp_path) unless $path_f;
254 print STDERR "Found as @p but directory\n" if $opt_v;
257 elsif (-f _ && -r _) {
261 warn "Ignored $try: unreadable\n";
266 opendir DIR, "@p" or die "opendir @p: $!";
267 while ($cip=readdir(DIR)) {
268 if (lc $cip eq $lcp){
273 closedir DIR or die "closedir @p: $!";
274 return "" unless $found;
276 return "@p" if -f "@p" and -r _;
277 warn "Ignored @p: unreadable\n" if -f _;
286 return "" if length $dir and not -d $dir;
288 return minus_f_nocase($dir,$file);
291 my $path = minus_f_nocase($dir,$file);
292 return $path if length $path and containspod($path);
299 my($recurse,$s,@dirs) = @_;
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;
307 $global_target = (splitdir $s)[-1]; # XXX: why not use File::Basename?
308 for ($i=0; $i<@dirs; $i++) {
310 ($dir = VMS::Filespec::unixpath($dir)) =~ s!/\z!! if $Is_VMS;
311 if ( ( $ret = check_file $dir,"$s.pod")
312 or ( $ret = check_file $dir,"$s.pm")
313 or ( $ret = check_file $dir,$s)
315 $ret = check_file $dir,"$s.com")
316 or ( $^O eq 'os2' and
317 $ret = check_file $dir,"$s.cmd")
318 or ( ($Is_MSWin32 or $Is_Dos or $^O eq 'os2') and
319 $ret = check_file $dir,"$s.bat")
320 or ( $ret = check_file "$dir/pod","$s.pod")
321 or ( $ret = check_file "$dir/pod",$s)
322 or ( $ret = check_file "$dir/pods","$s.pod")
323 or ( $ret = check_file "$dir/pods",$s)
329 opendir(D,$dir) or die "Can't opendir $dir: $!";
330 my @newdirs = map catfile($dir, $_), grep {
332 not /^auto\z/s and # save time! don't search auto dirs
335 closedir(D) or die "Can't closedir $dir: $!";
336 next unless @newdirs;
338 @newdirs = map((s/\.dir\z//,$_)[1],@newdirs) if $Is_VMS;
339 print STDERR "Also looking in @newdirs\n" if $opt_v;
340 push(@dirs,@newdirs);
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
356 my ($file, $tmp, $filter) = @_;
360 # why was this append?
361 sysopen(OUT, $tmp, O_WRONLY | O_EXCL | O_CREAT, 0600)
362 or die ("Can't open $tmp: $!");
363 Pod::Text->new()->parse_from_file($file,\*OUT);
364 close OUT or die "can't close $tmp: $!";
367 my $cmd = catfile($bindir, 'pod2man') . " --lax $file | $opt_n -man";
368 $cmd .= " | col -x" if $^O =~ /hpux/;
370 $rslt = filter_nroff($rslt) if $filter;
371 unless (($err = $?)) {
372 # why was this append?
373 sysopen(TMP, $tmp, O_WRONLY | O_EXCL | O_CREAT, 0600)
374 or die "Can't open $tmp: $!";
376 or die "Can't print $tmp: $!";
378 or die "Can't close $tmp: $!";
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: $!");
389 $cut = $1 eq 'cut' if /^=(\w+)/;
392 or die "Can't print $tmp: $!";
394 close IN or die "Can't close $file: $!";
395 close OUT or die "Can't close $tmp: $!";
400 my ($tmp, $no_tty, @pagers) = @_;
402 open(TMP,"<", $tmp) or die "Can't open $tmp: $!";
405 print or die "Can't print to stdout: $!";
407 close TMP or die "Can't close while $tmp: $!";
410 foreach my $pager (@pagers) {
411 last if system("$pager $tmp") == 0;
420 1 while unlink($_); # XXX: expect failure
422 unlink($_); # or die "Can't unlink $_: $!";
429 if ($podidx && open(PODIDX, $podidx)) {
430 my $searchfor = catfile split '::';
431 print STDERR "Searching for '$searchfor' in $podidx\n" if $opt_v;
435 push(@found, $_) if m,/$searchfor(?:\.(?:pod|pm))?\z,i;
437 close(PODIDX) or die "Can't close $podidx: $!";
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;
446 push @found, $_ if $opt_m or containspod($_);
452 for ($i = 0; $trn = $ENV{'DCL$PATH;'.$i}; $i++) {
453 push(@searchdirs,$trn);
455 push(@searchdirs,'perl_root:[lib.pod]') # installed pods
458 push(@searchdirs, grep(-d, split($Config{path_sep},
462 my @files = searchfor(0,$_,@searchdirs);
464 print STDERR "Found as @files\n" if $opt_v;
467 # no match, try recursive search
468 @searchdirs = grep(!/^\.\z/s,@INC);
469 @files= searchfor(1,$_,@searchdirs) if $opt_r;
471 print STDERR "Loosely found as @files\n" if $opt_v;
474 print STDERR "No documentation found for \"$_\".\n";
476 print STDERR "However, try\n";
477 for my $dir (@global_found) {
478 opendir(DIR, $dir) or die "opendir $dir: $!";
479 while (my $file = readdir(DIR)) {
480 next if ($file =~ /^\./s);
481 $file =~ s/\.(pm|pod)\z//; # XXX: badfs
482 print STDERR "\tperldoc $_\::$file\n";
484 closedir DIR or die "closedir $dir: $!";
493 exit ($Is_VMS ? 98962 : 1);
497 print join("\n", @found), "\n";
501 my $lines = $ENV{LINES} || 24;
504 if (! -t STDOUT) { $no_tty = 1 }
505 END { close(STDOUT) || die "Can't close STDOUT: $!" }
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
510 # that's because you did it wrong, should be descriptor based --tchrist
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 }
522 $tmp = 'Sys$Scratch:perldoc.tmp1_'.$$;
523 $buffer = 'Sys$Scratch:perldoc.tmp1_b'.$$;
524 push @pagers, qw( most more less type/page );
527 $tmp = "$ENV{TEMP}/perldoc1.$$";
528 $buffer = "$ENV{TEMP}/perldoc1.b$$";
530 $buffer =~ tr!\\/!//!s;
531 push @pagers, qw( less.exe more.com< );
532 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
537 $tmp = POSIX::tmpnam();
538 $buffer = POSIX::tmpnam();
539 unshift @pagers, 'less', 'cmd /c more <';
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$$" );
547 push @pagers, qw( more less pg view cat );
548 unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
550 unshift @pagers, $ENV{PERLDOC_PAGER} if $ENV{PERLDOC_PAGER};
552 # make sure cleanup called
554 sub END { cleanup($tmp, $buffer) }
557 eval q{ use sigtrap qw(die INT TERM HUP QUIT) };
560 foreach my $pager (@pagers) {
561 if (system($pager, @found) == 0) {
567 use vmsish qw(status exit);
577 my $perlfunc = shift @found;
578 open(PFUNC, "<", $perlfunc)
579 or die("Can't open $perlfunc: $!");
581 # Functions like -r, -e, etc. are listed under `-X'.
582 my $search_string = ($opt_f =~ /^-[rwxoRWXOeszfdlpSbctugkTBMAC]$/)
588 last if /^=head2 Alphabetical Listing of Perl Functions/;
591 # Look for our function
595 if (/^=item\s+\Q$search_string\E\b/o) {
599 last if $found > 1 and not $inlist;
609 ++$found if /^\w/; # found descriptive text
612 die "No documentation for perl function `$opt_f' found\n";
614 close PFUNC or die "Can't open $perlfunc: $!";
618 local @ARGV = @found; # I'm lazy, sue me.
621 my $rx = eval { qr/$opt_q/ } or die <<EOD;
622 Invalid regular expression '$opt_q' given as -q pattern:
624 Did you mean \\Q$opt_q ?
628 for (@found) { die "invalid file spec: $!" if /[<>|]/ }
631 if (/^=head2\s+.*(?:$opt_q)/oi) {
633 push @pod, "=head1 Found in $ARGV\n\n" unless $found_in{$ARGV}++;
642 die("No documentation for perl FAQ keyword `$opt_q' found\n");
649 sysopen(TMP, $buffer, O_WRONLY | O_EXCL | O_CREAT)
650 or die("Can't open $buffer: $!");
651 print TMP "=over 8\n\n";
652 print TMP @pod or die "Can't print $buffer: $!";
654 close TMP or die "Can't close $buffer: $!";
660 printout($_, $tmp, $filter);
662 page($tmp, $no_tty, @pagers);
668 my $nada = substr($arg, 0, 0); # zero-length
669 local $@; # preserve caller's version
670 eval { eval "# $nada" };
671 return length($@) != 0;
674 sub am_taint_checking {
675 my($k,$v) = each %ENV;
676 return is_tainted($v);
684 perldoc - Look up Perl documentation in pod format.
688 B<perldoc> [B<-h>] [B<-v>] [B<-t>] [B<-u>] [B<-m>] [B<-l>] [B<-F>] [B<-X>] PageName|ModuleName|ProgramName
690 B<perldoc> B<-f> BuiltinFunction
692 B<perldoc> B<-q> FAQ Keyword
696 I<perldoc> looks up a piece of documentation in .pod format that is embedded
697 in the perl installation tree or in a perl script, and displays it via
698 C<pod2man | nroff -man | $PAGER>. (In addition, if running under HP-UX,
699 C<col -x> will be used.) This is primarily used for the documentation for
700 the perl library modules.
702 Your system may also have man pages installed for those modules, in
703 which case you can probably just use the man(1) command.
711 Prints out a brief help message.
715 Describes search for the item in detail.
717 =item B<-t> text output
719 Display docs using plain text converter, instead of nroff. This may be faster,
720 but it won't look as nice.
722 =item B<-u> unformatted
724 Find docs only; skip reformatting by pod2*
728 Display the entire module: both code and unformatted pod documentation.
729 This may be useful if the docs don't explain a function in the detail
730 you need, and you'd like to inspect the code directly; perldoc will find
731 the file for you and simply hand it off for display.
733 =item B<-l> file name only
735 Display the file name of the module found.
737 =item B<-F> file names
739 Consider arguments as file names, no search in directories will be performed.
743 The B<-f> option followed by the name of a perl built in function will
744 extract the documentation of this function from L<perlfunc>.
748 The B<-q> option takes a regular expression as an argument. It will search
749 the question headings in perlfaq[1-9] and print the entries matching
750 the regular expression.
752 =item B<-X> use an index if present
754 The B<-X> option looks for a entry whose basename matches the name given on the
755 command line in the file C<$Config{archlib}/pod.idx>. The pod.idx file should
756 contain fully qualified filenames, one per line.
758 =item B<-U> run insecurely
760 Because B<perldoc> does not run properly tainted, and is known to
761 have security issues, it will not normally execute as the superuser.
762 If you use the B<-U> flag, it will do so, but only after setting
763 the effective and real IDs to nobody's or nouser's account, or -2
764 if unavailable. If it cannot relinguish its privileges, it will not
767 =item B<PageName|ModuleName|ProgramName>
769 The item you want to look up. Nested modules (such as C<File::Basename>)
770 are specified either as C<File::Basename> or C<File/Basename>. You may also
771 give a descriptive name of a page, such as C<perlfunc>. You may also give a
772 partial or wrong-case name, such as "basename" for "File::Basename", but
773 this will be slower, if there is more then one page with the same partial
774 name, you will only get the first one.
780 Any switches in the C<PERLDOC> environment variable will be used before the
781 command line arguments. C<perldoc> also searches directories
782 specified by the C<PERL5LIB> (or C<PERLLIB> if C<PERL5LIB> is not
783 defined) and C<PATH> environment variables.
784 (The latter is so that embedded pods for executables, such as
785 C<perldoc> itself, are available.) C<perldoc> will use, in order of
786 preference, the pager defined in C<PERLDOC_PAGER>, C<MANPAGER>, or
787 C<PAGER> before trying to find a pager on its own. (C<MANPAGER> is not
788 used if C<perldoc> was told to display plain text or unformatted pod.)
790 One useful value for C<PERLDOC_PAGER> is C<less -+C -E>.
794 This is perldoc v2.01.
798 Kenneth Albanowski <kjahds@kjahds.com>
800 Minor updates by Andy Dougherty <doughera@lafcol.lafayette.edu>,
806 # Version 2.02: Mon Mar 13 18:03:04 MST 2000
807 # Tom Christiansen <tchrist@perl.com>
808 # Added -U insecurity option
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.
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
818 # Version 1.14: Wed Jul 15 01:50:20 EST 1998
819 # Robin Barker <rmb1@cise.npl.co.uk>
820 # -strict, -w cleanups
821 # Version 1.13: Fri Feb 27 16:20:50 EST 1997
822 # Gurusamy Sarathy <gsar@activestate.com>
823 # -doc tweaks for -F and -X options
824 # Version 1.12: Sat Apr 12 22:41:09 EST 1997
825 # Gurusamy Sarathy <gsar@activestate.com>
826 # -various fixes for win32
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
832 # Version 1.10: Thu Nov 9 07:23:47 EST 1995
833 # Kenneth Albanowski <kjahds@kjahds.com>
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
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
851 # Cache directories read during sloppy match
854 close OUT or die "Can't close $file: $!";
855 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
856 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';