This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate:
[perl5.git] / autodoc.pl
CommitLineData
94bdecf9
JH
1#!/usr/bin/perl -w
2
3require 5.003; # keep this compatible, an old perl is all we may have before
4 # we build the new one
5
c240c76d
JH
6BEGIN {
7 push @INC, 'lib';
d34f9d2e 8 require 'regen_lib.pl';
18b6fe04 9}
a64c954a
IZ
10
11
94bdecf9 12#
346f75ff 13# See database of global and static function prototypes in embed.fnc
94bdecf9
JH
14# This is used to generate prototype headers under various configurations,
15# export symbols lists for different platforms, and macros to provide an
16# implicit interpreter context argument.
17#
18
19open IN, "embed.fnc" or die $!;
20
21# walk table providing an array of components in each line to
22# subroutine, printing the result
23sub walk_table (&@) {
24 my $function = shift;
25 my $filename = shift || '-';
26 my $leader = shift;
27 my $trailer = shift;
28 my $F;
29 local *F;
30 if (ref $filename) { # filehandle
31 $F = $filename;
32 }
33 else {
c240c76d 34 safer_unlink $filename;
94bdecf9 35 open F, ">$filename" or die "Can't open $filename: $!";
7647e345 36 binmode F;
94bdecf9
JH
37 $F = \*F;
38 }
39 print $F $leader if $leader;
40 seek IN, 0, 0; # so we may restart
41 while (<IN>) {
42 chomp;
43 next if /^:/;
5b7ea690 44 while (s|\\\s*$||) {
94bdecf9
JH
45 $_ .= <IN>;
46 chomp;
47 }
9ca8eaf1 48 s/\s+$//;
94bdecf9
JH
49 my @args;
50 if (/^\s*(#|$)/) {
51 @args = $_;
52 }
53 else {
54 @args = split /\s*\|\s*/, $_;
55 }
ce7d4f40 56 s/\b(NN|NULLOK)\b\s+//g for @args;
94bdecf9
JH
57 print $F $function->(@args);
58 }
59 print $F $trailer if $trailer;
c240c76d
JH
60 unless (ref $filename) {
61 close $F or die "Error closing $filename: $!";
62 }
94bdecf9
JH
63}
64
65my %apidocs;
66my %gutsdocs;
67my %docfuncs;
9ee5824c 68my %seenfuncs;
94bdecf9
JH
69
70my $curheader = "Unknown section";
71
72sub autodoc ($$) { # parse a file and extract documentation info
73 my($fh,$file) = @_;
74 my($in, $doc, $line);
75FUNC:
76 while (defined($in = <$fh>)) {
77 if ($in=~ /^=head1 (.*)/) {
78 $curheader = $1;
79 next FUNC;
80 }
81 $line++;
5b7ea690 82 if ($in =~ /^=for\s+apidoc\s+(.*?)\s*\n/) {
94bdecf9
JH
83 my $proto = $1;
84 $proto = "||$proto" unless $proto =~ /\|/;
85 my($flags, $ret, $name, @args) = split /\|/, $proto;
86 my $docs = "";
87DOC:
88 while (defined($doc = <$fh>)) {
94bdecf9
JH
89 $line++;
90 last DOC if $doc =~ /^=\w+/;
91 if ($doc =~ m:^\*/$:) {
92 warn "=cut missing? $file:$line:$doc";;
93 last DOC;
94 }
95 $docs .= $doc;
96 }
97 $docs = "\n$docs" if $docs and $docs !~ /^\n/;
98 if ($flags =~ /m/) {
99 if ($flags =~ /A/) {
100 $apidocs{$curheader}{$name} = [$flags, $docs, $ret, $file, @args];
101 }
102 else {
103 $gutsdocs{$curheader}{$name} = [$flags, $docs, $ret, $file, @args];
104 }
105 }
106 else {
107 $docfuncs{$name} = [$flags, $docs, $ret, $file, $curheader, @args];
108 }
109 if (defined $doc) {
24303b65 110 if ($doc =~ /^=(?:for|head)/) {
94bdecf9
JH
111 $in = $doc;
112 redo FUNC;
113 }
114 } else {
115 warn "$file:$line:$in";
116 }
117 }
118 }
119}
120
121sub docout ($$$) { # output the docs for one function
122 my($fh, $name, $docref) = @_;
123 my($flags, $docs, $ret, $file, @args) = @$docref;
5a701aeb 124 $name =~ s/\s*$//;
94bdecf9
JH
125
126 $docs .= "NOTE: this function is experimental and may change or be
127removed without notice.\n\n" if $flags =~ /x/;
128 $docs .= "NOTE: the perl_ form of this function is deprecated.\n\n"
129 if $flags =~ /p/;
130
5a701aeb 131 print $fh "=item $name\nX<$name>\n$docs";
94bdecf9
JH
132
133 if ($flags =~ /U/) { # no usage
134 # nothing
135 } elsif ($flags =~ /s/) { # semicolon ("dTHR;")
136 print $fh "\t\t$name;\n\n";
137 } elsif ($flags =~ /n/) { # no args
138 print $fh "\t$ret\t$name\n\n";
139 } else { # full usage
140 print $fh "\t$ret\t$name";
141 print $fh "(" . join(", ", @args) . ")";
142 print $fh "\n\n";
143 }
144 print $fh "=for hackers\nFound in file $file\n\n";
145}
146
9ee5824c
NC
147sub readonly_header (*) {
148 my $fh = shift;
149 print $fh <<"_EOH_";
150-*- buffer-read-only: t -*-
151
152!!!!!!! DO NOT EDIT THIS FILE !!!!!!!
153This file is built by $0 extracting documentation from the C source
154files.
155
156_EOH_
157}
158
159sub readonly_footer (*) {
160 my $fh = shift;
161 print $fh <<'_EOF_';
162=cut
163
164 ex: set ro:
165_EOF_
166}
167
94bdecf9 168my $file;
18b6fe04
NC
169# glob() picks up docs from extra .c or .h files that may be in unclean
170# development trees.
171my $MANIFEST = do {
172 local ($/, *FH);
173 open FH, "MANIFEST" or die "Can't open MANIFEST: $!";
174 <FH>;
175};
176
177for $file (($MANIFEST =~ /^(\S+\.c)\t/gm), ($MANIFEST =~ /^(\S+\.h)\t/gm)) {
94bdecf9
JH
178 open F, "< $file" or die "Cannot open $file for docs: $!\n";
179 $curheader = "Functions in file $file\n";
180 autodoc(\*F,$file);
181 close F or die "Error closing $file: $!\n";
182}
183
c240c76d 184safer_unlink "pod/perlapi.pod";
94bdecf9
JH
185open (DOC, ">pod/perlapi.pod") or
186 die "Can't create pod/perlapi.pod: $!\n";
7647e345 187binmode DOC;
94bdecf9 188
9ee5824c 189walk_table { # load documented functions into appropriate hash
94bdecf9
JH
190 if (@_ > 1) {
191 my($flags, $retval, $func, @args) = @_;
192 return "" unless $flags =~ /d/;
193 $func =~ s/\t//g; $flags =~ s/p//; # clean up fields from embed.pl
194 $retval =~ s/\t//;
5b7ea690 195 my $docref = delete $docfuncs{$func};
9ee5824c 196 $seenfuncs{$func} = 1;
5b7ea690
JH
197 if ($docref and @$docref) {
198 if ($flags =~ /A/) {
199 $docref->[0].="x" if $flags =~ /M/;
9ee5824c
NC
200 $apidocs{$docref->[4]}{$func} =
201 [$docref->[0] . 'A', $docref->[1], $retval, $docref->[3],
202 @args];
5b7ea690 203 } else {
9ee5824c 204 $gutsdocs{$docref->[4]}{$func} =
5b7ea690
JH
205 [$docref->[0], $docref->[1], $retval, $docref->[3], @args];
206 }
207 }
208 else {
9ee5824c 209 warn "no docs for $func\n" unless $seenfuncs{$func};
94bdecf9
JH
210 }
211 }
212 return "";
213} \*DOC;
214
215for (sort keys %docfuncs) {
216 # Have you used a full for apidoc or just a func name?
217 # Have you used Ap instead of Am in the for apidoc?
218 warn "Unable to place $_!\n";
219}
220
9ee5824c
NC
221readonly_header(DOC);
222
94bdecf9
JH
223print DOC <<'_EOB_';
224=head1 NAME
225
226perlapi - autogenerated documentation for the perl public API
227
228=head1 DESCRIPTION
5a701aeb 229X<Perl API> X<API> X<api>
94bdecf9
JH
230
231This file contains the documentation of the perl public API generated by
232embed.pl, specifically a listing of functions, macros, flags, and variables
233that may be used by extension writers. The interfaces of any functions that
234are not listed here are subject to change without notice. For this reason,
235blindly using functions listed in proto.h is to be avoided when writing
236extensions.
237
238Note that all Perl API global variables must be referenced with the C<PL_>
239prefix. Some macros are provided for compatibility with the older,
240unadorned names, but this support may be disabled in a future release.
241
242The listing is alphabetical, case insensitive.
243
244_EOB_
245
246my $key;
34ef4abf
NC
247# case insensitive sort, with fallback for determinacy
248for $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %apidocs) {
94bdecf9
JH
249 my $section = $apidocs{$key};
250 print DOC "\n=head1 $key\n\n=over 8\n\n";
59c61330
NC
251 # Again, fallback for determinacy
252 for my $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$section) {
94bdecf9
JH
253 docout(\*DOC, $key, $section->{$key});
254 }
255 print DOC "\n=back\n";
256}
257
258print DOC <<'_EOE_';
259
260=head1 AUTHORS
261
262Until May 1997, this document was maintained by Jeff Okamoto
263<okamoto@corp.hp.com>. It is now maintained as part of Perl itself.
264
265With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
266Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
267Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
268Stephen McCamant, and Gurusamy Sarathy.
269
270API Listing originally by Dean Roehrich <roehrich@cray.com>.
271
272Updated to be autogenerated from comments in the source by Benjamin Stuhl.
273
274=head1 SEE ALSO
275
276perlguts(1), perlxs(1), perlxstut(1), perlintern(1)
277
278_EOE_
279
9ee5824c 280readonly_footer(DOC);
94bdecf9 281
c240c76d 282close(DOC) or die "Error closing pod/perlapi.pod: $!";
94bdecf9 283
c240c76d 284safer_unlink "pod/perlintern.pod";
94bdecf9
JH
285open(GUTS, ">pod/perlintern.pod") or
286 die "Unable to create pod/perlintern.pod: $!\n";
7647e345 287binmode GUTS;
9ee5824c 288readonly_header(GUTS);
94bdecf9
JH
289print GUTS <<'END';
290=head1 NAME
291
292perlintern - autogenerated documentation of purely B<internal>
293 Perl functions
294
295=head1 DESCRIPTION
5a701aeb 296X<internal Perl functions> X<interpreter functions>
94bdecf9
JH
297
298This file is the autogenerated documentation of functions in the
299Perl interpreter that are documented using Perl's internal documentation
300format but are not marked as part of the Perl API. In other words,
301B<they are not for use in extensions>!
302
303END
304
305for $key (sort { uc($a) cmp uc($b); } keys %gutsdocs) {
306 my $section = $gutsdocs{$key};
307 print GUTS "\n=head1 $key\n\n=over 8\n\n";
308 for my $key (sort { uc($a) cmp uc($b); } keys %$section) {
309 docout(\*GUTS, $key, $section->{$key});
310 }
311 print GUTS "\n=back\n";
312}
313
314print GUTS <<'END';
315
316=head1 AUTHORS
317
318The autodocumentation system was originally added to the Perl core by
319Benjamin Stuhl. Documentation is by whoever was kind enough to
320document their functions.
321
322=head1 SEE ALSO
323
324perlguts(1), perlapi(1)
325
326END
9ee5824c 327readonly_footer(GUTS);
94bdecf9 328
c240c76d 329close GUTS or die "Error closing pod/perlintern.pod: $!";