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