x
[heimdal.git] / cf / make-proto.pl
blobb89ef790670b4b7fce0e306bc689e1359b4fd748
1 # Make prototypes from .c files
2 # $Id$
4 ##use Getopt::Std;
5 require 'getopts.pl';
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 = "^_";
15 do Getopts('x:m:o:p:dqE:R:P:') || die "foo";
17 if($opt_d) {
18 $debug = 1;
21 if($opt_q) {
22 $oproto = 0;
25 if($opt_R) {
26 $private_func_re = $opt_R;
28 %flags = (
29 'multiline-proto' => 1,
30 'header' => 1,
31 'function-blocking' => 0,
32 'gnuc-attribute' => 1,
33 'cxx' => 1
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;
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";
65 close EXP;
68 while(<>) {
69 print $brace, " ", $_ if($debug);
71 # Handle C comments
72 s@/\*.*\*/@@;
73 s@//.*/@@;
74 if ( s@/\*.*@@) { $comment = 1;
75 } elsif ($comment && s@.*\*/@@) { $comment = 0;
76 } elsif ($comment) { next; }
78 if(/^\#if 0/) {
79 $if_0 = 1;
81 if($if_0 && /^\#endif/) {
82 $if_0 = 0;
84 if($if_0) { next }
85 if(/^\s*\#/) {
86 next;
88 if(/^\s*$/) {
89 $line = "";
90 next;
92 if(/\{/){
93 if (!/\}/) {
94 $brace++;
96 $_ = $line;
97 while(s/\*\//\ca/){
98 s/\/\*(.|\n)*\ca//;
100 s/^\s*//;
101 s/\s*$//;
102 s/\s+/ /g;
103 if($_ =~ /\)$/){
104 if(!/^static/ && !/^PRIVATE/){
105 if(/(.*)(__attribute__\s?\(.*\))/) {
106 $attr = $2;
107 $_ = $1;
108 } else {
109 $attr = "";
111 # remove outer ()
112 s/\s*\(/</;
113 s/\)\s?$/>/;
114 # remove , within ()
115 while(s/\(([^()]*),(.*)\)/($1\$$2)/g){}
116 s/\<\s*void\s*\>/<>/;
117 # remove parameter names
118 if($opt_P eq "remove") {
119 s/(\s*)([a-zA-Z0-9_]+)([,>])/$3/g;
120 s/\s+\*/*/g;
121 s/\(\*(\s*)([a-zA-Z0-9_]+)\)/(*)/g;
122 } elsif($opt_P eq "comment") {
123 s/([a-zA-Z0-9_]+)([,>])/\/\*$1\*\/$2/g;
124 s/\(\*([a-zA-Z0-9_]+)\)/(*\/\*$1\*\/)/g;
126 s/\<\>/<void>/;
127 # add newlines before parameters
128 if($flags{"multiline-proto"}) {
129 s/,\s*/,\n\t/g;
130 } else {
131 s/,\s*/, /g;
133 # fix removed ,
134 s/\$/,/g;
135 # match function name
136 /([a-zA-Z0-9_]+)\s*\</;
137 $f = $1;
138 if($oproto) {
139 $LP = "__P((";
140 $RP = "))";
141 } else {
142 $LP = "(";
143 $RP = ")";
145 # only add newline if more than one parameter
146 if($flags{"multiline-proto"} && /,/){
147 s/\</ $LP\n\t/;
148 }else{
149 s/\</ $LP/;
151 s/\>/$RP/;
152 # insert newline before function name
153 if($flags{"multiline-proto"}) {
154 s/(.*)\s([a-zA-Z0-9_]+ \Q$LP\E)/$1\n$2/;
156 if($attr ne "") {
157 $_ .= "\n $attr";
159 $_ = $_ . ";";
160 $funcs{$f} = $_;
163 $line = "";
165 if(/\}/){
166 $brace--;
168 if(/^\}/){
169 $brace = 0;
171 if($brace == 0) {
172 $line = $line . " " . $_;
176 sub foo {
177 local ($arg) = @_;
178 $_ = $arg;
179 s/.*\/([^\/]*)/$1/;
180 s/[^a-zA-Z0-9]/_/g;
181 "__" . $_ . "__";
184 if($opt_o) {
185 open(OUT, ">$opt_o");
186 $block = &foo($opt_o);
187 } else {
188 $block = "__public_h__";
191 if($opt_p) {
192 open(PRIV, ">$opt_p");
193 $private = &foo($opt_p);
194 } else {
195 $private = "__private_h__";
198 $public_h = "";
199 $private_h = "";
201 $public_h_header .= "/* This is a generated file */
202 #ifndef $block
203 #define $block
206 if ($oproto) {
207 $public_h_header .= "#ifdef __STDC__
208 #include <stdarg.h>
209 #ifndef __P
210 #define __P(x) x
211 #endif
212 #else
213 #ifndef __P
214 #define __P(x) ()
215 #endif
216 #endif
219 } else {
220 $public_h_header .= "#include <stdarg.h>
224 $public_h_trailer = "";
226 $private_h_header = "/* This is a generated file */
227 #ifndef $private
228 #define $private
231 if($oproto) {
232 $private_h_header .= "#ifdef __STDC__
233 #include <stdarg.h>
234 #ifndef __P
235 #define __P(x) x
236 #endif
237 #else
238 #ifndef __P
239 #define __P(x) ()
240 #endif
241 #endif
244 } else {
245 $private_h_header .= "#include <stdarg.h>
249 $private_h_trailer = "";
251 foreach(sort keys %funcs){
252 if(/^(main)$/) { next }
253 if(!defined($exported{$_}) && /$private_func_re/) {
254 $private_h .= $funcs{$_} . "\n\n";
255 if($funcs{$_} =~ /__attribute__/) {
256 $private_attribute_seen = 1;
258 } else {
259 if($flags{"function-blocking"}) {
260 $fupper = uc $_;
261 if($exported{$_} =~ /proto/) {
262 $public_h .= "#if !defined(HAVE_$fupper) || defined(NEED_${fupper}_PROTO)\n";
263 } else {
264 $public_h .= "#ifndef HAVE_$fupper\n";
267 $public_h .= $funcs{$_} . "\n";
268 if($funcs{$_} =~ /__attribute__/) {
269 $public_attribute_seen = 1;
271 if($flags{"function-blocking"}) {
272 $public_h .= "#endif\n";
274 $public_h .= "\n";
278 if($flags{"gnuc-attribute"}) {
279 if ($public_attribute_seen) {
280 $public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
281 #define __attribute__(x)
282 #endif
287 if ($private_attribute_seen) {
288 $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
289 #define __attribute__(x)
290 #endif
295 if($flags{"cxx"}) {
296 $public_h_header .= "#ifdef __cplusplus
297 extern \"C\" {
298 #endif
301 $public_h_trailer .= "#ifdef __cplusplus
303 #endif
308 if ($opt_E) {
309 $public_h_header .= "#ifndef $opt_E
310 #if defined(_WIN32)
311 #define ${opt_E}_FUNCTION _stdcall __declspec(dllimport)
312 #define ${opt_E}_VARIABLE __declspec(dllimport)
313 #else
314 #define ${opt_E}_FUNCTION
315 #define ${opt_E}_VARIABLE
316 #endif
317 #endif
321 $private_h_header .= "#ifndef $opt_E
322 #if defined(_WIN32)
323 #define ${opt_E}_FUNCTION _stdcall __declspec(dllimport)
324 #define ${opt_E}_VARIABLE __declspec(dllimport)
325 #else
326 #define ${opt_E}_FUNCTION
327 #define ${opt_E}_VARIABLE
328 #endif
329 #endif
334 if ($public_h ne "" && $flags{"header"}) {
335 $public_h = $public_h_header . $public_h .
336 $public_h_trailer . "#endif /* $block */\n";
338 if ($private_h ne "" && $flags{"header"}) {
339 $private_h = $private_h_header . $private_h .
340 $private_h_trailer . "#endif /* $private */\n";
343 if($opt_o) {
344 print OUT $public_h;
346 if($opt_p) {
347 print PRIV $private_h;
350 close OUT;
351 close PRIV;