diff options
Diffstat (limited to 'third_party/heimdal/cf/make-proto.pl')
-rw-r--r-- | third_party/heimdal/cf/make-proto.pl | 528 |
1 files changed, 528 insertions, 0 deletions
diff --git a/third_party/heimdal/cf/make-proto.pl b/third_party/heimdal/cf/make-proto.pl new file mode 100644 index 0000000..36a040c --- /dev/null +++ b/third_party/heimdal/cf/make-proto.pl @@ -0,0 +1,528 @@ +# Make prototypes from .c files +# $Id$ + +use Getopt::Std; +use File::Compare; + +use JSON; + +my $comment = 0; +my $doxygen = 0; +my $funcdoc = 0; +my $if_0 = 0; +my $brace = 0; +my $line = ""; +my $debug = 0; +my $oproto = 1; +my $private_func_re = "^_"; +my %depfunction; +my %exported; +my %deprecated; +my $apple = 0; +my %documentation; + +getopts('x:m:o:p:dqE:R:P:') || die "foo"; +if($opt_a) { + $apple = 1; +} + +if($opt_a) { + $apple = 1; +} + +if($opt_d) { + $debug = 1; +} + +if($opt_q) { + $oproto = 0; +} + +if($opt_R) { + $private_func_re = $opt_R; +} +my %flags = ( + 'multiline-proto' => 1, + 'header' => 1, + 'function-blocking' => 0, + 'gnuc-attribute' => 1, + 'cxx' => 1 + ); +if($opt_m) { + foreach $i (split(/,/, $opt_m)) { + if($i eq "roken") { + $flags{"multiline-proto"} = 0; + $flags{"header"} = 0; + $flags{"function-blocking"} = 0; + $flags{"gnuc-attribute"} = 0; + $flags{"cxx"} = 0; + } else { + if(substr($i, 0, 3) eq "no-") { + $flags{substr($i, 3)} = 0; + } else { + $flags{$i} = 1; + } + } + } +} + +if($opt_x) { + my $EXP; + local $/; + open(EXP, '<', $opt_x) || die "open ${opt_x}"; + my $obj = JSON->new->utf8->decode(<EXP>); + close $EXP; + + foreach my $x (keys %$obj) { + if (defined $obj->{$x}->{"export"}) { + $exported{$x} = $obj->{$x}; + } + if (defined $obj->{$x}->{"deprecated"}) { + $deprecated{$x} = $obj->{$x}->{"deprecated"}; + } + } +} + +while(<>) { + print $brace, " ", $_ if($debug); + + # Handle C comments + s@/\*.*\*/@@; + s@//.*/@@; + if ( s@/\*\*(.*)@@) { $comment = 1; $doxygen = 1; $funcdoc = $1; + } elsif ( s@/\*.*@@) { $comment = 1; + } elsif ($comment && s@.*\*/@@) { $comment = 0; $doxygen = 0; + } elsif ($doxygen) { $funcdoc .= $_; next; + } elsif ($comment) { next; } + + # Handle CPP #define's + $define = 1 if /^\s*\#\s*define/; + if ($define) { + $define = 0 if ! /\\$/; + next; + } + + if(/^\#if 0/) { + $if_0 = 1; + } + if($if_0 && /^\#endif/) { + $if_0 = 0; + } + if($if_0) { next } + if(/^\s*\#/) { + next; + } + if(/^\s*$/) { + $line = ""; + next; + } + if(/\{/){ + if (!/\}/) { + $brace++; + } + $_ = $line; + while(s/\*\//\ca/){ + s/\/\*(.|\n)*\ca//; + } + s/^\s*//; + s/\s*$//; + s/\s+/ /g; + if($_ =~ /\)$/){ + if(!/^static/ && !/^PRIVATE/){ + $attr = ""; + if(m/(.*)(__attribute__\s?\(.*\))/) { + $attr .= " $2"; + $_ = $1; + } + if(m/(.*)\s(\w+DEPRECATED_FUNCTION)\s?(\(.*\))(.*)/) { + $depfunction{$2} = 1; + $attr .= " $2$3"; + $_ = "$1 $4"; + } + if(m/(.*)\s(\w+DEPRECATED)(.*)/) { + $attr .= " $2"; + $_ = "$1 $3"; + } + if(m/(.*)\s(HEIMDAL_\w+_ATTRIBUTE)\s?(\(.*\))?(.*)/) { + $attr .= " $2$3"; + $_ = "$1 $4"; + } + # remove outer () + s/\s*\(/</; + s/\)\s?$/>/; + # remove , within () + while(s/\(([^()]*),(.*)\)/($1\$$2)/g){} + s/\<\s*void\s*\>/<>/; + # remove parameter names + if($opt_P eq "remove") { + s/(\s*)([a-zA-Z0-9_]+)([,>])/$3/g; + s/\s+\*/*/g; + s/\(\*(\s*)([a-zA-Z0-9_]+)\)/(*)/g; + } elsif($opt_P eq "comment") { + s/([a-zA-Z0-9_]+)([,>])/\/\*$1\*\/$2/g; + s/\(\*([a-zA-Z0-9_]+)\)/(*\/\*$1\*\/)/g; + } + s/\<\>/<void>/; + # add newlines before parameters + if($flags{"multiline-proto"}) { + s/,\s*/,\n\t/g; + } else { + s/,\s*/, /g; + } + # fix removed , + s/\$/,/g; + # match function name + /([a-zA-Z0-9_]+)\s*\</; + $f = $1; + if($oproto) { + $LP = "__P(("; + $RP = "))"; + } else { + $LP = "("; + $RP = ")"; + } + # only add newline if more than one parameter + if($flags{"multiline-proto"} && /,/){ + s/\</ $LP\n\t/; + }else{ + s/\</ $LP/; + } + s/\>/$RP/; + # insert newline before function name + if($flags{"multiline-proto"}) { + s/(.*)\s([a-zA-Z0-9_]+ \Q$LP\E)/$1\n$2/; + } + if($attr ne "") { + $_ .= "\n $attr"; + } + if ($funcdoc) { + $documentation{$f} = $funcdoc; + } + $funcdoc = undef; + if ($apple && exists $exported{$f}) { + $ios = $exported{$f}{ios}; + $ios = "NA" if (!defined $ios); + $mac = $exported{$f}{macos}; + $mac = "NA" if (!defined $mac); + die "$f neither" if ($mac eq "NA" and $ios eq "NA"); + $_ = $_ . " __OSX_AVAILABLE_STARTING(__MAC_${mac}, __IPHONE_${ios})"; + } + if (exists $deprecated{$f}) { + $_ = $_ . " GSSAPI_DEPRECATED_FUNCTION(\"$deprecated{$f}\")"; + $depfunction{GSSAPI_DEPRECATED_FUNCTION} = 1; + } + $_ = $_ . ";"; + $funcs{$f} = $_; + } + } + $line = ""; + } + if(/\}/){ + $brace--; + } + if(/^\}/){ + $brace = 0; + } + if($brace == 0) { + $line = $line . " " . $_; + } +} + +die "reached end of code and still in doxygen comment" if ($doxygen); +die "reached end of code and still in comment" if ($comment); + +sub foo { + local ($arg) = @_; + $_ = $arg; + s/.*\/([^\/]*)/$1/; + s/.*\\([^\\]*)/$1/; + s/[^a-zA-Z0-9]/_/g; + "__" . $_ . "__"; +} + +if($opt_o) { + open(OUT, ">${opt_o}.new"); + $block = &foo($opt_o); +} else { + $block = "__public_h__"; +} + +if($opt_p) { + open(PRIV, ">${opt_p}.new"); + $private = &foo($opt_p); +} else { + $private = "__private_h__"; +} + +$public_h = ""; +$private_h = ""; + +$public_h_header .= "/* This is a generated file */ +#ifndef $block +#define $block +#ifndef DOXY + +"; +if ($oproto) { + $public_h_header .= "#ifdef __STDC__ +#include <stdarg.h> +#ifndef __P +#define __P(x) x +#endif +#else +#ifndef __P +#define __P(x) () +#endif +#endif + +"; +} else { + $public_h_header .= "#include <stdarg.h> + +"; +} +$public_h_trailer = ""; + +$private_h_header = "/* This is a generated file */ +#ifndef $private +#define $private + +"; +if($oproto) { + $private_h_header .= "#ifdef __STDC__ +#include <stdarg.h> +#ifndef __P +#define __P(x) x +#endif +#else +#ifndef __P +#define __P(x) () +#endif +#endif + +"; +} else { + $private_h_header .= "#include <stdarg.h> + +"; +} +$private_h_trailer = ""; + + +foreach(sort keys %funcs){ + if(/^(DllMain|main)$/) { next } + if ($funcs{$_} =~ /\^/) { + $beginblock = "#ifdef __BLOCKS__\n"; + $endblock = "#endif /* __BLOCKS__ */\n"; + } else { + $beginblock = $endblock = ""; + } + # if we have an export table and doesn't have content, or matches private RE + if((scalar(keys(%exported)) ne 0 && !exists $exported{$_} ) || /$private_func_re/) { + $private_h .= $beginblock; +# if ($apple and not /$private_func_re/) { +# $private_h .= "#define $_ __ApplePrivate_${_}\n"; +# } + $private_h .= $funcs{$_} . "\n" ; + $private_h .= $endblock . "\n"; + if($funcs{$_} =~ /__attribute__/) { + $private_attribute_seen = 1; + } + } else { + if($documentation{$_}) { + $public_h .= "/**\n"; + $public_h .= "$documentation{$_}"; + $public_h .= " */\n\n"; + } + if($flags{"function-blocking"}) { + $fupper = uc $_; + if($exported{$_} =~ /proto/) { + $public_h .= "#if !defined(HAVE_$fupper) || defined(NEED_${fupper}_PROTO)\n"; + } else { + $public_h .= "#ifndef HAVE_$fupper\n"; + } + } + $public_h .= $beginblock . $funcs{$_} . "\n" . $endblock; + if($funcs{$_} =~ /__attribute__/) { + $public_attribute_seen = 1; + } + if($flags{"function-blocking"}) { + $public_h .= "#endif\n"; + } + $public_h .= "\n"; + } +} + +if($flags{"gnuc-attribute"}) { + if ($public_attribute_seen) { + $public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +"; + } + + if ($private_attribute_seen) { + $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +"; + } +} + +my $depstr = ""; +my $undepstr = ""; +foreach (keys %depfunction) { + $depstr .= "#ifndef $_ +#ifndef __has_extension +#define __has_extension(x) 0 +#define ${_}has_extension 1 +#endif +#if __has_extension(attribute_deprecated_with_message) +#define $_(x) __attribute__((__deprecated__(x))) +#elif defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 ))) +#define $_(X) __attribute__((__deprecated__)) +#else +#define $_(X) +#endif +#ifdef ${_}has_extension +#undef __has_extension +#undef ${_}has_extension +#endif +#endif /* $_ */ + + +"; + $public_h_trailer .= "#undef $_ + +"; + $private_h_trailer .= "#undef $_ +#define $_(X) + +"; +} + +$public_h_header .= $depstr; +$private_h_header .= $depstr; + + +if($flags{"cxx"}) { + $public_h_header .= "#ifdef __cplusplus +extern \"C\" { +#endif + +"; + $public_h_trailer = "#ifdef __cplusplus +} +#endif + +" . $public_h_trailer; + +} +if ($opt_E) { + $public_h_header .= "#ifndef $opt_E + #ifndef ${opt_E}_FUNCTION + #if defined(_WIN32) + #define ${opt_E}_FUNCTION __declspec(dllimport) + #else + #define ${opt_E}_FUNCTION + #endif + #endif + #ifndef ${opt_E}_NORETURN_FUNCTION + #if defined(_WIN32) + #define ${opt_E}_NORETURN_FUNCTION __declspec(dllimport noreturn) + #else + #define ${opt_E}_NORETURN_FUNCTION + #endif + #endif + #ifndef ${opt_E}_CALL + #if defined(_WIN32) + #define ${opt_E}_CALL __stdcall + #else + #define ${opt_E}_CALL + #endif + #endif + #ifndef ${opt_E}_VARIABLE + #if defined(_WIN32) + #define ${opt_E}_VARIABLE __declspec(dllimport) + #else + #define ${opt_E}_VARIABLE + #endif + #endif +#endif +"; + + $private_h_header .= "#ifndef $opt_E + #ifndef ${opt_E}_FUNCTION + #if defined(_WIN32) + #define ${opt_E}_FUNCTION __declspec(dllimport) + #else + #define ${opt_E}_FUNCTION + #endif + #endif + #ifndef ${opt_E}_NORETURN_FUNCTION + #if defined(_WIN32) + #define ${opt_E}_NORETURN_FUNCTION __declspec(dllimport noreturn) + #else + #define ${opt_E}_NORETURN_FUNCTION + #endif + #endif + #ifndef ${opt_E}_CALL + #if defined(_WIN32) + #define ${opt_E}_CALL __stdcall + #else + #define ${opt_E}_CALL + #endif + #endif + #ifndef ${opt_E}_VARIABLE + #if defined(_WIN32) + #define ${opt_E}_VARIABLE __declspec(dllimport) + #else + #define ${opt_E}_VARIABLE + #endif + #endif +#endif +"; +} + +$public_h_trailer .= $undepstr; +$private_h_trailer .= $undepstr; + +if ($public_h ne "" && $flags{"header"}) { + $public_h = $public_h_header . $public_h . + $public_h_trailer . "#endif /* DOXY */\n#endif /* $block */\n"; +} +if ($private_h ne "" && $flags{"header"}) { + $private_h = $private_h_header . $private_h . + $private_h_trailer . "#endif /* $private */\n"; +} + +if($opt_o) { + print OUT $public_h; +} +if($opt_p) { + print PRIV $private_h; +} + +close OUT; +close PRIV; + +if ($opt_o) { + + if (compare("${opt_o}.new", ${opt_o}) != 0) { + printf("updating ${opt_o}\n"); + rename("${opt_o}.new", ${opt_o}); + } else { + unlink("${opt_o}.new"); + } +} + +if ($opt_p) { + if (compare("${opt_p}.new", ${opt_p}) != 0) { + printf("updating ${opt_p}\n"); + rename("${opt_p}.new", ${opt_p}); + } else { + unlink("${opt_p}.new"); + } +} |