1# Make prototypes from .c files 2# $Id: make-proto.pl,v 1.1.1.1 2011/06/10 09:34:43 andrew Exp $ 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 15do Getopts('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/[^a-zA-Z0-9]/_/g; 184 "__" . $_ . "__"; 185} 186 187if($opt_o) { 188 open(OUT, ">$opt_o"); 189 $block = &foo($opt_o); 190} else { 191 $block = "__public_h__"; 192} 193 194if($opt_p) { 195 open(PRIV, ">$opt_p"); 196 $private = &foo($opt_p); 197} else { 198 $private = "__private_h__"; 199} 200 201$public_h = ""; 202$private_h = ""; 203 204$public_h_header .= "/* This is a generated file */ 205#ifndef $block 206#define $block 207 208"; 209if ($oproto) { 210 $public_h_header .= "#ifdef __STDC__ 211#include <stdarg.h> 212#ifndef __P 213#define __P(x) x 214#endif 215#else 216#ifndef __P 217#define __P(x) () 218#endif 219#endif 220 221"; 222} else { 223 $public_h_header .= "#include <stdarg.h> 224 225"; 226} 227$public_h_trailer = ""; 228 229$private_h_header = "/* This is a generated file */ 230#ifndef $private 231#define $private 232 233"; 234if($oproto) { 235 $private_h_header .= "#ifdef __STDC__ 236#include <stdarg.h> 237#ifndef __P 238#define __P(x) x 239#endif 240#else 241#ifndef __P 242#define __P(x) () 243#endif 244#endif 245 246"; 247} else { 248 $private_h_header .= "#include <stdarg.h> 249 250"; 251} 252$private_h_trailer = ""; 253 254foreach(sort keys %funcs){ 255 if(/^(main)$/) { next } 256 if(!defined($exported{$_}) && /$private_func_re/) { 257 $private_h .= $funcs{$_} . "\n\n"; 258 if($funcs{$_} =~ /__attribute__/) { 259 $private_attribute_seen = 1; 260 } 261 } else { 262 if($flags{"function-blocking"}) { 263 $fupper = uc $_; 264 if($exported{$_} =~ /proto/) { 265 $public_h .= "#if !defined(HAVE_$fupper) || defined(NEED_${fupper}_PROTO)\n"; 266 } else { 267 $public_h .= "#ifndef HAVE_$fupper\n"; 268 } 269 } 270 $public_h .= $funcs{$_} . "\n"; 271 if($funcs{$_} =~ /__attribute__/) { 272 $public_attribute_seen = 1; 273 } 274 if($flags{"function-blocking"}) { 275 $public_h .= "#endif\n"; 276 } 277 $public_h .= "\n"; 278 } 279} 280 281if($flags{"gnuc-attribute"}) { 282 if ($public_attribute_seen) { 283 $public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__) 284#define __attribute__(x) 285#endif 286 287"; 288 } 289 290 if ($private_attribute_seen) { 291 $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__) 292#define __attribute__(x) 293#endif 294 295"; 296 } 297} 298if($flags{"cxx"}) { 299 $public_h_header .= "#ifdef __cplusplus 300extern \"C\" { 301#endif 302 303"; 304 $public_h_trailer .= "#ifdef __cplusplus 305} 306#endif 307 308"; 309 310} 311if ($opt_E) { 312 $public_h_header .= "#ifndef $opt_E 313#if defined(_WIN32) 314#define ${opt_E}_FUNCTION __stdcall __declspec(dllimport) 315#define ${opt_E}_VARIABLE __declspec(dllimport) 316#else 317#define ${opt_E}_FUNCTION 318#define ${opt_E}_VARIABLE 319#endif 320#endif 321 322"; 323 324 $private_h_header .= "#ifndef $opt_E 325#if defined(_WIN32) 326#define ${opt_E}_FUNCTION __stdcall __declspec(dllimport) 327#define ${opt_E}_VARIABLE __declspec(dllimport) 328#else 329#define ${opt_E}_FUNCTION 330#define ${opt_E}_VARIABLE 331#endif 332#endif 333 334"; 335} 336 337if ($public_h ne "" && $flags{"header"}) { 338 $public_h = $public_h_header . $public_h . 339 $public_h_trailer . "#endif /* $block */\n"; 340} 341if ($private_h ne "" && $flags{"header"}) { 342 $private_h = $private_h_header . $private_h . 343 $private_h_trailer . "#endif /* $private */\n"; 344} 345 346if($opt_o) { 347 print OUT $public_h; 348} 349if($opt_p) { 350 print PRIV $private_h; 351} 352 353close OUT; 354close PRIV; 355