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