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