This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge branch 'blead' of ssh://stevep@perl5.git.perl.org/perl into blead
[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/;
5afac1eb
BM
135 $docs .= "NOTE: this function must be explicitly called as Perl_$name with an aTHX_ parameter.\n\n"
136 if $flags =~ /o/;
94bdecf9 137
d8c40edc 138 print $fh "=item $name\nX<$name>\n$docs";
94bdecf9
JH
139
140 if ($flags =~ /U/) { # no usage
141 # nothing
142 } elsif ($flags =~ /s/) { # semicolon ("dTHR;")
143 print $fh "\t\t$name;\n\n";
144 } elsif ($flags =~ /n/) { # no args
145 print $fh "\t$ret\t$name\n\n";
5afac1eb
BM
146 } elsif ($flags =~ /o/) { # no #define foo Perl_foo
147 print $fh "\t$ret\tPerl_$name";
148 print $fh "(" . (@args ? "pTHX_ " : "pTHX");
149 print $fh join(", ", @args) . ")\n\n";
94bdecf9
JH
150 } else { # full usage
151 print $fh "\t$ret\t$name";
152 print $fh "(" . join(", ", @args) . ")";
153 print $fh "\n\n";
154 }
155 print $fh "=for hackers\nFound in file $file\n\n";
156}
157
7b73ff98 158sub output {
5a0155e6 159 my ($podname, $header, $dochash, $missing, $footer) = @_;
7b73ff98
NC
160 my $filename = "pod/$podname.pod";
161 open my $fh, '>', $filename or die "Can't open $filename: $!";
162
163 print $fh <<"_EOH_", $header;
e0492643
NC
164-*- buffer-read-only: t -*-
165
166!!!!!!! DO NOT EDIT THIS FILE !!!!!!!
167This file is built by $0 extracting documentation from the C source
168files.
169
170_EOH_
e0492643 171
7b73ff98
NC
172 my $key;
173 # case insensitive sort, with fallback for determinacy
174 for $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$dochash) {
175 my $section = $dochash->{$key};
176 print $fh "\n=head1 $key\n\n=over 8\n\n";
177 # Again, fallback for determinacy
178 for my $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$section) {
179 docout($fh, $key, $section->{$key});
180 }
181 print $fh "\n=back\n";
182 }
183
5a0155e6 184 if (@$missing) {
a23e6e20 185 print $fh "\n=head1 Undocumented functions\n\n";
5a0155e6
TC
186 print $fh "These functions are currently undocumented:\n\n=over\n\n";
187 for my $missing (sort @$missing) {
188 print $fh "=item $missing\nX<$missing>\n\n";
189 }
190 print $fh "=back\n\n";
191 }
192
7b73ff98 193 print $fh $footer, <<'_EOF_';
e0492643
NC
194=cut
195
3f98fbb3 196 ex: set ro:
e0492643 197_EOF_
7b73ff98
NC
198
199 close $fh or die "Can't close $filename: $!";
e0492643
NC
200}
201
cd093254
MM
202if (@ARGV) {
203 my $workdir = shift;
204 chdir $workdir
205 or die "Couldn't chdir to '$workdir': $!";
206}
207
bc350081
NC
208open IN, "embed.fnc" or die $!;
209
bc350081
NC
210while (<IN>) {
211 chomp;
212 next if /^:/;
213 while (s|\\\s*$||) {
214 $_ .= <IN>;
215 chomp;
216 }
217 s/\s+$//;
218 next if /^\s*(#|$)/;
219
220 my ($flags, $retval, $func, @args) = split /\s*\|\s*/, $_;
221
bc350081
NC
222 next unless $func;
223
224 s/\b(NN|NULLOK)\b\s+//g for @args;
225 $func =~ s/\t//g; # clean up fields from embed.pl
226 $retval =~ s/\t//;
227
5ce57792
NC
228 $funcflags{$func} = {
229 flags => $flags,
230 retval => $retval,
231 args => \@args,
232 };
233}
234
235my $file;
236# glob() picks up docs from extra .c or .h files that may be in unclean
237# development trees.
238my $MANIFEST = do {
239 local ($/, *FH);
240 open FH, "MANIFEST" or die "Can't open MANIFEST: $!";
241 <FH>;
242};
243
244for $file (($MANIFEST =~ /^(\S+\.c)\t/gm), ($MANIFEST =~ /^(\S+\.h)\t/gm)) {
245 open F, "< $file" or die "Cannot open $file for docs: $!\n";
246 $curheader = "Functions in file $file\n";
247 autodoc(\*F,$file);
248 close F or die "Error closing $file: $!\n";
249}
250
251for (sort keys %funcflags) {
252 next unless $funcflags{$_}{flags} =~ /d/;
253 warn "no docs for $_\n"
bc350081 254}
94bdecf9 255
5ce57792
NC
256foreach (sort keys %missing) {
257 next if $macro{$_};
258 # Heuristics for known not-a-function macros:
259 next if /^[A-Z]/;
260 next if /^dj?[A-Z]/;
261
262 warn "Function '$_', documented in $missing{$_}, not listed in embed.fnc";
94bdecf9
JH
263}
264
5ce57792
NC
265# walk table providing an array of components in each line to
266# subroutine, printing the result
267
5a0155e6
TC
268my @missing_api = grep $funcflags{$_}{flags} =~ /A/ && !$docs{api}{$_}, keys %funcflags;
269output('perlapi', <<'_EOB_', $docs{api}, \@missing_api, <<'_EOE_');
94bdecf9
JH
270=head1 NAME
271
272perlapi - autogenerated documentation for the perl public API
273
274=head1 DESCRIPTION
d8c40edc 275X<Perl API> X<API> X<api>
94bdecf9
JH
276
277This file contains the documentation of the perl public API generated by
278embed.pl, specifically a listing of functions, macros, flags, and variables
279that may be used by extension writers. The interfaces of any functions that
280are not listed here are subject to change without notice. For this reason,
281blindly using functions listed in proto.h is to be avoided when writing
282extensions.
283
284Note that all Perl API global variables must be referenced with the C<PL_>
285prefix. Some macros are provided for compatibility with the older,
286unadorned names, but this support may be disabled in a future release.
287
2bbc8d55
SP
288Perl was originally written to handle US-ASCII only (that is characters
289whose ordinal numbers are in the range 0 - 127).
290And documentation and comments may still use the term ASCII, when
291sometimes in fact the entire range from 0 - 255 is meant.
292
293Note that Perl can be compiled and run under EBCDIC (See L<perlebcdic>)
294or ASCII. Most of the documentation (and even comments in the code)
295ignore the EBCDIC possibility.
296For almost all purposes the differences are transparent.
297As an example, under EBCDIC,
298instead of UTF-8, UTF-EBCDIC is used to encode Unicode strings, and so
299whenever this documentation refers to C<utf8>
300(and variants of that name, including in function names),
301it also (essentially transparently) means C<UTF-EBCDIC>.
302But the ordinals of characters differ between ASCII, EBCDIC, and
303the UTF- encodings, and a string encoded in UTF-EBCDIC may occupy more bytes
304than in UTF-8.
305
306Also, on some EBCDIC machines, functions that are documented as operating on
307US-ASCII (or Basic Latin in Unicode terminology) may in fact operate on all
308256 characters in the EBCDIC range, not just the subset corresponding to
309US-ASCII.
310
311The listing below is alphabetical, case insensitive.
94bdecf9
JH
312
313_EOB_
314
94bdecf9
JH
315=head1 AUTHORS
316
317Until May 1997, this document was maintained by Jeff Okamoto
318<okamoto@corp.hp.com>. It is now maintained as part of Perl itself.
319
320With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
321Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
322Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
323Stephen McCamant, and Gurusamy Sarathy.
324
325API Listing originally by Dean Roehrich <roehrich@cray.com>.
326
327Updated to be autogenerated from comments in the source by Benjamin Stuhl.
328
329=head1 SEE ALSO
330
b92fc6c1 331L<perlguts>, L<perlxs>, L<perlxstut>, L<perlintern>
94bdecf9
JH
332
333_EOE_
334
5a0155e6
TC
335my @missing_guts = grep $funcflags{$_}{flags} !~ /A/ && !$docs{guts}{$_}, keys %funcflags;
336
337output('perlintern', <<'END', $docs{guts}, \@missing_guts, <<'END');
94bdecf9
JH
338=head1 NAME
339
340perlintern - autogenerated documentation of purely B<internal>
341 Perl functions
342
343=head1 DESCRIPTION
d8c40edc 344X<internal Perl functions> X<interpreter functions>
94bdecf9
JH
345
346This file is the autogenerated documentation of functions in the
347Perl interpreter that are documented using Perl's internal documentation
348format but are not marked as part of the Perl API. In other words,
349B<they are not for use in extensions>!
350
351END
352
94bdecf9
JH
353=head1 AUTHORS
354
355The autodocumentation system was originally added to the Perl core by
356Benjamin Stuhl. Documentation is by whoever was kind enough to
357document their functions.
358
359=head1 SEE ALSO
360
b92fc6c1 361L<perlguts>, L<perlapi>
94bdecf9
JH
362
363END