Merge Samba3 and Samba4 together
[sfrench/samba-autobuild/.git] / source4 / heimdal / cf / make-proto.pl
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 do 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($_ =~ /\)$/){
104             if(!/^static/ && !/^PRIVATE/){
105                 if(/(.*)(__attribute__\s?\(.*\))/) {
106                     $attr = $2;
107                     $_ = $1;
108                 } else {
109                     $attr = "";
110                 }
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;
125                 }
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;
132                 }
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 = ")";
144                 }
145                 # only add newline if more than one parameter
146                 if($flags{"multiline-proto"} && /,/){ 
147                     s/\</ $LP\n\t/;
148                 }else{
149                     s/\</ $LP/;
150                 }
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/;
155                 }
156                 if($attr ne "") {
157                     $_ .= "\n    $attr";
158                 }
159                 $_ = $_ . ";";
160                 $funcs{$f} = $_;
161             }
162         }
163         $line = "";
164     }
165     if(/\}/){
166         $brace--;
167     }
168     if(/^\}/){
169         $brace = 0;
170     }
171     if($brace == 0) {
172         $line = $line . " " . $_;
173     }
174 }
175
176 sub foo {
177     local ($arg) = @_;
178     $_ = $arg;
179     s/.*\/([^\/]*)/$1/;
180     s/[^a-zA-Z0-9]/_/g;
181     "__" . $_ . "__";
182 }
183
184 if($opt_o) {
185     open(OUT, ">$opt_o");
186     $block = &foo($opt_o);
187 } else {
188     $block = "__public_h__";
189 }
190
191 if($opt_p) {
192     open(PRIV, ">$opt_p");
193     $private = &foo($opt_p);
194 } else {
195     $private = "__private_h__";
196 }
197
198 $public_h = "";
199 $private_h = "";
200
201 $public_h_header .= "/* This is a generated file */
202 #ifndef $block
203 #define $block
204
205 ";
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
217
218 ";
219 } else {
220     $public_h_header .= "#include <stdarg.h>
221
222 ";
223 }
224 $public_h_trailer = "";
225
226 $private_h_header = "/* This is a generated file */
227 #ifndef $private
228 #define $private
229
230 ";
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
242
243 ";
244 } else {
245     $private_h_header .= "#include <stdarg.h>
246
247 ";
248 }
249 $private_h_trailer = "";
250
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;
257         }
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";
265             }
266         }
267         $public_h .= $funcs{$_} . "\n";
268         if($funcs{$_} =~ /__attribute__/) {
269             $public_attribute_seen = 1;
270         }
271         if($flags{"function-blocking"}) {
272             $public_h .= "#endif\n";
273         }
274         $public_h .= "\n";
275     }
276 }
277
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
283
284 ";
285     }
286
287     if ($private_attribute_seen) {
288         $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
289 #define __attribute__(x)
290 #endif
291
292 ";
293     }
294 }
295 if($flags{"cxx"}) {
296     $public_h_header .= "#ifdef __cplusplus
297 extern \"C\" {
298 #endif
299
300 ";
301     $public_h_trailer .= "#ifdef __cplusplus
302 }
303 #endif
304
305 ";
306
307 }
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
318
319 ";
320     
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
330
331 ";
332 }
333     
334 if ($public_h ne "" && $flags{"header"}) {
335     $public_h = $public_h_header . $public_h . 
336         $public_h_trailer . "#endif /* $block */\n";
337 }
338 if ($private_h ne "" && $flags{"header"}) {
339     $private_h = $private_h_header . $private_h .
340         $private_h_trailer . "#endif /* $private */\n";
341 }
342
343 if($opt_o) {
344     print OUT $public_h;
345
346 if($opt_p) {
347     print PRIV $private_h;
348
349
350 close OUT;
351 close PRIV;