make-proto.pl revision 225736
1189251Ssam# Make prototypes from .c files
2189251Ssam# $Id: make-proto.pl 14183 2004-09-03 08:50:57Z lha $
3252726Srpaulo
4189251Ssam##use Getopt::Std;
5252726Srpaulorequire 'getopts.pl';
6252726Srpaulo
7189251Ssam$brace = 0;
8189251Ssam$line = "";
9189251Ssam$debug = 0;
10189251Ssam$oproto = 1;
11189251Ssam$private_func_re = "^_";
12189251Ssam
13189251Ssamdo Getopts('x:m:o:p:dqE:R:P:') || die "foo";
14189251Ssam
15189251Ssamif($opt_d) {
16189251Ssam    $debug = 1;
17189251Ssam}
18189251Ssam
19189251Ssamif($opt_q) {
20189251Ssam    $oproto = 0;
21189251Ssam}
22189251Ssam
23189251Ssamif($opt_R) {
24189251Ssam    $private_func_re = $opt_R;
25189251Ssam}
26189251Ssam%flags = (
27189251Ssam	  'multiline-proto' => 1,
28189251Ssam	  'header' => 1,
29214734Srpaulo	  'function-blocking' => 0,
30252726Srpaulo	  'gnuc-attribute' => 1,
31189251Ssam	  'cxx' => 1
32189251Ssam	  );
33189251Ssamif($opt_m) {
34189251Ssam    foreach $i (split(/,/, $opt_m)) {
35189251Ssam	if($i eq "roken") {
36189251Ssam	    $flags{"multiline-proto"} = 0;
37189251Ssam	    $flags{"header"} = 0;
38189251Ssam	    $flags{"function-blocking"} = 0;
39189251Ssam	    $flags{"gnuc-attribute"} = 0;
40189251Ssam	    $flags{"cxx"} = 0;
41209158Srpaulo	} else {
42189251Ssam	    if(substr($i, 0, 3) eq "no-") {
43189251Ssam		$flags{substr($i, 3)} = 0;
44189251Ssam	    } else {
45252726Srpaulo		$flags{$i} = 1;
46189251Ssam	    }
47189251Ssam	}
48189251Ssam    }
49189251Ssam}
50189251Ssam
51189251Ssamif($opt_x) {
52189251Ssam    open(EXP, $opt_x);
53189251Ssam    while(<EXP>) {
54189251Ssam	chomp;
55189251Ssam	s/\#.*//g;
56189251Ssam	s/\s+/ /g;
57189251Ssam	if(/^([a-zA-Z0-9_]+)\s?(.*)$/) {
58252726Srpaulo	    $exported{$1} = $2;
59189251Ssam	} else {
60189251Ssam	    print $_, "\n";
61214734Srpaulo	}
62214734Srpaulo    }
63252726Srpaulo    close EXP;
64252726Srpaulo}
65252726Srpaulo
66252726Srpaulowhile(<>) {
67252726Srpaulo    print $brace, " ", $_ if($debug);
68252726Srpaulo    if(/^\#if 0/) {
69252726Srpaulo	$if_0 = 1;
70214734Srpaulo    }
71189251Ssam    if($if_0 && /^\#endif/) {
72189251Ssam	$if_0 = 0;
73189251Ssam    }
74189251Ssam    if($if_0) { next }
75189251Ssam    if(/^\s*\#/) {
76189251Ssam	next;
77189251Ssam    }
78189251Ssam    if(/^\s*$/) {
79214734Srpaulo	$line = "";
80252726Srpaulo	next;
81252726Srpaulo    }
82189251Ssam    if(/\{/){
83189251Ssam	if (!/\}/) {
84252726Srpaulo	    $brace++;
85189251Ssam	}
86189251Ssam	$_ = $line;
87189251Ssam	while(s/\*\//\ca/){
88189251Ssam	    s/\/\*(.|\n)*\ca//;
89189251Ssam	}
90189251Ssam	s/^\s*//;
91189251Ssam	s/\s*$//;
92189251Ssam	s/\s+/ /g;
93214734Srpaulo	if($_ =~ /\)$/){
94252726Srpaulo	    if(!/^static/ && !/^PRIVATE/){
95252726Srpaulo		if(/(.*)(__attribute__\s?\(.*\))/) {
96252726Srpaulo		    $attr = $2;
97189251Ssam		    $_ = $1;
98189251Ssam		} else {
99252726Srpaulo		    $attr = "";
100252726Srpaulo		}
101252726Srpaulo		# remove outer ()
102189251Ssam		s/\s*\(/</;
103252726Srpaulo		s/\)\s?$/>/;
104214734Srpaulo		# remove , within ()
105214734Srpaulo		while(s/\(([^()]*),(.*)\)/($1\$$2)/g){}
106189251Ssam		s/\<\s*void\s*\>/<>/;
107189251Ssam		# remove parameter names
108189251Ssam		if($opt_P eq "remove") {
109189251Ssam		    s/(\s*)([a-zA-Z0-9_]+)([,>])/$3/g;
110189251Ssam		    s/\s+\*/*/g;
111189251Ssam		    s/\(\*(\s*)([a-zA-Z0-9_]+)\)/(*)/g;
112189251Ssam		} elsif($opt_P eq "comment") {
113189251Ssam		    s/([a-zA-Z0-9_]+)([,>])/\/\*$1\*\/$2/g;
114189251Ssam		    s/\(\*([a-zA-Z0-9_]+)\)/(*\/\*$1\*\/)/g;
115189251Ssam		}
116189251Ssam		s/\<\>/<void>/;
117189251Ssam		# add newlines before parameters
118189251Ssam		if($flags{"multiline-proto"}) {
119189251Ssam		    s/,\s*/,\n\t/g;
120189251Ssam		} else {
121189251Ssam		    s/,\s*/, /g;
122189251Ssam		}
123189251Ssam		# fix removed ,
124189251Ssam		s/\$/,/g;
125189251Ssam		# match function name
126189251Ssam		/([a-zA-Z0-9_]+)\s*\</;
127189251Ssam		$f = $1;
128189251Ssam		if($oproto) {
129189251Ssam		    $LP = "__P((";
130189251Ssam		    $RP = "))";
131189251Ssam		} else {
132189251Ssam		    $LP = "(";
133189251Ssam		    $RP = ")";
134189251Ssam		}
135189251Ssam		# only add newline if more than one parameter
136189251Ssam                if($flags{"multiline-proto"} && /,/){
137189251Ssam		    s/\</ $LP\n\t/;
138189251Ssam		}else{
139214734Srpaulo		    s/\</ $LP/;
140214734Srpaulo		}
141214734Srpaulo		s/\>/$RP/;
142214734Srpaulo		# insert newline before function name
143214734Srpaulo		if($flags{"multiline-proto"}) {
144214734Srpaulo		    s/(.*)\s([a-zA-Z0-9_]+ \Q$LP\E)/$1\n$2/;
145214734Srpaulo		}
146214734Srpaulo		if($attr ne "") {
147214734Srpaulo		    $_ .= "\n    $attr";
148214734Srpaulo		}
149214734Srpaulo		$_ = $_ . ";";
150214734Srpaulo		$funcs{$f} = $_;
151214734Srpaulo	    }
152214734Srpaulo	}
153214734Srpaulo	$line = "";
154214734Srpaulo    }
155214734Srpaulo    if(/\}/){
156214734Srpaulo	$brace--;
157214734Srpaulo    }
158214734Srpaulo    if(/^\}/){
159214734Srpaulo	$brace = 0;
160214734Srpaulo    }
161214734Srpaulo    if($brace == 0) {
162214734Srpaulo	$line = $line . " " . $_;
163252726Srpaulo    }
164252726Srpaulo}
165252726Srpaulo
166252726Srpaulosub foo {
167252726Srpaulo    local ($arg) = @_;
168252726Srpaulo    $_ = $arg;
169252726Srpaulo    s/.*\/([^\/]*)/$1/;
170252726Srpaulo    s/[^a-zA-Z0-9]/_/g;
171252726Srpaulo    "__" . $_ . "__";
172252726Srpaulo}
173252726Srpaulo
174252726Srpauloif($opt_o) {
175252726Srpaulo    open(OUT, ">$opt_o");
176252726Srpaulo    $block = &foo($opt_o);
177252726Srpaulo} else {
178252726Srpaulo    $block = "__public_h__";
179252726Srpaulo}
180252726Srpaulo
181252726Srpauloif($opt_p) {
182252726Srpaulo    open(PRIV, ">$opt_p");
183252726Srpaulo    $private = &foo($opt_p);
184252726Srpaulo} else {
185252726Srpaulo    $private = "__private_h__";
186189251Ssam}
187189251Ssam
188189251Ssam$public_h = "";
189189251Ssam$private_h = "";
190189251Ssam
191189251Ssam$public_h_header .= "/* This is a generated file */
192189251Ssam#ifndef $block
193189251Ssam#define $block
194189251Ssam
195189251Ssam";
196189251Ssamif ($oproto) {
197189251Ssam    $public_h_header .= "#ifdef __STDC__
198189251Ssam#include <stdarg.h>
199189251Ssam#ifndef __P
200189251Ssam#define __P(x) x
201189251Ssam#endif
202189251Ssam#else
203189251Ssam#ifndef __P
204189251Ssam#define __P(x) ()
205189251Ssam#endif
206189251Ssam#endif
207189251Ssam
208189251Ssam";
209189251Ssam} else {
210189251Ssam    $public_h_header .= "#include <stdarg.h>
211189251Ssam
212189251Ssam";
213189251Ssam}
214189251Ssam$public_h_trailer = "";
215189251Ssam
216189251Ssam$private_h_header = "/* This is a generated file */
217189251Ssam#ifndef $private
218189251Ssam#define $private
219189251Ssam
220189251Ssam";
221189251Ssamif($oproto) {
222189251Ssam    $private_h_header .= "#ifdef __STDC__
223189251Ssam#include <stdarg.h>
224189251Ssam#ifndef __P
225252726Srpaulo#define __P(x) x
226252726Srpaulo#endif
227252726Srpaulo#else
228252726Srpaulo#ifndef __P
229189251Ssam#define __P(x) ()
230252726Srpaulo#endif
231189251Ssam#endif
232189251Ssam
233214734Srpaulo";
234252726Srpaulo} else {
235189251Ssam    $private_h_header .= "#include <stdarg.h>
236252726Srpaulo
237252726Srpaulo";
238252726Srpaulo}
239189251Ssam$private_h_trailer = "";
240189251Ssam
241189251Ssamforeach(sort keys %funcs){
242189251Ssam    if(/^(main)$/) { next }
243189251Ssam    if(!defined($exported{$_}) && /$private_func_re/) {
244189251Ssam	$private_h .= $funcs{$_} . "\n\n";
245189251Ssam	if($funcs{$_} =~ /__attribute__/) {
246189251Ssam	    $private_attribute_seen = 1;
247189251Ssam	}
248189251Ssam    } else {
249189251Ssam	if($flags{"function-blocking"}) {
250189251Ssam	    $fupper = uc $_;
251189251Ssam	    if($exported{$_} =~ /proto/) {
252189251Ssam		$public_h .= "#if !defined(HAVE_$fupper) || defined(NEED_${fupper}_PROTO)\n";
253189251Ssam	    } else {
254189251Ssam		$public_h .= "#ifndef HAVE_$fupper\n";
255189251Ssam	    }
256189251Ssam	}
257189251Ssam	$public_h .= $funcs{$_} . "\n";
258189251Ssam	if($funcs{$_} =~ /__attribute__/) {
259189251Ssam	    $public_attribute_seen = 1;
260189251Ssam	}
261189251Ssam	if($flags{"function-blocking"}) {
262189251Ssam	    $public_h .= "#endif\n";
263189251Ssam	}
264189251Ssam	$public_h .= "\n";
265189251Ssam    }
266214734Srpaulo}
267214734Srpaulo
268189251Ssamif($flags{"gnuc-attribute"}) {
269214734Srpaulo    if ($public_attribute_seen) {
270214734Srpaulo	$public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
271189251Ssam#define __attribute__(x)
272189251Ssam#endif
273189251Ssam
274189251Ssam";
275189251Ssam    }
276189251Ssam
277189251Ssam    if ($private_attribute_seen) {
278189251Ssam	$private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
279189251Ssam#define __attribute__(x)
280189251Ssam#endif
281189251Ssam
282189251Ssam";
283189251Ssam    }
284189251Ssam}
285189251Ssamif($flags{"cxx"}) {
286189251Ssam    $public_h_header .= "#ifdef __cplusplus
287189251Ssamextern \"C\" {
288189251Ssam#endif
289189251Ssam
290252726Srpaulo";
291252726Srpaulo    $public_h_trailer .= "#ifdef __cplusplus
292189251Ssam}
293189251Ssam#endif
294189251Ssam
295189251Ssam";
296189251Ssam
297252726Srpaulo}
298252726Srpauloif ($opt_E) {
299189251Ssam    $public_h_header .= "#ifndef $opt_E
300189251Ssam#if defined(_WIN32)
301214734Srpaulo#define $opt_E _stdcall
302214734Srpaulo#else
303214734Srpaulo#define $opt_E
304214734Srpaulo#endif
305214734Srpaulo#endif
306214734Srpaulo
307214734Srpaulo";
308214734Srpaulo
309214734Srpaulo    $private_h_header .= "#ifndef $opt_E
310214734Srpaulo#if defined(_WIN32)
311214734Srpaulo#define $opt_E _stdcall
312214734Srpaulo#else
313214734Srpaulo#define $opt_E
314214734Srpaulo#endif
315214734Srpaulo#endif
316214734Srpaulo
317214734Srpaulo";
318214734Srpaulo}
319214734Srpaulo
320214734Srpauloif ($public_h ne "" && $flags{"header"}) {
321214734Srpaulo    $public_h = $public_h_header . $public_h .
322214734Srpaulo	$public_h_trailer . "#endif /* $block */\n";
323214734Srpaulo}
324214734Srpauloif ($private_h ne "" && $flags{"header"}) {
325214734Srpaulo    $private_h = $private_h_header . $private_h .
326214734Srpaulo	$private_h_trailer . "#endif /* $private */\n";
327214734Srpaulo}
328214734Srpaulo
329214734Srpauloif($opt_o) {
330214734Srpaulo    print OUT $public_h;
331214734Srpaulo}
332214734Srpauloif($opt_p) {
333214734Srpaulo    print PRIV $private_h;
334214734Srpaulo}
335189251Ssam
336189251Ssamclose OUT;
337189251Ssamclose PRIV;
338189251Ssam