No more late changes, dammit
[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 }
48 my @args;
49 if (/^\s*(#|$)/) {
50 @args = $_;
51 }
52 else {
53 @args = split /\s*\|\s*/, $_;
54 }
55 print $F $function->(@args);
56 }
57 print $F $trailer if $trailer;
36bb303b 58 unless (ref $filename) {
59 close $F or die "Error closing $filename: $!";
60 }
94bdecf9 61}
62
63my %apidocs;
64my %gutsdocs;
65my %docfuncs;
66
67my $curheader = "Unknown section";
68
69sub autodoc ($$) { # parse a file and extract documentation info
70 my($fh,$file) = @_;
71 my($in, $doc, $line);
72FUNC:
73 while (defined($in = <$fh>)) {
74 if ($in=~ /^=head1 (.*)/) {
75 $curheader = $1;
76 next FUNC;
77 }
78 $line++;
78c9d763 79 if ($in =~ /^=for\s+apidoc\s+(.*?)\s*\n/) {
94bdecf9 80 my $proto = $1;
81 $proto = "||$proto" unless $proto =~ /\|/;
82 my($flags, $ret, $name, @args) = split /\|/, $proto;
83 my $docs = "";
84DOC:
85 while (defined($doc = <$fh>)) {
94bdecf9 86 $line++;
87 last DOC if $doc =~ /^=\w+/;
88 if ($doc =~ m:^\*/$:) {
89 warn "=cut missing? $file:$line:$doc";;
90 last DOC;
91 }
92 $docs .= $doc;
93 }
94 $docs = "\n$docs" if $docs and $docs !~ /^\n/;
95 if ($flags =~ /m/) {
96 if ($flags =~ /A/) {
97 $apidocs{$curheader}{$name} = [$flags, $docs, $ret, $file, @args];
98 }
99 else {
100 $gutsdocs{$curheader}{$name} = [$flags, $docs, $ret, $file, @args];
101 }
102 }
103 else {
104 $docfuncs{$name} = [$flags, $docs, $ret, $file, $curheader, @args];
105 }
106 if (defined $doc) {
e509e693 107 if ($doc =~ /^=(?:for|head)/) {
94bdecf9 108 $in = $doc;
109 redo FUNC;
110 }
111 } else {
112 warn "$file:$line:$in";
113 }
114 }
115 }
116}
117
118sub docout ($$$) { # output the docs for one function
119 my($fh, $name, $docref) = @_;
120 my($flags, $docs, $ret, $file, @args) = @$docref;
121
122 $docs .= "NOTE: this function is experimental and may change or be
123removed without notice.\n\n" if $flags =~ /x/;
124 $docs .= "NOTE: the perl_ form of this function is deprecated.\n\n"
125 if $flags =~ /p/;
126
127 print $fh "=item $name\n$docs";
128
129 if ($flags =~ /U/) { # no usage
130 # nothing
131 } elsif ($flags =~ /s/) { # semicolon ("dTHR;")
132 print $fh "\t\t$name;\n\n";
133 } elsif ($flags =~ /n/) { # no args
134 print $fh "\t$ret\t$name\n\n";
135 } else { # full usage
136 print $fh "\t$ret\t$name";
137 print $fh "(" . join(", ", @args) . ")";
138 print $fh "\n\n";
139 }
140 print $fh "=for hackers\nFound in file $file\n\n";
141}
142
143my $file;
69e39a9a 144# glob() picks up docs from extra .c or .h files that may be in unclean
145# development trees.
146my $MANIFEST = do {
147 local ($/, *FH);
148 open FH, "MANIFEST" or die "Can't open MANIFEST: $!";
149 <FH>;
150};
151
152for $file (($MANIFEST =~ /^(\S+\.c)\t/gm), ($MANIFEST =~ /^(\S+\.h)\t/gm)) {
94bdecf9 153 open F, "< $file" or die "Cannot open $file for docs: $!\n";
154 $curheader = "Functions in file $file\n";
155 autodoc(\*F,$file);
156 close F or die "Error closing $file: $!\n";
157}
158
36bb303b 159safer_unlink "pod/perlapi.pod";
94bdecf9 160open (DOC, ">pod/perlapi.pod") or
161 die "Can't create pod/perlapi.pod: $!\n";
c333cfe7 162binmode DOC;
94bdecf9 163
164walk_table { # load documented functions into approriate hash
165 if (@_ > 1) {
166 my($flags, $retval, $func, @args) = @_;
167 return "" unless $flags =~ /d/;
168 $func =~ s/\t//g; $flags =~ s/p//; # clean up fields from embed.pl
169 $retval =~ s/\t//;
78c9d763 170 my $docref = delete $docfuncs{$func};
171 if ($docref and @$docref) {
172 if ($flags =~ /A/) {
173 $docref->[0].="x" if $flags =~ /M/;
174 $apidocs{$docref->[4]}{$func} =
175 [$docref->[0] . 'A', $docref->[1], $retval,
176 $docref->[3], @args];
177 } else {
178 $gutsdocs{$docref->[4]}{$func} =
179 [$docref->[0], $docref->[1], $retval, $docref->[3], @args];
180 }
181 }
182 else {
94bdecf9 183 warn "no docs for $func\n" unless $docref and @$docref;
94bdecf9 184 }
185 }
186 return "";
187} \*DOC;
188
189for (sort keys %docfuncs) {
190 # Have you used a full for apidoc or just a func name?
191 # Have you used Ap instead of Am in the for apidoc?
192 warn "Unable to place $_!\n";
193}
194
195print DOC <<'_EOB_';
196=head1 NAME
197
198perlapi - autogenerated documentation for the perl public API
199
200=head1 DESCRIPTION
201
202This file contains the documentation of the perl public API generated by
203embed.pl, specifically a listing of functions, macros, flags, and variables
204that may be used by extension writers. The interfaces of any functions that
205are not listed here are subject to change without notice. For this reason,
206blindly using functions listed in proto.h is to be avoided when writing
207extensions.
208
209Note that all Perl API global variables must be referenced with the C<PL_>
210prefix. Some macros are provided for compatibility with the older,
211unadorned names, but this support may be disabled in a future release.
212
213The listing is alphabetical, case insensitive.
214
215_EOB_
216
217my $key;
6a477168 218# case insensitive sort, with fallback for determinacy
219for $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %apidocs) {
94bdecf9 220 my $section = $apidocs{$key};
221 print DOC "\n=head1 $key\n\n=over 8\n\n";
222 for my $key (sort { uc($a) cmp uc($b); } keys %$section) {
223 docout(\*DOC, $key, $section->{$key});
224 }
225 print DOC "\n=back\n";
226}
227
228print DOC <<'_EOE_';
229
230=head1 AUTHORS
231
232Until May 1997, this document was maintained by Jeff Okamoto
233<okamoto@corp.hp.com>. It is now maintained as part of Perl itself.
234
235With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
236Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
237Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
238Stephen McCamant, and Gurusamy Sarathy.
239
240API Listing originally by Dean Roehrich <roehrich@cray.com>.
241
242Updated to be autogenerated from comments in the source by Benjamin Stuhl.
243
244=head1 SEE ALSO
245
246perlguts(1), perlxs(1), perlxstut(1), perlintern(1)
247
248_EOE_
249
250
36bb303b 251close(DOC) or die "Error closing pod/perlapi.pod: $!";
94bdecf9 252
36bb303b 253safer_unlink "pod/perlintern.pod";
94bdecf9 254open(GUTS, ">pod/perlintern.pod") or
255 die "Unable to create pod/perlintern.pod: $!\n";
c333cfe7 256binmode GUTS;
94bdecf9 257print GUTS <<'END';
258=head1 NAME
259
260perlintern - autogenerated documentation of purely B<internal>
261 Perl functions
262
263=head1 DESCRIPTION
264
265This file is the autogenerated documentation of functions in the
266Perl interpreter that are documented using Perl's internal documentation
267format but are not marked as part of the Perl API. In other words,
268B<they are not for use in extensions>!
269
270END
271
272for $key (sort { uc($a) cmp uc($b); } keys %gutsdocs) {
273 my $section = $gutsdocs{$key};
274 print GUTS "\n=head1 $key\n\n=over 8\n\n";
275 for my $key (sort { uc($a) cmp uc($b); } keys %$section) {
276 docout(\*GUTS, $key, $section->{$key});
277 }
278 print GUTS "\n=back\n";
279}
280
281print GUTS <<'END';
282
283=head1 AUTHORS
284
285The autodocumentation system was originally added to the Perl core by
286Benjamin Stuhl. Documentation is by whoever was kind enough to
287document their functions.
288
289=head1 SEE ALSO
290
291perlguts(1), perlapi(1)
292
293END
294
36bb303b 295close GUTS or die "Error closing pod/perlintern.pod: $!";