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