source: trunk/essentials/dev-lang/perl/autodoc.pl@ 3310

Last change on this file since 3310 was 3181, checked in by bird, 19 years ago

perl 5.8.8

File size: 7.8 KB
Line 
1#!/usr/bin/perl -w
2
3require 5.003; # keep this compatible, an old perl is all we may have before
4 # we build the new one
5
6BEGIN {
7 push @INC, 'lib';
8 require 'regen_lib.pl';
9}
10
11
12#
13# See database of global and static function prototypes in embed.fnc
14# This is used to generate prototype headers under various configurations,
15# export symbols lists for different platforms, and macros to provide an
16# implicit interpreter context argument.
17#
18
19open IN, "embed.fnc" or die $!;
20
21# walk table providing an array of components in each line to
22# subroutine, printing the result
23sub walk_table (&@) {
24 my $function = shift;
25 my $filename = shift || '-';
26 my $leader = shift;
27 my $trailer = shift;
28 my $F;
29 local *F;
30 if (ref $filename) { # filehandle
31 $F = $filename;
32 }
33 else {
34 safer_unlink $filename;
35 open F, ">$filename" or die "Can't open $filename: $!";
36 binmode F;
37 $F = \*F;
38 }
39 print $F $leader if $leader;
40 seek IN, 0, 0; # so we may restart
41 while (<IN>) {
42 chomp;
43 next if /^:/;
44 while (s|\\\s*$||) {
45 $_ .= <IN>;
46 chomp;
47 }
48 s/\s+$//;
49 my @args;
50 if (/^\s*(#|$)/) {
51 @args = $_;
52 }
53 else {
54 @args = split /\s*\|\s*/, $_;
55 }
56 s/\b(NN|NULLOK)\b\s+//g for @args;
57 print $F $function->(@args);
58 }
59 print $F $trailer if $trailer;
60 unless (ref $filename) {
61 close $F or die "Error closing $filename: $!";
62 }
63}
64
65my %apidocs;
66my %gutsdocs;
67my %docfuncs;
68
69my $curheader = "Unknown section";
70
71sub autodoc ($$) { # parse a file and extract documentation info
72 my($fh,$file) = @_;
73 my($in, $doc, $line);
74FUNC:
75 while (defined($in = <$fh>)) {
76 if ($in=~ /^=head1 (.*)/) {
77 $curheader = $1;
78 next FUNC;
79 }
80 $line++;
81 if ($in =~ /^=for\s+apidoc\s+(.*?)\s*\n/) {
82 my $proto = $1;
83 $proto = "||$proto" unless $proto =~ /\|/;
84 my($flags, $ret, $name, @args) = split /\|/, $proto;
85 my $docs = "";
86DOC:
87 while (defined($doc = <$fh>)) {
88 $line++;
89 last DOC if $doc =~ /^=\w+/;
90 if ($doc =~ m:^\*/$:) {
91 warn "=cut missing? $file:$line:$doc";;
92 last DOC;
93 }
94 $docs .= $doc;
95 }
96 $docs = "\n$docs" if $docs and $docs !~ /^\n/;
97 if ($flags =~ /m/) {
98 if ($flags =~ /A/) {
99 $apidocs{$curheader}{$name} = [$flags, $docs, $ret, $file, @args];
100 }
101 else {
102 $gutsdocs{$curheader}{$name} = [$flags, $docs, $ret, $file, @args];
103 }
104 }
105 else {
106 $docfuncs{$name} = [$flags, $docs, $ret, $file, $curheader, @args];
107 }
108 if (defined $doc) {
109 if ($doc =~ /^=(?:for|head)/) {
110 $in = $doc;
111 redo FUNC;
112 }
113 } else {
114 warn "$file:$line:$in";
115 }
116 }
117 }
118}
119
120sub docout ($$$) { # output the docs for one function
121 my($fh, $name, $docref) = @_;
122 my($flags, $docs, $ret, $file, @args) = @$docref;
123 $name =~ s/\s*$//;
124
125 $docs .= "NOTE: this function is experimental and may change or be
126removed without notice.\n\n" if $flags =~ /x/;
127 $docs .= "NOTE: the perl_ form of this function is deprecated.\n\n"
128 if $flags =~ /p/;
129
130 print $fh "=item $name\nX<$name>\n$docs";
131
132 if ($flags =~ /U/) { # no usage
133 # nothing
134 } elsif ($flags =~ /s/) { # semicolon ("dTHR;")
135 print $fh "\t\t$name;\n\n";
136 } elsif ($flags =~ /n/) { # no args
137 print $fh "\t$ret\t$name\n\n";
138 } else { # full usage
139 print $fh "\t$ret\t$name";
140 print $fh "(" . join(", ", @args) . ")";
141 print $fh "\n\n";
142 }
143 print $fh "=for hackers\nFound in file $file\n\n";
144}
145
146my $file;
147# glob() picks up docs from extra .c or .h files that may be in unclean
148# development trees.
149my $MANIFEST = do {
150 local ($/, *FH);
151 open FH, "MANIFEST" or die "Can't open MANIFEST: $!";
152 <FH>;
153};
154