X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=autodoc.pl;h=042131e97606a566c15a9e7e7751f72162b4f4bc;hb=d2d1d4de13bedc11af82b2ca4fd580671530195c;hp=33c22232fa8a478925c671bfaf6bac30e1cfbe4d;hpb=346f75ffc624859cdc8927b1e206026c5a850b7c;p=p5sagit%2Fp5-mst-13.2.git diff --git a/autodoc.pl b/autodoc.pl index 33c2223..042131e 100644 --- a/autodoc.pl +++ b/autodoc.pl @@ -1,10 +1,22 @@ #!/usr/bin/perl -w +# +# Unconditionally regenerate: +# +# pod/perlintern.pod +# pod/perlapi.pod +# +# from information stored in +# +# embed.fnc +# plus all the .c and .h files listed in MANIFEST +# +# Has an optional arg, which is the directory to chdir to before reading +# MANIFEST and *.[ch]. +# +# This script is normally invoked as part of 'make all', but is also +# called from from regen.pl. -require 5.003; # keep this compatible, an old perl is all we may have before - # we build the new one - -BEGIN { push @INC, 'lib' } # glob() below requires File::Glob - +use strict; # # See database of global and static function prototypes in embed.fnc @@ -13,49 +25,10 @@ BEGIN { push @INC, 'lib' } # glob() below requires File::Glob # implicit interpreter context argument. # -open IN, "embed.fnc" or die $!; - -# walk table providing an array of components in each line to -# subroutine, printing the result -sub walk_table (&@) { - my $function = shift; - my $filename = shift || '-'; - my $leader = shift; - my $trailer = shift; - my $F; - local *F; - if (ref $filename) { # filehandle - $F = $filename; - } - else { - open F, ">$filename" or die "Can't open $filename: $!"; - $F = \*F; - } - print $F $leader if $leader; - seek IN, 0, 0; # so we may restart - while () { - chomp; - next if /^:/; - while (s|\\$||) { - $_ .= ; - chomp; - } - my @args; - if (/^\s*(#|$)/) { - @args = $_; - } - else { - @args = split /\s*\|\s*/, $_; - } - print $F $function->(@args); - } - print $F $trailer if $trailer; - close $F unless ref $filename; -} - my %apidocs; my %gutsdocs; my %docfuncs; +my %seenfuncs; my $curheader = "Unknown section"; @@ -69,17 +42,13 @@ FUNC: next FUNC; } $line++; - if ($in =~ /^=for\s+apidoc\s+(.*)\n/) { + if ($in =~ /^=for\s+apidoc\s+(.*?)\s*\n/) { my $proto = $1; $proto = "||$proto" unless $proto =~ /\|/; my($flags, $ret, $name, @args) = split /\|/, $proto; my $docs = ""; DOC: while (defined($doc = <$fh>)) { - if ($doc =~ /^=head1 (.*)/) { - $curheader = $1; - next DOC; - } $line++; last DOC if $doc =~ /^=\w+/; if ($doc =~ m:^\*/$:) { @@ -101,7 +70,7 @@ DOC: $docfuncs{$name} = [$flags, $docs, $ret, $file, $curheader, @args]; } if (defined $doc) { - if ($doc =~ /^=for/) { + if ($doc =~ /^=(?:for|head)/) { $in = $doc; redo FUNC; } @@ -115,13 +84,14 @@ DOC: sub docout ($$$) { # output the docs for one function my($fh, $name, $docref) = @_; my($flags, $docs, $ret, $file, @args) = @$docref; + $name =~ s/\s*$//; $docs .= "NOTE: this function is experimental and may change or be removed without notice.\n\n" if $flags =~ /x/; $docs .= "NOTE: the perl_ form of this function is deprecated.\n\n" if $flags =~ /p/; - print $fh "=item $name\n$docs"; + print $fh "=item $name\nX<$name>\n$docs"; if ($flags =~ /U/) { # no usage # nothing @@ -137,38 +107,104 @@ removed without notice.\n\n" if $flags =~ /x/; print $fh "=for hackers\nFound in file $file\n\n"; } +sub output { + my ($podname, $header, $dochash, $footer) = @_; + my $filename = "pod/$podname.pod"; + open my $fh, '>', $filename or die "Can't open $filename: $!"; + + print $fh <<"_EOH_", $header; +-*- buffer-read-only: t -*- + +!!!!!!! DO NOT EDIT THIS FILE !!!!!!! +This file is built by $0 extracting documentation from the C source +files. + +_EOH_ + + my $key; + # case insensitive sort, with fallback for determinacy + for $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$dochash) { + my $section = $dochash->{$key}; + print $fh "\n=head1 $key\n\n=over 8\n\n"; + # Again, fallback for determinacy + for my $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$section) { + docout($fh, $key, $section->{$key}); + } + print $fh "\n=back\n"; + } + + print $fh $footer, <<'_EOF_'; +=cut + + ex: set ro: +_EOF_ + + close $fh or die "Can't close $filename: $!"; +} + +if (@ARGV) { + my $workdir = shift; + chdir $workdir + or die "Couldn't chdir to '$workdir': $!"; +} + my $file; -for $file (glob('*.c'), glob('*.h')) { +# glob() picks up docs from extra .c or .h files that may be in unclean +# development trees. +my $MANIFEST = do { + local ($/, *FH); + open FH, "MANIFEST" or die "Can't open MANIFEST: $!"; + ; +}; + +for $file (($MANIFEST =~ /^(\S+\.c)\t/gm), ($MANIFEST =~ /^(\S+\.h)\t/gm)) { open F, "< $file" or die "Cannot open $file for docs: $!\n"; $curheader = "Functions in file $file\n"; autodoc(\*F,$file); close F or die "Error closing $file: $!\n"; } -unlink "pod/perlapi.pod"; -open (DOC, ">pod/perlapi.pod") or - die "Can't create pod/perlapi.pod: $!\n"; +open IN, "embed.fnc" or die $!; + +# walk table providing an array of components in each line to +# subroutine, printing the result -walk_table { # load documented functions into approriate hash - if (@_ > 1) { - my($flags, $retval, $func, @args) = @_; - return "" unless $flags =~ /d/; - $func =~ s/\t//g; $flags =~ s/p//; # clean up fields from embed.pl - $retval =~ s/\t//; +while () { + chomp; + next if /^:/; + while (s|\\\s*$||) { + $_ .= ; + chomp; + } + s/\s+$//; + next if /^\s*(#|$)/; + + my ($flags, $retval, $func, @args) = split /\s*\|\s*/, $_; + + next unless $flags =~ /d/; + next unless $func; + + s/\b(NN|NULLOK)\b\s+//g for @args; + $func =~ s/\t//g; # clean up fields from embed.pl + $retval =~ s/\t//; + + my $docref = delete $docfuncs{$func}; + $seenfuncs{$func} = 1; + if ($docref and @$docref) { if ($flags =~ /A/) { - my $docref = delete $docfuncs{$func}; - warn "no docs for $func\n" unless $docref and @$docref; - $docref->[0].="x" if $flags =~ /M/; - $apidocs{$docref->[4]}{$func} = - [$docref->[0] . 'A', $docref->[1], $retval, $docref->[3], @args]; + $docref->[0].="x" if $flags =~ /M/; + $apidocs{$docref->[4]}{$func} = + [$docref->[0] . 'A', $docref->[1], $retval, $docref->[3], + @args]; } else { - my $docref = delete $docfuncs{$func}; - $gutsdocs{$docref->[4]}{$func} = - [$docref->[0], $docref->[1], $retval, $docref->[3], @args]; + $gutsdocs{$docref->[4]}{$func} = + [$docref->[0], $docref->[1], $retval, $docref->[3], @args]; } } - return ""; -} \*DOC; + else { + warn "no docs for $func\n" unless $seenfuncs{$func}; + } +} for (sort keys %docfuncs) { # Have you used a full for apidoc or just a func name? @@ -176,12 +212,13 @@ for (sort keys %docfuncs) { warn "Unable to place $_!\n"; } -print DOC <<'_EOB_'; +output('perlapi', <<'_EOB_', \%apidocs, <<'_EOE_'); =head1 NAME perlapi - autogenerated documentation for the perl public API =head1 DESCRIPTION +X X X This file contains the documentation of the perl public API generated by embed.pl, specifically a listing of functions, macros, flags, and variables @@ -194,22 +231,33 @@ Note that all Perl API global variables must be referenced with the C prefix. Some macros are provided for compatibility with the older, unadorned names, but this support may be disabled in a future release. -The listing is alphabetical, case insensitive. +Perl was originally written to handle US-ASCII only (that is characters +whose ordinal numbers are in the range 0 - 127). +And documentation and comments may still use the term ASCII, when +sometimes in fact the entire range from 0 - 255 is meant. + +Note that Perl can be compiled and run under EBCDIC (See L) +or ASCII. Most of the documentation (and even comments in the code) +ignore the EBCDIC possibility. +For almost all purposes the differences are transparent. +As an example, under EBCDIC, +instead of UTF-8, UTF-EBCDIC is used to encode Unicode strings, and so +whenever this documentation refers to C +(and variants of that name, including in function names), +it also (essentially transparently) means C. +But the ordinals of characters differ between ASCII, EBCDIC, and +the UTF- encodings, and a string encoded in UTF-EBCDIC may occupy more bytes +than in UTF-8. + +Also, on some EBCDIC machines, functions that are documented as operating on +US-ASCII (or Basic Latin in Unicode terminology) may in fact operate on all +256 characters in the EBCDIC range, not just the subset corresponding to +US-ASCII. + +The listing below is alphabetical, case insensitive. _EOB_ -my $key; -for $key (sort { uc($a) cmp uc($b); } keys %apidocs) { # case insensitive sort - my $section = $apidocs{$key}; - print DOC "\n=head1 $key\n\n=over 8\n\n"; - for my $key (sort { uc($a) cmp uc($b); } keys %$section) { - docout(\*DOC, $key, $section->{$key}); - } - print DOC "\n=back\n"; -} - -print DOC <<'_EOE_'; - =head1 AUTHORS Until May 1997, this document was maintained by Jeff Okamoto @@ -230,18 +278,14 @@ perlguts(1), perlxs(1), perlxstut(1), perlintern(1) _EOE_ - -close(DOC); - -open(GUTS, ">pod/perlintern.pod") or - die "Unable to create pod/perlintern.pod: $!\n"; -print GUTS <<'END'; +output('perlintern', <<'END', \%gutsdocs, <<'END'); =head1 NAME perlintern - autogenerated documentation of purely B Perl functions =head1 DESCRIPTION +X X This file is the autogenerated documentation of functions in the Perl interpreter that are documented using Perl's internal documentation @@ -250,17 +294,6 @@ B! END -for $key (sort { uc($a) cmp uc($b); } keys %gutsdocs) { - my $section = $gutsdocs{$key}; - print GUTS "\n=head1 $key\n\n=over 8\n\n"; - for my $key (sort { uc($a) cmp uc($b); } keys %$section) { - docout(\*GUTS, $key, $section->{$key}); - } - print GUTS "\n=back\n"; -} - -print GUTS <<'END'; - =head1 AUTHORS The autodocumentation system was originally added to the Perl core by @@ -272,6 +305,3 @@ document their functions. perlguts(1), perlapi(1) END - -close GUTS; -