1# Make prototypes from .c files 2# Id 3 4##use Getopt::Std; 5require 'getopts.pl'; 6 7my $comment = 0; 8my $if_0 = 0; 9my $brace = 0; 10my $line = ""; 11my $debug = 0; 12my $oproto = 1; 13my $private_func_re = "^_"; 14 15Getopts('x:m:o:p:dqE:R:P:') || die "foo"; 16 17if($opt_d) { 18 $debug = 1; 19} 20 21if($opt_q) { 22 $oproto = 0; 23} 24 25if($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 ); 35if($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 53if($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 68while(<>) { 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($_ =~ /\)$/ or $_ =~ /DEPRECATED$/){ 104 if(!/^static/ && !/^PRIVATE/){ 105 $attr = ""; 106 if(m/(.*)(__attribute__\s?\(.*\))/) { 107 $attr .= " $2"; 108 $_ = $1; 109 } 110 if(m/(.*)\s(\w+DEPRECATED)/) { 111 $attr .= " $2"; 112 $_ = $1; 113 } 114 # remove outer () 115 s/\s*\(/</; 116 s/\)\s?$/>/; 117 # remove , within () 118 while(s/\(([^()]*),(.*)\)/($1\$$2)/g){} 119 s/\<\s*void\s*\>/<>/; 120 # remove parameter names 121 if($opt_P eq "remove") { 122 s/(\s*)([a-zA-Z0-9_]+)([,>])/$3/g; 123 s/\s+\*/*/g; 124 s/\(\*(\s*)([a-zA-Z0-9_]+)\)/(*)/g; 125 } elsif($opt_P eq "comment") { 126 s/([a-zA-Z0-9_]+)([,>])/\/\*$1\*\/$2/g; 127 s/\(\*([a-zA-Z0-9_]+)\)/(*\/\*$1\*\/)/g; 128 } 129 s/\<\>/<void>/; 130 # add newlines before parameters 131 if($flags{"multiline-proto"}) { 132 s/,\s*/,\n\t/g; 133 } else { 134 s/,\s*/, /g; 135 } 136 # fix removed , 137 s/\$/,/g; 138 # match function name 139 /([a-zA-Z0-9_]+)\s*\</; 140 $f = $1; 141 if($oproto) { 142 $LP = "__P(("; 143 $RP = "))"; 144 } else { 145 $LP = "("; 146 $RP = ")"; 147 } 148 # only add newline if more than one parameter 149 if($flags{"multiline-proto"} && /,/){ 150 s/\</ $LP\n\t/; 151 }else{ 152 s/\</ $LP/; 153 } 154 s/\>/$RP/; 155 # insert newline before function name 156 if($flags{"multiline-proto"}) { 157 s/(.*)\s([a-zA-Z0-9_]+ \Q$LP\E)/$1\n$2/; 158 } 159 if($attr ne "") { 160 $_ .= "\n $attr"; 161 } 162 $_ = $_ . ";"; 163 $funcs{$f} = $_; 164 } 165 } 166 $line = ""; 167 } 168 if(/\}/){ 169 $brace--; 170 } 171 if(/^\}/){ 172 $brace = 0; 173 } 174 if($brace == 0) { 175 $line = $line . " " . $_; 176 } 177} 178 179sub foo { 180 local ($arg) = @_; 181 $_ = $arg; 182 s/.*\/([^\/]*)/$1/; 183 s/.*\\([^\\]*)/$1/; 184 s/[^a-zA-Z0-9]/_/g; 185 "__" . $_ . "__"; 186} 187 188if($opt_o) { 189 open(OUT, ">$opt_o"); 190 $block = &foo($opt_o); 191} else { 192 $block = "__public_h__"; 193} 194 195if($opt_p) { 196 open(PRIV, ">$opt_p"); 197 $private = &foo($opt_p); 198} else { 199 $private = "__private_h__"; 200} 201 202$public_h = ""; 203$private_h = ""; 204 205$public_h_header .= "/* This is a generated file */ 206#ifndef $block 207#define $block 208 209"; 210if ($oproto) { 211 $public_h_header .= "#ifdef __STDC__ 212#include <stdarg.h> 213#ifndef __P 214#define __P(x) x 215#endif 216#else 217#ifndef __P 218#define __P(x) () 219#endif 220#endif 221 222"; 223} else { 224 $public_h_header .= "#include <stdarg.h> 225 226"; 227} 228$public_h_trailer = ""; 229 230$private_h_header = "/* This is a generated file */ 231#ifndef $private 232#define $private 233 234"; 235if($oproto) { 236 $private_h_header .= "#ifdef __STDC__ 237#include <stdarg.h> 238#ifndef __P 239#define __P(x) x 240#endif 241#else 242#ifndef __P 243#define __P(x) () 244#endif 245#endif 246 247"; 248} else { 249 $private_h_header .= "#include <stdarg.h> 250 251"; 252} 253$private_h_trailer = ""; 254 255foreach(sort keys %funcs){ 256 if(/^(main)$/) { next } 257 if ($funcs{$_} =~ /\^/) { 258 $beginblock = "#ifdef __BLOCKS__\n"; 259 $endblock = "#endif /* __BLOCKS__ */\n"; 260 } else { 261 $beginblock = $endblock = ""; 262 } 263 if(!defined($exported{$_}) && /$private_func_re/) { 264 $private_h .= $beginblock . $funcs{$_} . "\n" . $endblock . "\n"; 265 if($funcs{$_} =~ /__attribute__/) { 266 $private_attribute_seen = 1; 267 } 268 } else { 269 if($flags{"function-blocking"}) { 270 $fupper = uc $_; 271 if($exported{$_} =~ /proto/) { 272 $public_h .= "#if !defined(HAVE_$fupper) || defined(NEED_${fupper}_PROTO)\n"; 273 } else { 274 $public_h .= "#ifndef HAVE_$fupper\n"; 275 } 276 } 277 $public_h .= $beginblock . $funcs{$_} . "\n" . $endblock; 278 if($funcs{$_} =~ /__attribute__/) { 279 $public_attribute_seen = 1; 280 } 281 if($flags{"function-blocking"}) { 282 $public_h .= "#endif\n"; 283 } 284 $public_h .= "\n"; 285 } 286} 287 288if($flags{"gnuc-attribute"}) { 289 if ($public_attribute_seen) { 290 $public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__) 291#define __attribute__(x) 292#endif 293 294"; 295 } 296 297 if ($private_attribute_seen) { 298 $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__) 299#define __attribute__(x) 300#endif 301 302"; 303 } 304} 305if($flags{"cxx"}) { 306 $public_h_header .= "#ifdef __cplusplus 307extern \"C\" { 308#endif 309 310"; 311 $public_h_trailer .= "#ifdef __cplusplus 312} 313#endif 314 315"; 316 317} 318if ($opt_E) { 319 $public_h_header .= "#ifndef $opt_E 320#ifndef ${opt_E}_FUNCTION 321#if defined(_WIN32) 322#define ${opt_E}_FUNCTION __declspec(dllimport) 323#define ${opt_E}_CALL __stdcall 324#define ${opt_E}_VARIABLE __declspec(dllimport) 325#else 326#define ${opt_E}_FUNCTION 327#define ${opt_E}_CALL 328#define ${opt_E}_VARIABLE 329#endif 330#endif 331#endif 332"; 333 334 $private_h_header .= "#ifndef $opt_E 335#ifndef ${opt_E}_FUNCTION 336#if defined(_WIN32) 337#define ${opt_E}_FUNCTION __declspec(dllimport) 338#define ${opt_E}_CALL __stdcall 339#define ${opt_E}_VARIABLE __declspec(dllimport) 340#else 341#define ${opt_E}_FUNCTION 342#define ${opt_E}_CALL 343#define ${opt_E}_VARIABLE 344#endif 345#endif 346#endif 347 348"; 349} 350 351if ($public_h ne "" && $flags{"header"}) { 352 $public_h = $public_h_header . $public_h . 353 $public_h_trailer . "#endif /* $block */\n"; 354} 355if ($private_h ne "" && $flags{"header"}) { 356 $private_h = $private_h_header . $private_h . 357 $private_h_trailer . "#endif /* $private */\n"; 358} 359 360if($opt_o) { 361 print OUT $public_h; 362} 363if($opt_p) { 364 print PRIV $private_h; 365} 366 367close OUT; 368close PRIV; 369