1 | # Make prototypes from .c files
|
---|
2 | # $Id$
|
---|
3 |
|
---|
4 | ##use Getopt::Std;
|
---|
5 | require 'getopts.pl';
|
---|
6 |
|
---|
7 | my $comment = 0;
|
---|
8 | my $if_0 = 0;
|
---|
9 | my $brace = 0;
|
---|
10 | my $line = "";
|
---|
11 | my $debug = 0;
|
---|
12 | my $oproto = 1;
|
---|
13 | my $private_func_re = "^_";
|
---|
14 |
|
---|
15 | Getopts('x:m:o:p:dqE:R:P:') || die "foo";
|
---|
16 |
|
---|
17 | if($opt_d) {
|
---|
18 | $debug = 1;
|
---|
19 | }
|
---|
20 |
|
---|
21 | if($opt_q) {
|
---|
22 | $oproto = 0;
|
---|
23 | }
|
---|
24 |
|
---|
25 | if($opt_R) {
|
---|
26 | $private_func_re = $opt_R;
|
---|
27 | }
|
---|
28 | %flags = (
|
---|
29 | 'multiline-proto' => 1,
|
---|
30 | 'header' => 1,
|
---|
31 | 'function-blocking' => 0,
|
---|
32 | 'gnuc-attribute' => 1,
|
---|
33 | 'cxx' => 1
|
---|
34 | );
|
---|
35 | if($opt_m) {
|
---|
36 | foreach $i (split(/,/, $opt_m)) {
|
---|
37 | if($i eq "roken") {
|
---|
38 | $flags{"multiline-proto"} = 0;
|
---|
39 | $flags{"header"} = 0;
|
---|
40 | $flags{"function-blocking"} = 0;
|
---|
41 | $flags{"gnuc-attribute"} = 0;
|
---|
42 | $flags{"cxx"} = 0;
|
---|
43 | } else {
|
---|
44 | if(substr($i, 0, 3) eq "no-") {
|
---|
45 | $flags{substr($i, 3)} = 0;
|
---|
46 | } else {
|
---|
47 | $flags{$i} = 1;
|
---|
48 | }
|
---|
49 | }
|
---|
50 | }
|
---|
51 | }
|
---|
52 |
|
---|
53 | if($opt_x) {
|
---|
54 | open(EXP, $opt_x);
|
---|
55 | while(<EXP>) {
|
---|
56 | chomp;
|
---|
57 | s/\#.*//g;
|
---|
58 | s/\s+/ /g;
|
---|
59 | if(/^([a-zA-Z0-9_]+)\s?(.*)$/) {
|
---|
60 | $exported{$1} = $2;
|
---|
61 | } else {
|
---|
62 | print $_, "\n";
|
---|
63 | }
|
---|
64 | }
|
---|
65 | close EXP;
|
---|
66 | }
|
---|
67 |
|
---|
68 | while(<>) {
|
---|
69 | print $brace, " ", $_ if($debug);
|
---|
70 |
|
---|
71 | # Handle C comments
|
---|
72 | s@/\*.*\*/@@;
|
---|
73 | s@//.*/@@;
|
---|
74 | if ( s@/\*.*@@) { $comment = 1;
|
---|
75 | } elsif ($comment && s@.*\*/@@) { $comment = 0;
|
---|
76 | } elsif ($comment) { next; }
|
---|
77 |
|
---|
78 | if(/^\#if 0/) {
|
---|
79 | $if_0 = 1;
|
---|
80 | }
|
---|
81 | if($if_0 && /^\#endif/) {
|
---|
82 | $if_0 = 0;
|
---|
83 | }
|
---|
84 | if($if_0) { next }
|
---|
85 | if(/^\s*\#/) {
|
---|
86 | next;
|
---|
87 | }
|
---|
88 | if(/^\s*$/) {
|
---|
89 | $line = "";
|
---|
90 | next;
|
---|
91 | }
|
---|
92 | if(/\{/){
|
---|
93 | if (!/\}/) {
|
---|
94 | $brace++;
|
---|
95 | }
|
---|
96 | $_ = $line;
|
---|
97 | while(s/\*\//\ca/){
|
---|
98 | s/\/\*(.|\n)*\ca//;
|
---|
99 | }
|
---|
100 | s/^\s*//;
|
---|
101 | s/\s*$//;
|
---|
102 | s/\s+/ /g;
|
---|
103 | if($_ =~ /\)$/ or $_ =~ /DEPRECATED$/){
|
---|
104 | if(!/^static/ && !/^PRIVATE/){
|
---|
105 | $attr = "";
|
---|
106 | if(m/(.*)(__attribute__\s?\(.*\))/) {
|
---|
107 | $attr .= " $2";
|
---|
108 | $_ = $1;
|
---|
109 | }
|
---|
110 | if(m/(.*)\s(\w+DEPRECATED)/) {
|
---|
111 | $attr .= " $2";
|
---|
112 | $_ = $1;
|
---|
113 | }
|
---|
114 | # remove outer ()
|
---|
115 | s/\s*\(/</;
|
---|
116 | s/\)\s?$/>/;
|
---|
117 | # remove , within ()
|
---|
118 | while(s/\(([^()]*),(.*)\)/($1\$$2)/g){}
|
---|
119 | s/\<\s*void\s*\>/<>/;
|
---|
120 | # remove parameter names
|
---|
121 | if($opt_P eq "remove") {
|
---|
122 | s/(\s*)([a-zA-Z0-9_]+)([,>])/$3/g;
|
---|
123 | s/\s+\*/*/g;
|
---|
124 | s/\(\*(\s*)([a-zA-Z0-9_]+)\)/(*)/g;
|
---|
125 | } elsif($opt_P eq "comment") {
|
---|
126 | s/([a-zA-Z0-9_]+)([,>])/\/\*$1\*\/$2/g;
|
---|
127 | s/\(\*([a-zA-Z0-9_]+)\)/(*\/\*$1\*\/)/g;
|
---|
128 | }
|
---|
129 | s/\<\>/<void>/;
|
---|
130 | # add newlines before parameters
|
---|
131 | if($flags{"multiline-proto"}) {
|
---|
132 | s/,\s*/,\n\t/g;
|
---|
133 | } else {
|
---|
134 | s/,\s*/, /g;
|
---|
135 | }
|
---|
136 | # fix removed ,
|
---|
137 | s/\$/,/g;
|
---|
138 | # match function name
|
---|
139 | /([a-zA-Z0-9_]+)\s*\</;
|
---|
140 | $f = $1;
|
---|
141 | if($oproto) {
|
---|
142 | $LP = "__P((";
|
---|
143 | $RP = "))";
|
---|
144 | } else {
|
---|
145 | $LP = "(";
|
---|
146 | $RP = ")";
|
---|
147 | }
|
---|
148 | # only add newline if more than one parameter
|
---|
149 | if($flags{"multiline-proto"} && /,/){
|
---|
150 | s/\</ $LP\n\t/;
|
---|
151 | }else{
|
---|
152 | s/\</ $LP/;
|
---|
153 | }
|
---|
154 | s/\>/$RP/;
|
---|
155 | # insert newline before function name
|
---|
156 | if($flags{"multiline-proto"}) {
|
---|
157 | s/(.*)\s([a-zA-Z0-9_]+ \Q$LP\E)/$1\n$2/;
|
---|
158 | }
|
---|
159 | if($attr ne "") {
|
---|
160 | $_ .= "\n $attr";
|
---|
161 | }
|
---|
162 | $_ = $_ . ";";
|
---|
163 | $funcs{$f} = $_;
|
---|
164 | }
|
---|
165 | }
|
---|
166 | $line = "";
|
---|
167 | }
|
---|
168 | if(/\}/){
|
---|
169 | $brace--;
|
---|
170 | }
|
---|
171 | if(/^\}/){
|
---|
172 | $brace = 0;
|
---|
173 | }
|
---|
174 | if($brace == 0) {
|
---|
175 | $line = $line . " " . $_;
|
---|
176 | }
|
---|
177 | }
|
---|
178 |
|
---|
179 | sub foo {
|
---|
180 | local ($arg) = @_;
|
---|
181 | $_ = $arg;
|
---|
182 | s/.*\/([^\/]*)/$1/;
|
---|
183 | s/.*\\([^\\]*)/$1/;
|
---|
184 | s/[^a-zA-Z0-9]/_/g;
|
---|
185 | "__" . $_ . "__";
|
---|
186 | }
|
---|
187 |
|
---|
188 | if($opt_o) {
|
---|
189 | open(OUT, ">$opt_o");
|
---|
190 | $block = &foo($opt_o);
|
---|
191 | } else {
|
---|
192 | $block = "__public_h__";
|
---|
193 | }
|
---|
194 |
|
---|
195 | if($opt_p) {
|
---|
196 | open(PRIV, ">$opt_p");
|
---|
197 | $private = &foo($opt_p);
|
---|
198 | } else {
|
---|
199 | $private = "__private_h__";
|
---|
200 | }
|
---|
201 |
|
---|
202 | $public_h = "";
|
---|
203 | $private_h = "";
|
---|
204 |
|
---|
205 | $public_h_header .= "/* This is a generated file */
|
---|
206 | #ifndef $block
|
---|
207 | #define $block
|
---|
208 |
|
---|
209 | ";
|
---|
210 | if ($oproto) {
|
---|
211 | $public_h_header .= "#ifdef __STDC__
|
---|
212 | #include <stdarg.h>
|
---|
213 | #ifndef __P
|
---|
214 | #define __P(x) x
|
---|
215 | #endif
|
---|
216 | #else
|
---|
217 | #ifndef __P
|
---|
218 | #define __P(x) ()
|
---|
219 | #endif
|
---|
220 | #endif
|
---|
221 |
|
---|
222 | ";
|
---|
223 | } else {
|
---|
224 | $public_h_header .= "#include <stdarg.h>
|
---|
225 |
|
---|
226 | ";
|
---|
227 | }
|
---|
228 | $public_h_trailer = "";
|
---|
229 |
|
---|
230 | $private_h_header = "/* This is a generated file */
|
---|
231 | #ifndef $private
|
---|
232 | #define $private
|
---|
233 |
|
---|
234 | ";
|
---|
235 | if($oproto) {
|
---|
236 | $private_h_header .= "#ifdef __STDC__
|
---|
237 | #include <stdarg.h>
|
---|
238 | #ifndef __P
|
---|
239 | #define __P(x) x
|
---|
240 | #endif
|
---|
241 | #else
|
---|
242 | #ifndef __P
|
---|
243 | #define __P(x) ()
|
---|
244 | #endif
|
---|
245 | #endif
|
---|
246 |
|
---|
247 | ";
|
---|
248 | } else {
|
---|
249 | $private_h_header .= "#include <stdarg.h>
|
---|
250 |
|
---|
251 | ";
|
---|
252 | }
|
---|
253 | $private_h_trailer = "";
|
---|
254 |
|
---|
255 | foreach(sort keys %funcs){
|
---|
256 | if(/^(main)$/) { next }
|
---|
257 | if ($funcs{$_} =~ /\^/) {
|
---|
258 | $beginblock = "#ifdef __BLOCKS__\n";
|
---|
259 | $endblock = "#endif /* __BLOCKS__ */\n";
|
---|
260 | } else {
|
---|
261 | $beginblock = $endblock = "";
|
---|
262 | }
|
---|
263 | if(!defined($exported{$_}) && /$private_func_re/) {
|
---|
264 | $private_h .= $beginblock . $funcs{$_} . "\n" . $endblock . "\n";
|
---|
265 | if($funcs{$_} =~ /__attribute__/) {
|
---|
266 | $private_attribute_seen = 1;
|
---|
267 | }
|
---|
268 | } else {
|
---|
269 | if($flags{"function-blocking"}) {
|
---|
270 | $fupper = uc $_;
|
---|
271 | if($exported{$_} =~ /proto/) {
|
---|
272 | $public_h .= "#if !defined(HAVE_$fupper) || defined(NEED_${fupper}_PROTO)\n";
|
---|
273 | } else {
|
---|
274 | $public_h .= "#ifndef HAVE_$fupper\n";
|
---|
275 | }
|
---|
276 | }
|
---|
277 | $public_h .= $beginblock . $funcs{$_} . "\n" . $endblock;
|
---|
278 | if($funcs{$_} =~ /__attribute__/) {
|
---|
279 | $public_attribute_seen = 1;
|
---|
280 | }
|
---|
281 | if($flags{"function-blocking"}) {
|
---|
282 | $public_h .= "#endif\n";
|
---|
283 | }
|
---|
284 | $public_h .= "\n";
|
---|
285 | }
|
---|
286 | }
|
---|
287 |
|
---|
288 | if($flags{"gnuc-attribute"}) {
|
---|
289 | if ($public_attribute_seen) {
|
---|
290 | $public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
|
---|
291 | #define __attribute__(x)
|
---|
292 | #endif
|
---|
293 |
|
---|
294 | ";
|
---|
295 | }
|
---|
296 |
|
---|
297 | if ($private_attribute_seen) {
|
---|
298 | $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
|
---|
299 | #define __attribute__(x)
|
---|
300 | #endif
|
---|
301 |
|
---|
302 | ";
|
---|
303 | }
|
---|
304 | }
|
---|
305 | if($flags{"cxx"}) {
|
---|
306 | $public_h_header .= "#ifdef __cplusplus
|
---|
307 | extern \"C\" {
|
---|
308 | #endif
|
---|
309 |
|
---|
310 | ";
|
---|
311 | $public_h_trailer .= "#ifdef __cplusplus
|
---|
312 | }
|
---|
313 | #endif
|
---|
314 |
|
---|
315 | ";
|
---|
316 |
|
---|
317 | }
|
---|
318 | if ($opt_E) {
|
---|
319 | $public_h_header .= "#ifndef $opt_E
|
---|
320 | #ifndef ${opt_E}_FUNCTION
|
---|
321 | #if defined(_WIN32)
|
---|
322 | #define ${opt_E}_FUNCTION __declspec(dllimport)
|
---|
323 | #define ${opt_E}_CALL __stdcall
|
---|
324 | #define ${opt_E}_VARIABLE __declspec(dllimport)
|
---|
325 | #else
|
---|
326 | #define ${opt_E}_FUNCTION
|
---|
327 | #define ${opt_E}_CALL
|
---|
328 | #define ${opt_E}_VARIABLE
|
---|
329 | #endif
|
---|
330 | #endif
|
---|
331 | #endif
|
---|
332 | ";
|
---|
333 |
|
---|
334 | $private_h_header .= "#ifndef $opt_E
|
---|
335 | #ifndef ${opt_E}_FUNCTION
|
---|
336 | #if defined(_WIN32)
|
---|
337 | #define ${opt_E}_FUNCTION __declspec(dllimport)
|
---|
338 | #define ${opt_E}_CALL __stdcall
|
---|
339 | #define ${opt_E}_VARIABLE __declspec(dllimport)
|
---|
340 | #else
|
---|
341 | #define ${opt_E}_FUNCTION
|
---|
342 | #define ${opt_E}_CALL
|
---|
343 | #define ${opt_E}_VARIABLE
|
---|
344 | #endif
|
---|
345 | #endif
|
---|
346 | #endif
|
---|
347 |
|
---|
348 | ";
|
---|
349 | }
|
---|
350 |
|
---|
351 | if ($public_h ne "" && $flags{"header"}) {
|
---|
352 | $public_h = $public_h_header . $public_h .
|
---|
353 | $public_h_trailer . "#endif /* $block */\n";
|
---|
354 | }
|
---|
355 | if ($private_h ne "" && $flags{"header"}) {
|
---|
356 | $private_h = $private_h_header . $private_h .
|
---|
357 | $private_h_trailer . "#endif /* $private */\n";
|
---|
358 | }
|
---|
359 |
|
---|
360 | if($opt_o) {
|
---|
361 | print OUT $public_h;
|
---|
362 | }
|
---|
363 | if($opt_p) {
|
---|
364 | print PRIV $private_h;
|
---|
365 | }
|
---|
366 |
|
---|
367 | close OUT;
|
---|
368 | close PRIV;
|
---|