This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
autodoc.pl: Don't list undocumented deprecated fcns in API
[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.
151c3fe5
KW
18#
19# '=head1' are the only headings looked for. If the next line after the
20# heading begins with a word character, it is considered to be the first line
21# of documentation that applies to the heading itself. That is, it is output
22# immediately after the heading, before the first function, and not indented.
23# The next input line that is a pod directive terminates this heading-level
24# documentation.
94bdecf9 25
56a0c332 26use strict;
a64c954a 27
94bdecf9 28#
346f75ff 29# See database of global and static function prototypes in embed.fnc
94bdecf9
JH
30# This is used to generate prototype headers under various configurations,
31# export symbols lists for different platforms, and macros to provide an
32# implicit interpreter context argument.
33#
34
6a235718 35my %docs;
5ce57792
NC
36my %funcflags;
37my %macro = (
38 ax => 1,
39 items => 1,
40 ix => 1,
41 svtype => 1,
42 );
43my %missing;
94bdecf9
JH
44
45my $curheader = "Unknown section";
46
47sub autodoc ($$) { # parse a file and extract documentation info
48 my($fh,$file) = @_;
151c3fe5 49 my($in, $doc, $line, $header_doc);
94bdecf9
JH
50FUNC:
51 while (defined($in = <$fh>)) {
5ce57792
NC
52 if ($in =~ /^#\s*define\s+([A-Za-z_][A-Za-z_0-9]+)\(/ &&
53 ($file ne 'embed.h' || $file ne 'proto.h')) {
54 $macro{$1} = $file;
55 next FUNC;
56 }
94bdecf9
JH
57 if ($in=~ /^=head1 (.*)/) {
58 $curheader = $1;
151c3fe5
KW
59
60 # If the next line begins with a word char, then is the start of
61 # heading-level documentation.
62 if (defined($doc = <$fh>)) {
63 if ($doc !~ /^\w/) {
64 $in = $doc;
65 redo FUNC;
66 }
67 $header_doc = $doc;
68 $line++;
69
70 # Continue getting the heading-level documentation until read
71 # in any pod directive (or as a fail-safe, find a closing
72 # comment to this pod in a C language file
73HDR_DOC:
74 while (defined($doc = <$fh>)) {
75 if ($doc =~ /^=\w/) {
76 $in = $doc;
77 redo FUNC;
78 }
79 $line++;
80
81 if ($doc =~ m:^\s*\*/$:) {
82 warn "=cut missing? $file:$line:$doc";;
83 last HDR_DOC;
84 }
85 $header_doc .= $doc;
86 }
87 }
94bdecf9
JH
88 next FUNC;
89 }
90 $line++;
78c9d763 91 if ($in =~ /^=for\s+apidoc\s+(.*?)\s*\n/) {
94bdecf9
JH
92 my $proto = $1;
93 $proto = "||$proto" unless $proto =~ /\|/;
94 my($flags, $ret, $name, @args) = split /\|/, $proto;
95 my $docs = "";
96DOC:
97 while (defined($doc = <$fh>)) {
94bdecf9
JH
98 $line++;
99 last DOC if $doc =~ /^=\w+/;
100 if ($doc =~ m:^\*/$:) {
101 warn "=cut missing? $file:$line:$doc";;
102 last DOC;
103 }
104 $docs .= $doc;
105 }
106 $docs = "\n$docs" if $docs and $docs !~ /^\n/;
5ce57792
NC
107
108 # Check the consistency of the flags
109 my ($embed_where, $inline_where);
110 my ($embed_may_change, $inline_may_change);
111
112 my $docref = delete $funcflags{$name};
113 if ($docref and %$docref) {
114 $embed_where = $docref->{flags} =~ /A/ ? 'api' : 'guts';
115 $embed_may_change = $docref->{flags} =~ /M/;
d4e99c76 116 $flags .= 'D' if $docref->{flags} =~ /D/;
5ce57792
NC
117 } else {
118 $missing{$name} = $file;
94bdecf9 119 }
5ce57792
NC
120 if ($flags =~ /m/) {
121 $inline_where = $flags =~ /A/ ? 'api' : 'guts';
122 $inline_may_change = $flags =~ /x/;
123
124 if (defined $embed_where && $inline_where ne $embed_where) {
125 warn "Function '$name' inconsistency: embed.fnc says $embed_where, Pod says $inline_where";
126 }
127
128 if (defined $embed_may_change
129 && $inline_may_change ne $embed_may_change) {
130 my $message = "Function '$name' inconsistency: ";
131 if ($embed_may_change) {
132 $message .= "embed.fnc says 'may change', Pod does not";
133 } else {
134 $message .= "Pod says 'may change', embed.fnc does not";
135 }
136 warn $message;
137 }
138 } elsif (!defined $embed_where) {
139 warn "Unable to place $name!\n";
140 next;
141 } else {
142 $inline_where = $embed_where;
143 $flags .= 'x' if $embed_may_change;
144 @args = @{$docref->{args}};
145 $ret = $docref->{retval};
94bdecf9 146 }
5ce57792
NC
147
148 $docs{$inline_where}{$curheader}{$name}
149 = [$flags, $docs, $ret, $file, @args];
150
151c3fe5
KW
151 # Create a special entry with an empty-string name for the
152 # heading-level documentation.
153 if (defined $header_doc) {
154 $docs{$inline_where}{$curheader}{""} = $header_doc;
155 undef $header_doc;
156 }
157
94bdecf9 158 if (defined $doc) {
e509e693 159 if ($doc =~ /^=(?:for|head)/) {
94bdecf9
JH
160 $in = $doc;
161 redo FUNC;
162 }
163 } else {
164 warn "$file:$line:$in";
165 }
166 }
167 }
168}
169
170sub docout ($$$) { # output the docs for one function
171 my($fh, $name, $docref) = @_;
172 my($flags, $docs, $ret, $file, @args) = @$docref;
d8c40edc 173 $name =~ s/\s*$//;
94bdecf9 174
d4e99c76
KW
175 if ($flags =~ /D/) {
176 $docs = "\n\nDEPRECATED! It is planned to remove this function from a
177future release of Perl. Do not use it for new code; remove it from
178existing code.\n\n$docs";
179 }
180 else {
181 $docs .= "NOTE: this function is experimental and may change or be
94bdecf9 182removed without notice.\n\n" if $flags =~ /x/;
d4e99c76 183 }
94bdecf9
JH
184 $docs .= "NOTE: the perl_ form of this function is deprecated.\n\n"
185 if $flags =~ /p/;
5afac1eb
BM
186 $docs .= "NOTE: this function must be explicitly called as Perl_$name with an aTHX_ parameter.\n\n"
187 if $flags =~ /o/;
94bdecf9 188
d8c40edc 189 print $fh "=item $name\nX<$name>\n$docs";
94bdecf9
JH
190
191 if ($flags =~ /U/) { # no usage
192 # nothing
193 } elsif ($flags =~ /s/) { # semicolon ("dTHR;")
194 print $fh "\t\t$name;\n\n";
195 } elsif ($flags =~ /n/) { # no args
196 print $fh "\t$ret\t$name\n\n";
197 } else { # full usage
dee6204d
FC
198 my $p = $flags =~ /o/; # no #define foo Perl_foo
199 my $n = "Perl_"x$p . $name;
200 my $large_ret = length $ret > 7;
201 my $indent_size = 7+8 # nroff: 7 under =head + 8 under =item
202 +8+($large_ret ? 1 + length $ret : 8)
203 +length($n) + 1;
204 my $indent;
205 print $fh "\t$ret" . ($large_ret ? ' ' : "\t") . "$n(";
06e9ce89
FC
206 my $long_args;
207 for (@args) {
d2086f64 208 if ($indent_size + 2 + length > 79) {
06e9ce89
FC
209 $long_args=1;
210 $indent_size -= length($n) - 3;
211 last;
212 }
213 }
214 my $args = '';
215 if ($p) {
216 $args = @args ? "pTHX_ " : "pTHX";
217 if ($long_args) { print $fh $args; $args = '' }
218 }
219 $long_args and print $fh "\n";
220 my $first = !$long_args;
dee6204d
FC
221 while () {
222 if (!@args or
223 length $args
d2086f64 224 && $indent_size + 3 + length($args[0]) + length $args > 79
dee6204d
FC
225 ) {
226 print $fh
227 $first ? '' : (
228 $indent //=
229 "\t".($large_ret ? " " x (1+length $ret) : "\t")
06e9ce89 230 ." "x($long_args ? 4 : 1 + length $n)
dee6204d
FC
231 ),
232 $args, (","x($args ne 'pTHX_ ') . "\n")x!!@args;
233 $args = $first = '';
234 }
235 @args or last;
236 $args .= ", "x!!(length $args && $args ne 'pTHX_ ')
237 . shift @args;
238 }
06e9ce89 239 if ($long_args) { print $fh "\n", substr $indent, 0, -4 }
dee6204d 240 print $fh ")\n\n";
94bdecf9
JH
241 }
242 print $fh "=for hackers\nFound in file $file\n\n";
243}
244
7b73ff98 245sub output {
5a0155e6 246 my ($podname, $header, $dochash, $missing, $footer) = @_;
7b73ff98
NC
247 my $filename = "pod/$podname.pod";
248 open my $fh, '>', $filename or die "Can't open $filename: $!";
249
250 print $fh <<"_EOH_", $header;
e0492643
NC
251-*- buffer-read-only: t -*-
252
253!!!!!!! DO NOT EDIT THIS FILE !!!!!!!
254This file is built by $0 extracting documentation from the C source
255files.
256
257_EOH_
e0492643 258
7b73ff98
NC
259 my $key;
260 # case insensitive sort, with fallback for determinacy
261 for $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$dochash) {
262 my $section = $dochash->{$key};
151c3fe5
KW
263 print $fh "\n=head1 $key\n\n";
264
265 # Output any heading-level documentation and delete so won't get in
266 # the way later
267 if (exists $section->{""}) {
268 print $fh $section->{""} . "\n";
269 delete $section->{""};
270 }
271 print $fh "=over 8\n\n";
272
7b73ff98
NC
273 # Again, fallback for determinacy
274 for my $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$section) {
275 docout($fh, $key, $section->{$key});
276 }
277 print $fh "\n=back\n";
278 }
279
5a0155e6 280 if (@$missing) {
a23e6e20 281 print $fh "\n=head1 Undocumented functions\n\n";
2616800a 282 print $fh $podname eq 'perlapi' ? <<'_EOB_' : <<'_EOB_';
474d0ac8
DM
283The following functions have been flagged as part of the public API,
284but are currently undocumented. Use them at your own risk, as the
ba4591a5
KW
285interfaces are subject to change. Functions that are not listed in this
286document are not intended for public use, and should NOT be used under any
287circumstances.
288
289If you use one of the undocumented functions below, you may wish to consider
290creating and submitting documentation for it. If your patch is accepted, this
291will indicate that the interface is stable (unless it is explicitly marked
292otherwise).
cf5f2f8f
KW
293
294=over
295
296_EOB_
2616800a
FC
297The following functions are currently undocumented. If you use one of
298them, you may wish to consider creating and submitting documentation for
299it.
300
301=over
302
303_EOB_
cf5f2f8f
KW
304 for my $missing (sort @$missing) {
305 print $fh "=item $missing\nX<$missing>\n\n";
5a0155e6 306 }
cf5f2f8f
KW
307 print $fh "=back\n\n";
308}
5a0155e6 309
cf5f2f8f 310print $fh $footer, <<'_EOF_';
e0492643
NC
311=cut
312
3f98fbb3 313 ex: set ro:
e0492643 314_EOF_
7b73ff98
NC
315
316 close $fh or die "Can't close $filename: $!";
e0492643
NC
317}
318
cd093254
MM
319if (@ARGV) {
320 my $workdir = shift;
321 chdir $workdir
322 or die "Couldn't chdir to '$workdir': $!";
323}
324
bc350081
NC
325open IN, "embed.fnc" or die $!;
326
bc350081
NC
327while (<IN>) {
328 chomp;
329 next if /^:/;
330 while (s|\\\s*$||) {
331 $_ .= <IN>;
332 chomp;
333 }
334 s/\s+$//;
335 next if /^\s*(#|$)/;
336
337 my ($flags, $retval, $func, @args) = split /\s*\|\s*/, $_;
338
bc350081
NC
339 next unless $func;
340
341 s/\b(NN|NULLOK)\b\s+//g for @args;
342 $func =~ s/\t//g; # clean up fields from embed.pl
343 $retval =~ s/\t//;
344
5ce57792
NC
345 $funcflags{$func} = {
346 flags => $flags,
347 retval => $retval,
348 args => \@args,
349 };
350}
351
352my $file;
353# glob() picks up docs from extra .c or .h files that may be in unclean
354# development trees.
355my $MANIFEST = do {
356 local ($/, *FH);
357 open FH, "MANIFEST" or die "Can't open MANIFEST: $!";
358 <FH>;
359};
360
361for $file (($MANIFEST =~ /^(\S+\.c)\t/gm), ($MANIFEST =~ /^(\S+\.h)\t/gm)) {
362 open F, "< $file" or die "Cannot open $file for docs: $!\n";
363 $curheader = "Functions in file $file\n";
364 autodoc(\*F,$file);
365 close F or die "Error closing $file: $!\n";
366}
367
368for (sort keys %funcflags) {
369 next unless $funcflags{$_}{flags} =~ /d/;
370 warn "no docs for $_\n"
bc350081 371}
94bdecf9 372
5ce57792
NC
373foreach (sort keys %missing) {
374 next if $macro{$_};
375 # Heuristics for known not-a-function macros:
376 next if /^[A-Z]/;
377 next if /^dj?[A-Z]/;
378
379 warn "Function '$_', documented in $missing{$_}, not listed in embed.fnc";
94bdecf9
JH
380}
381
5ce57792
NC
382# walk table providing an array of components in each line to
383# subroutine, printing the result
384
8c869419
KW
385# List of funcs in the public API that aren't also marked as experimental nor
386# deprecated.
387my @missing_api = grep $funcflags{$_}{flags} =~ /A/ && $funcflags{$_}{flags} !~ /[MD]/ && !$docs{api}{$_}, keys %funcflags;
5a0155e6 388output('perlapi', <<'_EOB_', $docs{api}, \@missing_api, <<'_EOE_');
94bdecf9
JH
389=head1 NAME
390
391perlapi - autogenerated documentation for the perl public API
392
393=head1 DESCRIPTION
d8c40edc 394X<Perl API> X<API> X<api>
94bdecf9
JH
395
396This file contains the documentation of the perl public API generated by
ef9741a5 397F<embed.pl>, specifically a listing of functions, macros, flags, and variables
cf5f2f8f
KW
398that may be used by extension writers. L<At the end|/Undocumented functions>
399is a list of functions which have yet to be documented. The interfaces of
400those are subject to change without notice. Any functions not listed here are
401not part of the public API, and should not be used by extension writers at
402all. For these reasons, blindly using functions listed in proto.h is to be
403avoided when writing extensions.
94bdecf9
JH
404
405Note that all Perl API global variables must be referenced with the C<PL_>
406prefix. Some macros are provided for compatibility with the older,
407unadorned names, but this support may be disabled in a future release.
408
2bbc8d55
SP
409Perl was originally written to handle US-ASCII only (that is characters
410whose ordinal numbers are in the range 0 - 127).
411And documentation and comments may still use the term ASCII, when
412sometimes in fact the entire range from 0 - 255 is meant.
413
414Note that Perl can be compiled and run under EBCDIC (See L<perlebcdic>)
415or ASCII. Most of the documentation (and even comments in the code)
416ignore the EBCDIC possibility.
417For almost all purposes the differences are transparent.
418As an example, under EBCDIC,
419instead of UTF-8, UTF-EBCDIC is used to encode Unicode strings, and so
420whenever this documentation refers to C<utf8>
421(and variants of that name, including in function names),
422it also (essentially transparently) means C<UTF-EBCDIC>.
423But the ordinals of characters differ between ASCII, EBCDIC, and
424the UTF- encodings, and a string encoded in UTF-EBCDIC may occupy more bytes
425than in UTF-8.
426
2bbc8d55 427The listing below is alphabetical, case insensitive.
94bdecf9
JH
428
429_EOB_
430
94bdecf9
JH
431=head1 AUTHORS
432
433Until May 1997, this document was maintained by Jeff Okamoto
434<okamoto@corp.hp.com>. It is now maintained as part of Perl itself.
435
436With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
437Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
438Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
439Stephen McCamant, and Gurusamy Sarathy.
440
441API Listing originally by Dean Roehrich <roehrich@cray.com>.
442
443Updated to be autogenerated from comments in the source by Benjamin Stuhl.
444
445=head1 SEE ALSO
446
b92fc6c1 447L<perlguts>, L<perlxs>, L<perlxstut>, L<perlintern>
94bdecf9
JH
448
449_EOE_
450
79fc8511
FC
451# List of non-static internal functions
452my @missing_guts =
453 grep $funcflags{$_}{flags} !~ /[As]/ && !$docs{guts}{$_}, keys %funcflags;
5a0155e6
TC
454
455output('perlintern', <<'END', $docs{guts}, \@missing_guts, <<'END');
94bdecf9
JH
456=head1 NAME
457
458perlintern - autogenerated documentation of purely B<internal>
459 Perl functions
460
461=head1 DESCRIPTION
d8c40edc 462X<internal Perl functions> X<interpreter functions>
94bdecf9
JH
463
464This file is the autogenerated documentation of functions in the
465Perl interpreter that are documented using Perl's internal documentation
466format but are not marked as part of the Perl API. In other words,
467B<they are not for use in extensions>!
468
469END
470
94bdecf9
JH
471=head1 AUTHORS
472
473The autodocumentation system was originally added to the Perl core by
474Benjamin Stuhl. Documentation is by whoever was kind enough to
475document their functions.
476
477=head1 SEE ALSO
478
b92fc6c1 479L<perlguts>, L<perlapi>
94bdecf9
JH
480
481END