Add an optimisation to allow proxy constant subroutines to be copied
[p5sagit/p5-mst-13.2.git] / autodoc.pl
CommitLineData
94bdecf9 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
36bb303b 6BEGIN {
7 push @INC, 'lib';
9ad884cb 8 require 'regen_lib.pl';
69e39a9a 9}
a64c954a 10
11
94bdecf9 12#
346f75ff 13# See database of global and static function prototypes in embed.fnc
94bdecf9 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 {
36bb303b 34 safer_unlink $filename;
94bdecf9 35 open F, ">$filename" or die "Can't open $filename: $!";
c333cfe7 36 binmode F;
94bdecf9 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 /^:/;
78c9d763 44 while (s|\\\s*$||) {
94bdecf9 45 $_ .= <IN>;
46 chomp;
47 }
23f1b5c3 48 s/\s+$//;
94bdecf9 49 my @args;
50 if (/^\s*(#|$)/) {
51 @args = $_;
52 }
53 else {
54 @args = split /\s*\|\s*/, $_;
55 }
1b6737cc 56 s/\b(NN|NULLOK)\b\s+//g for @args;
94bdecf9 57 print $F $function->(@args);
58 }
59 print $F $trailer if $trailer;
36bb303b 60 unless (ref $filename) {
61 close $F or die "Error closing $filename: $!";
62 }
94bdecf9 63}
64
65my %apidocs;
66my %gutsdocs;
67my %docfuncs;
7eb550cf 68my %seenfuncs;
94bdecf9 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++;
78c9d763 82 if ($in =~ /^=for\s+apidoc\s+(.*?)\s*\n/) {
94bdecf9 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 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) {
e509e693 110 if ($doc =~ /^=(?:for|head)/) {
94bdecf9 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;
d8c40edc 124 $name =~ s/\s*$//;
94bdecf9 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
d8c40edc 131 print $fh "=item $name\nX<$name>\n$docs";
94bdecf9 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
147my $file;
69e39a9a 148# glob() picks up docs from extra .c or .h files that may be in unclean
149# development trees.
150my $MANIFEST = do {
151 local ($/, *FH);
152 open FH, "MANIFEST" or die "Can't open MANIFEST: $!";
153 <FH>;
154};
155
156for $file (($MANIFEST =~ /^(\S+\.c)\t/gm), ($MANIFEST =~ /^(\S+\.h)\t/gm)) {
94bdecf9 157 open F, "< $file" or die "Cannot open $file for docs: $!\n";
158 $curheader = "Functions in file $file\n";
159 autodoc(\*F,$file);
160 close F or die "Error closing $file: $!\n";
161}
162
36bb303b 163safer_unlink "pod/perlapi.pod";
94bdecf9 164open (DOC, ">pod/perlapi.pod") or
165 die "Can't create pod/perlapi.pod: $!\n";
c333cfe7 166binmode DOC;
94bdecf9 167
7eb550cf 168walk_table { # load documented functions into appropriate hash
94bdecf9 169 if (@_ > 1) {
170 my($flags, $retval, $func, @args) = @_;
171 return "" unless $flags =~ /d/;
172 $func =~ s/\t//g; $flags =~ s/p//; # clean up fields from embed.pl
173 $retval =~ s/\t//;
78c9d763 174 my $docref = delete $docfuncs{$func};
7eb550cf 175 $seenfuncs{$func} = 1;
78c9d763 176 if ($docref and @$docref) {
177 if ($flags =~ /A/) {
178 $docref->[0].="x" if $flags =~ /M/;
7eb550cf 179 $apidocs{$docref->[4]}{$func} =
180 [$docref->[0] . 'A', $docref->[1], $retval, $docref->[3],
181 @args];
78c9d763 182 } else {
7eb550cf 183 $gutsdocs{$docref->[4]}{$func} =
78c9d763 184 [$docref->[0], $docref->[1], $retval, $docref->[3], @args];
185 }
186 }
187 else {
7eb550cf 188 warn "no docs for $func\n" unless $seenfuncs{$func};
94bdecf9 189 }
190 }
191 return "";
192} \*DOC;
193
194for (sort keys %docfuncs) {
195 # Have you used a full for apidoc or just a func name?
196 # Have you used Ap instead of Am in the for apidoc?
197 warn "Unable to place $_!\n";
198}
199
200print DOC <<'_EOB_';
201=head1 NAME
202
203perlapi - autogenerated documentation for the perl public API
204
205=head1 DESCRIPTION
d8c40edc 206X<Perl API> X<API> X<api>
94bdecf9 207
208This file contains the documentation of the perl public API generated by
209embed.pl, specifically a listing of functions, macros, flags, and variables
210that may be used by extension writers. The interfaces of any functions that
211are not listed here are subject to change without notice. For this reason,
212blindly using functions listed in proto.h is to be avoided when writing
213extensions.
214
215Note that all Perl API global variables must be referenced with the C<PL_>
216prefix. Some macros are provided for compatibility with the older,
217unadorned names, but this support may be disabled in a future release.
218
219The listing is alphabetical, case insensitive.
220
221_EOB_
222
223my $key;
6a477168 224# case insensitive sort, with fallback for determinacy
225for $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %apidocs) {
94bdecf9 226 my $section = $apidocs{$key};
227 print DOC "\n=head1 $key\n\n=over 8\n\n";
22469dce 228 # Again, fallback for determinacy
229 for my $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$section) {
94bdecf9 230 docout(\*DOC, $key, $section->{$key});
231 }
232 print DOC "\n=back\n";
233}
234
235print DOC <<'_EOE_';
236
237=head1 AUTHORS
238
239Until May 1997, this document was maintained by Jeff Okamoto
240<okamoto@corp.hp.com>. It is now maintained as part of Perl itself.
241
242With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
243Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
244Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
245Stephen McCamant, and Gurusamy Sarathy.
246
247API Listing originally by Dean Roehrich <roehrich@cray.com>.
248
249Updated to be autogenerated from comments in the source by Benjamin Stuhl.
250
251=head1 SEE ALSO
252
253perlguts(1), perlxs(1), perlxstut(1), perlintern(1)
254
255_EOE_
256
257
36bb303b 258close(DOC) or die "Error closing pod/perlapi.pod: $!";
94bdecf9 259
36bb303b 260safer_unlink "pod/perlintern.pod";
94bdecf9 261open(GUTS, ">pod/perlintern.pod") or
262 die "Unable to create pod/perlintern.pod: $!\n";
c333cfe7 263binmode GUTS;
94bdecf9 264print GUTS <<'END';
265=head1 NAME
266
267perlintern - autogenerated documentation of purely B<internal>
268 Perl functions
269
270=head1 DESCRIPTION
d8c40edc 271X<internal Perl functions> X<interpreter functions>
94bdecf9 272
273This file is the autogenerated documentation of functions in the
274Perl interpreter that are documented using Perl's internal documentation
275format but are not marked as part of the Perl API. In other words,
276B<they are not for use in extensions>!
277
278END
279
280for $key (sort { uc($a) cmp uc($b); } keys %gutsdocs) {
281 my $section = $gutsdocs{$key};
282 print GUTS "\n=head1 $key\n\n=over 8\n\n";
283 for my $key (sort { uc($a) cmp uc($b); } keys %$section) {
284 docout(\*GUTS, $key, $section->{$key});
285 }
286 print GUTS "\n=back\n";
287}
288
289print GUTS <<'END';
290
291=head1 AUTHORS
292
293The autodocumentation system was originally added to the Perl core by
294Benjamin Stuhl. Documentation is by whoever was kind enough to
295document their functions.
296
297=head1 SEE ALSO
298
299perlguts(1), perlapi(1)
300
301END
302
36bb303b 303close GUTS or die "Error closing pod/perlintern.pod: $!";