rebuild krb5-protos.h and krb5-private.h if in maintainer-mode
[heimdal.git] / cf / make-proto.pl
blob055bc4e52960672f2bd6606c5ae7ec25208745ce
1 # Make prototypes from .c files
2 # $Id$
4 ##use Getopt::Std;
5 require 'getopts.pl';
6 use File::Compare;
8 my $comment = 0;
9 my $if_0 = 0;
10 my $brace = 0;
11 my $line = "";
12 my $debug = 0;
13 my $oproto = 1;
14 my $private_func_re = "^_";
15 my %depfunction = ();
17 Getopts('x:m:o:p:dqE:R:P:') || die "foo";
19 if($opt_d) {
20 $debug = 1;
23 if($opt_q) {
24 $oproto = 0;
27 if($opt_R) {
28 $private_func_re = $opt_R;
30 my %flags = (
31 'multiline-proto' => 1,
32 'header' => 1,
33 'function-blocking' => 0,
34 'gnuc-attribute' => 1,
35 'cxx' => 1
37 if($opt_m) {
38 foreach $i (split(/,/, $opt_m)) {
39 if($i eq "roken") {
40 $flags{"multiline-proto"} = 0;
41 $flags{"header"} = 0;
42 $flags{"function-blocking"} = 0;
43 $flags{"gnuc-attribute"} = 0;
44 $flags{"cxx"} = 0;
45 } else {
46 if(substr($i, 0, 3) eq "no-") {
47 $flags{substr($i, 3)} = 0;
48 } else {
49 $flags{$i} = 1;
55 if($opt_x) {
56 open(EXP, $opt_x);
57 while(<EXP>) {
58 chomp;
59 s/\#.*//g;
60 s/\s+/ /g;
61 if(/^([a-zA-Z0-9_]+)\s?(.*)$/) {
62 $exported{$1} = $2;
63 } else {
64 print $_, "\n";
67 close EXP;
70 while(<>) {
71 print $brace, " ", $_ if($debug);
73 # Handle C comments
74 s@/\*.*\*/@@;
75 s@//.*/@@;
76 if ( s@/\*.*@@) { $comment = 1;
77 } elsif ($comment && s@.*\*/@@) { $comment = 0;
78 } elsif ($comment) { next; }
80 if(/^\#if 0/) {
81 $if_0 = 1;
83 if($if_0 && /^\#endif/) {
84 $if_0 = 0;
86 if($if_0) { next }
87 if(/^\s*\#/) {
88 next;
90 if(/^\s*$/) {
91 $line = "";
92 next;
94 if(/\{/){
95 if (!/\}/) {
96 $brace++;
98 $_ = $line;
99 while(s/\*\//\ca/){
100 s/\/\*(.|\n)*\ca//;
102 s/^\s*//;
103 s/\s*$//;
104 s/\s+/ /g;
105 if($_ =~ /\)$/){
106 if(!/^static/ && !/^PRIVATE/){
107 $attr = "";
108 if(m/(.*)(__attribute__\s?\(.*\))/) {
109 $attr .= " $2";
110 $_ = $1;
112 if(m/(.*)\s(\w+DEPRECATED_FUNCTION)\s?(\(.*\))(.*)/) {
113 $depfunction{$2} = 1;
114 $attr .= " $2$3";
115 $_ = "$1 $4";
117 if(m/(.*)\s(\w+DEPRECATED)(.*)/) {
118 $attr .= " $2";
119 $_ = "$1 $3";
121 # remove outer ()
122 s/\s*\(/</;
123 s/\)\s?$/>/;
124 # remove , within ()
125 while(s/\(([^()]*),(.*)\)/($1\$$2)/g){}
126 s/\<\s*void\s*\>/<>/;
127 # remove parameter names
128 if($opt_P eq "remove") {
129 s/(\s*)([a-zA-Z0-9_]+)([,>])/$3/g;
130 s/\s+\*/*/g;
131 s/\(\*(\s*)([a-zA-Z0-9_]+)\)/(*)/g;
132 } elsif($opt_P eq "comment") {
133 s/([a-zA-Z0-9_]+)([,>])/\/\*$1\*\/$2/g;
134 s/\(\*([a-zA-Z0-9_]+)\)/(*\/\*$1\*\/)/g;
136 s/\<\>/<void>/;
137 # add newlines before parameters
138 if($flags{"multiline-proto"}) {
139 s/,\s*/,\n\t/g;
140 } else {
141 s/,\s*/, /g;
143 # fix removed ,
144 s/\$/,/g;
145 # match function name
146 /([a-zA-Z0-9_]+)\s*\</;
147 $f = $1;
148 if($oproto) {
149 $LP = "__P((";
150 $RP = "))";
151 } else {
152 $LP = "(";
153 $RP = ")";
155 # only add newline if more than one parameter
156 if($flags{"multiline-proto"} && /,/){
157 s/\</ $LP\n\t/;
158 }else{
159 s/\</ $LP/;
161 s/\>/$RP/;
162 # insert newline before function name
163 if($flags{"multiline-proto"}) {
164 s/(.*)\s([a-zA-Z0-9_]+ \Q$LP\E)/$1\n$2/;
166 if($attr ne "") {
167 $_ .= "\n $attr";
169 $_ = $_ . ";";
170 $funcs{$f} = $_;
173 $line = "";
175 if(/\}/){
176 $brace--;
178 if(/^\}/){
179 $brace = 0;
181 if($brace == 0) {
182 $line = $line . " " . $_;
186 sub foo {
187 local ($arg) = @_;
188 $_ = $arg;
189 s/.*\/([^\/]*)/$1/;
190 s/.*\\([^\\]*)/$1/;
191 s/[^a-zA-Z0-9]/_/g;
192 "__" . $_ . "__";
195 if($opt_o) {
196 open(OUT, ">${opt_o}.new");
197 $block = &foo($opt_o);
198 } else {
199 $block = "__public_h__";
202 if($opt_p) {
203 open(PRIV, ">${opt_p}.new");
204 $private = &foo($opt_p);
205 } else {
206 $private = "__private_h__";
209 $public_h = "";
210 $private_h = "";
212 $public_h_header .= "/* This is a generated file */
213 #ifndef $block
214 #define $block
217 if ($oproto) {
218 $public_h_header .= "#ifdef __STDC__
219 #include <stdarg.h>
220 #ifndef __P
221 #define __P(x) x
222 #endif
223 #else
224 #ifndef __P
225 #define __P(x) ()
226 #endif
227 #endif
230 } else {
231 $public_h_header .= "#include <stdarg.h>
235 $public_h_trailer = "";
237 $private_h_header = "/* This is a generated file */
238 #ifndef $private
239 #define $private
242 if($oproto) {
243 $private_h_header .= "#ifdef __STDC__
244 #include <stdarg.h>
245 #ifndef __P
246 #define __P(x) x
247 #endif
248 #else
249 #ifndef __P
250 #define __P(x) ()
251 #endif
252 #endif
255 } else {
256 $private_h_header .= "#include <stdarg.h>
260 $private_h_trailer = "";
262 foreach(sort keys %funcs){
263 if(/^(main)$/) { next }
264 if ($funcs{$_} =~ /\^/) {
265 $beginblock = "#ifdef __BLOCKS__\n";
266 $endblock = "#endif /* __BLOCKS__ */\n";
267 } else {
268 $beginblock = $endblock = "";
270 if(!defined($exported{$_}) && /$private_func_re/) {
271 $private_h .= $beginblock . $funcs{$_} . "\n" . $endblock . "\n";
272 if($funcs{$_} =~ /__attribute__/) {
273 $private_attribute_seen = 1;
275 } else {
276 if($flags{"function-blocking"}) {
277 $fupper = uc $_;
278 if($exported{$_} =~ /proto/) {
279 $public_h .= "#if !defined(HAVE_$fupper) || defined(NEED_${fupper}_PROTO)\n";
280 } else {
281 $public_h .= "#ifndef HAVE_$fupper\n";
284 $public_h .= $beginblock . $funcs{$_} . "\n" . $endblock;
285 if($funcs{$_} =~ /__attribute__/) {
286 $public_attribute_seen = 1;
288 if($flags{"function-blocking"}) {
289 $public_h .= "#endif\n";
291 $public_h .= "\n";
295 if($flags{"gnuc-attribute"}) {
296 if ($public_attribute_seen) {
297 $public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
298 #define __attribute__(x)
299 #endif
304 if ($private_attribute_seen) {
305 $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
306 #define __attribute__(x)
307 #endif
313 my $depstr = "";
314 my $undepstr = "";
315 foreach (keys %depfunction) {
316 $depstr .= "#ifndef $_
317 #ifndef __has_extension
318 #define __has_extension(x) 0
319 #define ${_}has_extension 1
320 #endif
321 #if __has_extension(attribute_deprecated_with_message)
322 #define $_(x) __attribute__((__deprecated__(x)))
323 #elif defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
324 #define $_(X) __attribute__((__deprecated__))
325 #else
326 #define $_(X)
327 #endif
328 #ifdef ${_}has_extension
329 #undef __has_extension
330 #undef ${_}has_extension
331 #endif
332 #endif /* $_ */
336 $public_h_trailer .= "#undef $_
339 $private_h_trailer .= "#undef $_
340 #define $_(X)
345 $public_h_header .= $depstr;
346 $private_h_header .= $depstr;
349 if($flags{"cxx"}) {
350 $public_h_header .= "#ifdef __cplusplus
351 extern \"C\" {
352 #endif
355 $public_h_trailer = "#ifdef __cplusplus
357 #endif
359 " . $public_h_trailer;
362 if ($opt_E) {
363 $public_h_header .= "#ifndef $opt_E
364 #ifndef ${opt_E}_FUNCTION
365 #if defined(_WIN32)
366 #define ${opt_E}_FUNCTION __declspec(dllimport)
367 #define ${opt_E}_CALL __stdcall
368 #define ${opt_E}_VARIABLE __declspec(dllimport)
369 #else
370 #define ${opt_E}_FUNCTION
371 #define ${opt_E}_CALL
372 #define ${opt_E}_VARIABLE
373 #endif
374 #endif
375 #endif
378 $private_h_header .= "#ifndef $opt_E
379 #ifndef ${opt_E}_FUNCTION
380 #if defined(_WIN32)
381 #define ${opt_E}_FUNCTION __declspec(dllimport)
382 #define ${opt_E}_CALL __stdcall
383 #define ${opt_E}_VARIABLE __declspec(dllimport)
384 #else
385 #define ${opt_E}_FUNCTION
386 #define ${opt_E}_CALL
387 #define ${opt_E}_VARIABLE
388 #endif
389 #endif
390 #endif
395 $public_h_trailer .= $undepstr;
396 $private_h_trailer .= $undepstr;
398 if ($public_h ne "" && $flags{"header"}) {
399 $public_h = $public_h_header . $public_h .
400 $public_h_trailer . "#endif /* $block */\n";
402 if ($private_h ne "" && $flags{"header"}) {
403 $private_h = $private_h_header . $private_h .
404 $private_h_trailer . "#endif /* $private */\n";
407 if($opt_o) {
408 print OUT $public_h;
410 if($opt_p) {
411 print PRIV $private_h;
414 close OUT;
415 close PRIV;
417 if ($opt_o) {
419 if (compare("${opt_o}.new", ${opt_o}) != 0) {
420 printf("updating ${opt_o}\n");
421 rename("${opt_o}.new", ${opt_o});
422 } else {
423 unlink("${opt_o}.new");
427 if ($opt_p) {
428 if (compare("${opt_p}.new", ${opt_p}) != 0) {
429 printf("updating ${opt_p}\n");
430 rename("${opt_p}.new", ${opt_p});
431 } else {
432 unlink("${opt_p}.new");