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