This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge %apidocs and %gutsdocs into $docs{api} and $docs{guts}.
[perl5.git] / autodoc.pl
1 #!/usr/bin/perl -w
2
3 # Unconditionally regenerate:
4 #
5 #    pod/perlintern.pod
6 #    pod/perlapi.pod
7 #
8 # from information stored in
9 #
10 #    embed.fnc
11 #    plus all the .c and .h files listed in MANIFEST
12 #
13 # Has an optional arg, which is the directory to chdir to before reading
14 # MANIFEST and *.[ch].
15 #
16 # This script is normally invoked as part of 'make all', but is also
17 # called from from regen.pl.
18
19 use strict;
20
21 #
22 # See database of global and static function prototypes in embed.fnc
23 # This is used to generate prototype headers under various configurations,
24 # export symbols lists for different platforms, and macros to provide an
25 # implicit interpreter context argument.
26 #
27
28 my %docs;
29 my %docfuncs;
30 my %seenfuncs;
31
32 my $curheader = "Unknown section";
33
34 sub autodoc ($$) { # parse a file and extract documentation info
35     my($fh,$file) = @_;
36     my($in, $doc, $line);
37 FUNC:
38     while (defined($in = <$fh>)) {
39         if ($in=~ /^=head1 (.*)/) {
40             $curheader = $1;
41             next FUNC;
42         }
43         $line++;
44         if ($in =~ /^=for\s+apidoc\s+(.*?)\s*\n/) {
45             my $proto = $1;
46             $proto = "||$proto" unless $proto =~ /\|/;
47             my($flags, $ret, $name, @args) = split /\|/, $proto;
48             my $docs = "";
49 DOC:
50             while (defined($doc = <$fh>)) {
51                 $line++;
52                 last DOC if $doc =~ /^=\w+/;
53                 if ($doc =~ m:^\*/$:) {
54                     warn "=cut missing? $file:$line:$doc";;
55                     last DOC;
56                 }
57                 $docs .= $doc;
58             }
59             $docs = "\n$docs" if $docs and $docs !~ /^\n/;
60             if ($flags =~ /m/) {
61                 if ($flags =~ /A/) {
62                     $docs{api}{$curheader}{$name} = [$flags, $docs, $ret, $file, @args];
63                 }
64                 else {
65                     $docs{guts}{$curheader}{$name} = [$flags, $docs, $ret, $file, @args];
66                 }
67             }
68             else {
69                 $docfuncs{$name} = [$flags, $docs, $ret, $file, $curheader, @args];
70             }
71             $seenfuncs{$name} = 1;
72             if (defined $doc) {
73                 if ($doc =~ /^=(?:for|head)/) {
74                     $in = $doc;
75                     redo FUNC;
76                 }
77             } else {
78                 warn "$file:$line:$in";
79             }
80         }
81     }
82 }
83
84 sub docout ($$$) { # output the docs for one function
85     my($fh, $name, $docref) = @_;
86     my($flags, $docs, $ret, $file, @args) = @$docref;
87     $name =~ s/\s*$//;
88
89     $docs .= "NOTE: this function is experimental and may change or be
90 removed without notice.\n\n" if $flags =~ /x/;
91     $docs .= "NOTE: the perl_ form of this function is deprecated.\n\n"
92         if $flags =~ /p/;
93
94     print $fh "=item $name\nX<$name>\n$docs";
95
96     if ($flags =~ /U/) { # no usage
97         # nothing
98     } elsif ($flags =~ /s/) { # semicolon ("dTHR;")
99         print $fh "\t\t$name;\n\n";
100     } elsif ($flags =~ /n/) { # no args
101         print $fh "\t$ret\t$name\n\n";
102     } else { # full usage
103         print $fh "\t$ret\t$name";
104         print $fh "(" . join(", ", @args) . ")";
105         print $fh "\n\n";
106     }
107     print $fh "=for hackers\nFound in file $file\n\n";
108 }
109
110 sub output {
111     my ($podname, $header, $dochash, $footer) = @_;
112     my $filename = "pod/$podname.pod";
113     open my $fh, '>', $filename or die "Can't open $filename: $!";
114
115     print $fh <<"_EOH_", $header;
116 -*- buffer-read-only: t -*-
117
118 !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
119 This file is built by $0 extracting documentation from the C source
120 files.
121
122 _EOH_
123
124     my $key;
125     # case insensitive sort, with fallback for determinacy
126     for $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$dochash) {
127         my $section = $dochash->{$key}; 
128         print $fh "\n=head1 $key\n\n=over 8\n\n";
129         # Again, fallback for determinacy
130         for my $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$section) {
131             docout($fh, $key, $section->{$key});
132         }
133         print $fh "\n=back\n";
134     }
135
136     print $fh $footer, <<'_EOF_';
137 =cut
138
139  ex: set ro:
140 _EOF_
141
142     close $fh or die "Can't close $filename: $!";
143 }
144
145 if (@ARGV) {
146     my $workdir = shift;
147     chdir $workdir
148         or die "Couldn't chdir to '$workdir': $!";
149 }
150
151 my $file;
152 # glob() picks up docs from extra .c or .h files that may be in unclean
153 # development trees.
154 my $MANIFEST = do {
155   local ($/, *FH);
156   open FH, "MANIFEST" or die "Can't open MANIFEST: $!";
157   <FH>;
158 };
159
160 for $file (($MANIFEST =~ /^(\S+\.c)\t/gm), ($MANIFEST =~ /^(\S+\.h)\t/gm)) {
161     open F, "< $file" or die "Cannot open $file for docs: $!\n";
162     $curheader = "Functions in file $file\n";
163     autodoc(\*F,$file);
164     close F or die "Error closing $file: $!\n";
165 }
166
167 open IN, "embed.fnc" or die $!;
168
169 # walk table providing an array of components in each line to
170 # subroutine, printing the result
171
172 while (<IN>) {
173     chomp;
174     next if /^:/;
175     while (s|\\\s*$||) {
176         $_ .= <IN>;
177         chomp;
178     }
179     s/\s+$//;
180     next if /^\s*(#|$)/;
181
182     my ($flags, $retval, $func, @args) = split /\s*\|\s*/, $_;
183
184     next unless $flags =~ /d/;
185     next unless $func;
186
187     s/\b(NN|NULLOK)\b\s+//g for @args;
188     $func =~ s/\t//g; # clean up fields from embed.pl
189     $retval =~ s/\t//;
190
191     my $docref = delete $docfuncs{$func};
192     if ($docref and @$docref) {
193         if ($flags =~ /A/) {
194             $docref->[0].="x" if $flags =~ /M/;
195             $docs{api}{$docref->[4]}{$func} =
196                 [$docref->[0] . 'A', $docref->[1], $retval, $docref->[3],
197                  @args];
198         } else {
199             $docs{guts}{$docref->[4]}{$func} =
200                 [$docref->[0], $docref->[1], $retval, $docref->[3], @args];
201         }
202     }
203     else {
204         warn "no docs for $func\n" unless $seenfuncs{$func};
205     }
206 }
207
208 for (sort keys %docfuncs) {
209     # Have you used a full for apidoc or just a func name?
210     # Have you used Ap instead of Am in the for apidoc?
211     warn "Unable to place $_!\n";
212 }
213
214 output('perlapi', <<'_EOB_', $docs{api}, <<'_EOE_');
215 =head1 NAME
216
217 perlapi - autogenerated documentation for the perl public API
218
219 =head1 DESCRIPTION
220 X<Perl API> X<API> X<api>
221
222 This file contains the documentation of the perl public API generated by
223 embed.pl, specifically a listing of functions, macros, flags, and variables
224 that may be used by extension writers.  The interfaces of any functions that
225 are not listed here are subject to change without notice.  For this reason,
226 blindly using functions listed in proto.h is to be avoided when writing
227 extensions.
228
229 Note that all Perl API global variables must be referenced with the C<PL_>
230 prefix.  Some macros are provided for compatibility with the older,
231 unadorned names, but this support may be disabled in a future release.
232
233 Perl was originally written to handle US-ASCII only (that is characters
234 whose ordinal numbers are in the range 0 - 127).
235 And documentation and comments may still use the term ASCII, when
236 sometimes in fact the entire range from 0 - 255 is meant.
237
238 Note that Perl can be compiled and run under EBCDIC (See L<perlebcdic>)
239 or ASCII.  Most of the documentation (and even comments in the code)
240 ignore the EBCDIC possibility.  
241 For almost all purposes the differences are transparent.
242 As an example, under EBCDIC,
243 instead of UTF-8, UTF-EBCDIC is used to encode Unicode strings, and so
244 whenever this documentation refers to C<utf8>
245 (and variants of that name, including in function names),
246 it also (essentially transparently) means C<UTF-EBCDIC>.
247 But the ordinals of characters differ between ASCII, EBCDIC, and
248 the UTF- encodings, and a string encoded in UTF-EBCDIC may occupy more bytes
249 than in UTF-8.
250
251 Also, on some EBCDIC machines, functions that are documented as operating on
252 US-ASCII (or Basic Latin in Unicode terminology) may in fact operate on all
253 256 characters in the EBCDIC range, not just the subset corresponding to
254 US-ASCII.
255
256 The listing below is alphabetical, case insensitive.
257
258 _EOB_
259
260 =head1 AUTHORS
261
262 Until May 1997, this document was maintained by Jeff Okamoto
263 <okamoto@corp.hp.com>.  It is now maintained as part of Perl itself.
264
265 With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
266 Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
267 Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
268 Stephen McCamant, and Gurusamy Sarathy.
269
270 API Listing originally by Dean Roehrich <roehrich@cray.com>.
271
272 Updated to be autogenerated from comments in the source by Benjamin Stuhl.
273
274 =head1 SEE ALSO
275
276 perlguts(1), perlxs(1), perlxstut(1), perlintern(1)
277
278 _EOE_
279
280 output('perlintern', <<'END', $docs{guts}, <<'END');
281 =head1 NAME
282
283 perlintern - autogenerated documentation of purely B<internal>
284                  Perl functions
285
286 =head1 DESCRIPTION
287 X<internal Perl functions> X<interpreter functions>
288
289 This file is the autogenerated documentation of functions in the
290 Perl interpreter that are documented using Perl's internal documentation
291 format but are not marked as part of the Perl API. In other words,
292 B<they are not for use in extensions>!
293
294 END
295
296 =head1 AUTHORS
297
298 The autodocumentation system was originally added to the Perl core by
299 Benjamin Stuhl. Documentation is by whoever was kind enough to
300 document their functions.
301
302 =head1 SEE ALSO
303
304 perlguts(1), perlapi(1)
305
306 END