1# Make prototypes from .c files 2# $Id: make-proto.pl 14183 2004-09-03 08:50:57Z lha $ 3 4##use Getopt::Std; 5require 'getopts.pl'; 6 7$brace = 0; 8$line = ""; 9$debug = 0; 10$oproto = 1; 11$private_func_re = "^_"; 12 13do Getopts('x:m:o:p:dqE:R:P:') || die "foo"; 14 15if($opt_d) { 16 $debug = 1; 17} 18 19if($opt_q) { 20 $oproto = 0; 21} 22 23if($opt_R) { 24 $private_func_re = $opt_R; 25} 26%flags = ( 27 'multiline-proto' => 1, 28 'header' => 1, 29 'function-blocking' => 0, 30 'gnuc-attribute' => 1, 31 'cxx' => 1 32 ); 33if($opt_m) { 34 foreach $i (split(/,/, $opt_m)) { 35 if($i eq "roken") { 36 $flags{"multiline-proto"} = 0; 37 $flags{"header"} = 0; 38 $flags{"function-blocking"} = 0; 39 $flags{"gnuc-attribute"} = 0; 40 $flags{"cxx"} = 0; 41 } else { 42 if(substr($i, 0, 3) eq "no-") { 43 $flags{substr($i, 3)} = 0; 44 } else { 45 $flags{$i} = 1; 46 } 47 } 48 } 49} 50 51if($opt_x) { 52 open(EXP, $opt_x); 53 while(<EXP>) { 54 chomp; 55 s/\#.*//g; 56 s/\s+/ /g; 57 if(/^([a-zA-Z0-9_]+)\s?(.*)$/) { 58 $exported{$1} = $2; 59 } else { 60 print $_, "\n"; 61 } 62 } 63 close EXP; 64} 65 66while(<>) { 67 print $brace, " ", $_ if($debug); 68 if(/^\#if 0/) { 69 $if_0 = 1; 70 } 71 if($if_0 && /^\#endif/) { 72 $if_0 = 0; 73 } 74 if($if_0) { next } 75 if(/^\s*\#/) { 76 next; 77 } 78 if(/^\s*$/) { 79 $line = ""; 80 next; 81 } 82 if(/\{/){ 83 if (!/\}/) { 84 $brace++; 85 } 86 $_ = $line; 87 while(s/\*\//\ca/){ 88 s/\/\*(.|\n)*\ca//; 89 } 90 s/^\s*//; 91 s/\s*$//; 92 s/\s+/ /g; 93 if($_ =~ /\)$/){ 94 if(!/^static/ && !/^PRIVATE/){ 95 if(/(.*)(__attribute__\s?\(.*\))/) { 96 $attr = $2; 97 $_ = $1; 98 } else { 99 $attr = ""; 100 } 101 # remove outer () 102 s/\s*\(/</; 103 s/\)\s?$/>/; 104 # remove , within () 105 while(s/\(([^()]*),(.*)\)/($1\$$2)/g){} 106 s/\<\s*void\s*\>/<>/; 107 # remove parameter names 108 if($opt_P eq "remove") { 109 s/(\s*)([a-zA-Z0-9_]+)([,>])/$3/g; 110 s/\s+\*/*/g; 111 s/\(\*(\s*)([a-zA-Z0-9_]+)\)/(*)/g; 112 } elsif($opt_P eq "comment") { 113 s/([a-zA-Z0-9_]+)([,>])/\/\*$1\*\/$2/g; 114 s/\(\*([a-zA-Z0-9_]+)\)/(*\/\*$1\*\/)/g; 115 } 116 s/\<\>/<void>/; 117 # add newlines before parameters 118 if($flags{"multiline-proto"}) { 119 s/,\s*/,\n\t/g; 120 } else { 121 s/,\s*/, /g; 122 } 123 # fix removed , 124 s/\$/,/g; 125 # match function name 126 /([a-zA-Z0-9_]+)\s*\</; 127 $f = $1; 128 if($oproto) { 129 $LP = "__P(("; 130 $RP = "))"; 131 } else { 132 $LP = "("; 133 $RP = ")"; 134 } 135 # only add newline if more than one parameter 136 if($flags{"multiline-proto"} && /,/){ 137 s/\</ $LP\n\t/; 138 }else{ 139 s/\</ $LP/; 140 } 141 s/\>/$RP/; 142 # insert newline before function name 143 if($flags{"multiline-proto"}) { 144 s/(.*)\s([a-zA-Z0-9_]+ \Q$LP\E)/$1\n$2/; 145 } 146 if($attr ne "") { 147 $_ .= "\n $attr"; 148 } 149 $_ = $_ . ";"; 150 $funcs{$f} = $_; 151 } 152 } 153 $line = ""; 154 } 155 if(/\}/){ 156 $brace--; 157 } 158 if(/^\}/){ 159 $brace = 0; 160 } 161 if($brace == 0) { 162 $line = $line . " " . $_; 163 } 164} 165 166sub foo { 167 local ($arg) = @_; 168 $_ = $arg; 169 s/.*\/([^\/]*)/$1/; 170 s/[^a-zA-Z0-9]/_/g; 171 "__" . $_ . "__"; 172} 173 174if($opt_o) { 175 open(OUT, ">$opt_o"); 176 $block = &foo($opt_o); 177} else { 178 $block = "__public_h__"; 179} 180 181if($opt_p) { 182 open(PRIV, ">$opt_p"); 183 $private = &foo($opt_p); 184} else { 185 $private = "__private_h__"; 186} 187 188$public_h = ""; 189$private_h = ""; 190 191$public_h_header .= "/* This is a generated file */ 192#ifndef $block 193#define $block 194 195"; 196if ($oproto) { 197 $public_h_header .= "#ifdef __STDC__ 198#include <stdarg.h> 199#ifndef __P 200#define __P(x) x 201#endif 202#else 203#ifndef __P 204#define __P(x) () 205#endif 206#endif 207 208"; 209} else { 210 $public_h_header .= "#include <stdarg.h> 211 212"; 213} 214$public_h_trailer = ""; 215 216$private_h_header = "/* This is a generated file */ 217#ifndef $private 218#define $private 219 220"; 221if($oproto) { 222 $private_h_header .= "#ifdef __STDC__ 223#include <stdarg.h> 224#ifndef __P 225#define __P(x) x 226#endif 227#else 228#ifndef __P 229#define __P(x) () 230#endif 231#endif 232 233"; 234} else { 235 $private_h_header .= "#include <stdarg.h> 236 237"; 238} 239$private_h_trailer = ""; 240 241foreach(sort keys %funcs){ 242 if(/^(main)$/) { next } 243 if(!defined($exported{$_}) && /$private_func_re/) { 244 $private_h .= $funcs{$_} . "\n\n"; 245 if($funcs{$_} =~ /__attribute__/) { 246 $private_attribute_seen = 1; 247 } 248 } else { 249 if($flags{"function-blocking"}) { 250 $fupper = uc $_; 251 if($exported{$_} =~ /proto/) { 252 $public_h .= "#if !defined(HAVE_$fupper) || defined(NEED_${fupper}_PROTO)\n"; 253 } else { 254 $public_h .= "#ifndef HAVE_$fupper\n"; 255 } 256 } 257 $public_h .= $funcs{$_} . "\n"; 258 if($funcs{$_} =~ /__attribute__/) { 259 $public_attribute_seen = 1; 260 } 261 if($flags{"function-blocking"}) { 262 $public_h .= "#endif\n"; 263 } 264 $public_h .= "\n"; 265 } 266} 267 268if($flags{"gnuc-attribute"}) { 269 if ($public_attribute_seen) { 270 $public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__) 271#define __attribute__(x) 272#endif 273 274"; 275 } 276 277 if ($private_attribute_seen) { 278 $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__) 279#define __attribute__(x) 280#endif 281 282"; 283 } 284} 285if($flags{"cxx"}) { 286 $public_h_header .= "#ifdef __cplusplus 287extern \"C\" { 288#endif 289 290"; 291 $public_h_trailer .= "#ifdef __cplusplus 292} 293#endif 294 295"; 296 297} 298if ($opt_E) { 299 $public_h_header .= "#ifndef $opt_E 300#if defined(_WIN32) 301#define $opt_E _stdcall 302#else 303#define $opt_E 304#endif 305#endif 306 307"; 308 309 $private_h_header .= "#ifndef $opt_E 310#if defined(_WIN32) 311#define $opt_E _stdcall 312#else 313#define $opt_E 314#endif 315#endif 316 317"; 318} 319 320if ($public_h ne "" && $flags{"header"}) { 321 $public_h = $public_h_header . $public_h . 322 $public_h_trailer . "#endif /* $block */\n"; 323} 324if ($private_h ne "" && $flags{"header"}) { 325 $private_h = $private_h_header . $private_h . 326 $private_h_trailer . "#endif /* $private */\n"; 327} 328 329if($opt_o) { 330 print OUT $public_h; 331} 332if($opt_p) { 333 print PRIV $private_h; 334} 335 336close OUT; 337close PRIV; 338