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