restore ABI level 5 compatibility
[imager.git] / apidocs.perl
CommitLineData
92bda632
TC
1#!perl -w
2use strict;
fe415ad2 3use ExtUtils::Manifest 'maniread';
92bda632
TC
4
5my $outname = shift || '-';
6
92bda632
TC
7my @funcs = make_func_list();
8my %funcs = map { $_ => 1 } @funcs;
9
10# look for files to parse
11
fe415ad2 12my $mani = maniread;
81409c5e 13my @files = sort grep /\.(c|im|h)$/, keys %$mani;
92bda632
TC
14
15# scan each file for =item <func>\b
16my $func;
17my $start;
18my %alldocs;
19my @funcdocs;
20my %from;
21my $category;
22my %funccats;
23my %cats;
24my $synopsis = '';
25my %funcsyns;
6cfee9d1
TC
26my $order;
27my %order;
92bda632
TC
28for my $file (@files) {
29 open SRC, "< $file"
30 or die "Cannot open $file for documentation: $!\n";
31 while (<SRC>) {
32 if (/^=item (\w+)\b/ && $funcs{$1}) {
33 $func = $1;
34 $start = $.;
35 @funcdocs = $_;
36 }
37 elsif ($func && /^=(cut|head)/) {
38 if ($funcs{$func}) { # only save the API functions
39 $alldocs{$func} = [ @funcdocs ];
5ca7e2ab 40 $from{$func} = "File $file";
92bda632
TC
41 if ($category) {
42 $funccats{$func} = $category;
43 push @{$cats{$category}}, $func;
44 }
45 if ($synopsis) {
46 $funcsyns{$func} = $synopsis;
47 }
6cfee9d1
TC
48 defined $order or $order = 50;
49 $order{$func} = $order;
92bda632
TC
50 }
51 undef $func;
52 undef $category;
6cfee9d1 53 undef $order;
92bda632
TC
54 $synopsis = '';
55 }
56 elsif ($func) {
57 if (/^=category (.*)/) {
58 $category = $1;
59 }
60 elsif (/^=synopsis (.*)/) {
8d14daab
TC
61 unless (length $synopsis) {
62 push @funcdocs, "\n";
63 }
92bda632 64 $synopsis .= "$1\n";
8d14daab 65 push @funcdocs, " $1\n";
92bda632 66 }
6cfee9d1
TC
67 elsif (/^=order (.*)$/) {
68 $order = $1;
69 $order =~ /^\d+$/
70 or die "=order must specify a number for $func in $file\n";
71 }
92bda632
TC
72 else {
73 push @funcdocs, $_;
74 }
75 }
76 }
77 $func and
78 die "Documentation for $func not followed by =cut or =head in $file\n";
79
80 close SRC;
81}
82
83open OUT, "> $outname"
84 or die "Cannot open $outname: $!";
85
091760c5
TC
86# I keep this file in git and as part of the dist, make sure newlines
87# don't mess me up
88binmode OUT;
89
92bda632
TC
90print OUT <<'EOS';
91Do not edit this file, it is generated automatically by apidocs.perl
92from Imager's source files.
93
5ca7e2ab
TC
94Each function description has a comment listing the source file where
95you can find the documentation.
92bda632
TC
96
97=head1 NAME
98
6cfee9d1 99Imager::APIRef - Imager's C API - reference.
92bda632
TC
100
101=head1 SYNOPSIS
102
103 i_color color;
6cfee9d1 104 color.rgba.r = 255; color.rgba.g = 0; color.rgba.b = 255;
92bda632
TC
105
106EOS
107
108for my $cat (sort { lc $a cmp lc $b } keys %cats) {
109 print OUT "\n # $cat\n";
81409c5e
TC
110 my @funcs = @{$cats{$cat}};
111 my %orig;
112 @orig{@funcs} = 0 .. $#funcs;
113 @funcs = sort { $order{$a} <=> $order{$b} || $orig{$a} <=> $orig{$b} } @funcs;
114 for my $func (grep $funcsyns{$_}, @funcs) {
92bda632
TC
115 my $syn = $funcsyns{$func};
116 $syn =~ s/^/ /gm;
117 print OUT $syn;
118 }
119}
120
121print OUT <<'EOS';
122
92bda632
TC
123=head1 DESCRIPTION
124
125EOS
126
127my %undoc = %funcs;
128
129for my $cat (sort { lc $a cmp lc $b } keys %cats) {
130 print OUT "=head2 $cat\n\n=over\n\n";
6cfee9d1
TC
131 my @ordered_funcs = sort {
132 $order{$a} <=> $order{$b}
133 || lc $a cmp lc $b
134 } @{$cats{$cat}};
135 for my $func (@ordered_funcs) {
92bda632
TC
136 print OUT @{$alldocs{$func}}, "\n";
137 print OUT "=for comment\nFrom: $from{$func}\n\n";
138 delete $undoc{$func};
139 }
140 print OUT "\n=back\n\n";
141}
142
50c75381 143# see if we have an uncategorised section
92bda632
TC
144if (grep $alldocs{$_}, keys %undoc) {
145 print OUT "=head2 Uncategorized functions\n\n=over\n\n";
6cfee9d1
TC
146 #print join(",", grep !exists $order{$_}, @funcs), "\n";
147 for my $func (sort { $order{$a} <=> $order{$b} || $a cmp $b }
148 grep $undoc{$_} && $alldocs{$_}, @funcs) {
149 print OUT @{$alldocs{$func}}, "\n";
150 print OUT "=for comment\nFrom: $from{$func}\n\n";
151 delete $undoc{$func};
92bda632
TC
152 }
153 print OUT "\n\n=back\n\n";
154}
155
156if (keys %undoc) {
157 print OUT <<'EOS';
158
159=head1 UNDOCUMENTED
160
161The following API functions are undocumented so far, hopefully this
162will change:
163
164=over
165
166EOS
167
168 print OUT "=item *\n\nB<$_>\n\n" for sort keys %undoc;
169
170 print OUT "\n\n=back\n\n";
171}
172
173print OUT <<'EOS';
174
175=head1 AUTHOR
176
5b480b14 177Tony Cook <tonyc@cpan.org>
92bda632
TC
178
179=head1 SEE ALSO
180
b96f5e9e 181Imager, Imager::API, Imager::ExtUtils, Imager::Inline
92bda632
TC
182
183=cut
184EOS
185
186close OUT;
187
188
189sub make_func_list {
abffffed 190 my @funcs = qw(i_img i_color i_fcolor i_fill_t mm_log mm_log i_img_color_channels i_img_has_alpha i_img_dim i_DF i_DFc i_DFp i_DFcp i_psamp_bits i_gsamp_bits i_psamp i_psampf);
92bda632
TC
191 open FUNCS, "< imexttypes.h"
192 or die "Cannot open imexttypes.h: $!\n";
193 my $in_struct;
194 while (<FUNCS>) {
195 /^typedef struct/ && ++$in_struct;
eac41a26 196 if ($in_struct && !/SKIP/ && /\(\*f_(i[om]?_\w+)/) {
6d5c85a2
TC
197 my $name = $1;
198 $name =~ s/_imp$//;
199 push @funcs, $name;
92bda632
TC
200 }
201 if (/^\} im_ext_funcs;$/) {
202 $in_struct
203 or die "Found end of functions structure but not the start";
204
205 close FUNCS;
206 return @funcs;
207 }
208 }
209 if ($in_struct) {
210 die "Found start of the functions structure but not the end\n";
211 }
212 else {
213 die "Found neither the start nor end of the functions structure\n";
214 }
215}
6cfee9d1
TC
216
217=head1 NAME
218
219apidocs.perl - parse Imager's source for POD documenting the C API
220
221=head1 SYNOPSIS
222
223 perl apidocs.perl lib/Imager/APIRef.pod
224
225=head1 DESCRIPTION
226
227Parses Imager's C sources, including .c, .h and .im files searching
228for function documentation.
229
230Besides the normal POD markup, the following can be included:
231
232=over
233
234=item =category I<category-name>
235
236The category the function should be in.
237
238=item =synopsis I<sample-code>
239
240Sample code using the function to include in the Imager::APIRef SYNOPSIS
241
242=item =order I<integer>
243
244Allows a function to be listed out of order. If this isn't specified
245it defaults to 50, so a value of 10 will cause the function to be
246listed at the beginning of its category, or 90 to list at the end.
247
248Functions with equal order are otherwise ordered by name.
249
250=back
251
252=head1 AUTHOR
253
254Tony Cook <tonyc@cpan.org>
255
256=cut
257