Path: blob/main/crypto/krb5/src/util/def-check.pl
105262 views
#!/usr/athena/bin/perl -w12# Code initially generated by s2p3# Code modified to use strict and IO::File45eval 'exec /usr/athena/bin/perl -S $0 ${1+"$@"}'6if 0; # line above evaluated when running under some shell (i.e., not perl)78use strict;9use IO::File;1011my $verbose = 0;12my $error = 0;13if ( $ARGV[0] eq "-v" ) { $verbose = 1; shift @ARGV; }14my $h_filename = shift @ARGV || die "usage: $0 [-v] header-file [def-file]\n";15my $d_filename = shift @ARGV;1617my $h = open_always($h_filename);18my $d = open_always($d_filename) if $d_filename;1920sub open_always21{22my $file = shift || die;23my $handle = new IO::File "<$file";24die "Could not open $file\n" if !$handle;25return $handle;26}2728my @convW = ();29my @convC = ();30my @convK = ();31my @convD = ();32my @vararg = ();3334my $len1;35my %conv;36my $printit;37my $vararg;3839LINE:40while (! $h->eof()) {41$_ = $h->getline();42s/(\r)?\n$//;43# get calling convention info for function decls44# what about function pointer typedefs?45# need to verify unhandled syntax actually triggers a report, not ignored46# blank lines47if (/^[ \t\cZ]*$/) {48next LINE;49}50Top:51# drop KRB5INT_BEGIN_DECLS and KRB5INT_END_DECLS52if (/^ *(KRB5INT|GSSAPI[A-Z]*)_(BEGIN|END)_DECLS/) {53next LINE;54}55# drop preprocessor directives56if (/^ *#/) {57while (/\\$/) { $_ .= $h->getline(); }58next LINE;59}60if (/^ *\?==/) {61next LINE;62}63s/#.*$//;64if (/^\} *$/) {65next LINE;66}67# strip comments68Cloop1:69if (/\/\*./) {70s;/\*[^*]*;/*;;71s;/\*\*([^/]);/*$1;;72s;/\*\*$;/*;;73s;/\*\*/; ;g;74goto Cloop1;75}76# multi-line comments?77if (/\/\*$/) {78$_ .= " ";79$len1 = length;80$_ .= $h->getline();81s/(\r)?\n$// if $len1 < length;82goto Cloop1 if /\/\*./;83}84# blank lines85if (/^[ \t]*$/) {86next LINE;87}88if (/^ *extern "C" \{/) {89next LINE;90}91s/KRB5_ATTR_DEPRECATED//;92# elide struct definitions93Struct1:94if (/\{[^}]*\}/) {95s/\{[^}]*\}/ /g;96goto Struct1;97}98# multi-line defs99if (/\{/) {100$_ .= "\n";101$len1 = length;102$_ .= $h->getline();103s/(\r)?\n$// if $len1 < length;104goto Struct1;105}106Semi:107unless (/;/) {108$_ .= "\n";109$len1 = length;110$_ .= $h->getline();111s/(\r)?\n$// if $len1 < length;112s/\n/ /g;113s/[ \t]+/ /g;114s/^[ \t]*//;115goto Top;116}117if (/^typedef[^;]*;/) {118s/^typedef[^;]*;//g;119goto Semi;120}121if (/^struct[^\(\)]*;/) {122s/^struct[^\(\)]*;//g;123goto Semi;124}125# should just have simple decls now; split lines at semicolons126s/ *;[ \t]*$//;127s/ *;/\n/g;128if (/^[ \t]*$/) {129next LINE;130}131s/[ \t]*$//;132goto Notfunct unless /\(.*\)/;133# Get rid of KRB5_PROTOTYPE134s/KRB5_PROTOTYPE//;135s/KRB5_STDARG_P//;136# here, is probably function decl137# strip simple arg list - parens, no parens inside; discard, iterate.138# the iteration should deal with function pointer args.139$vararg = /\.\.\./;140Striparg:141if (/ *\([^\(\)]*\)/) {142s/ *\([^\(\)]*\)//g;143goto Striparg;144}145# Also strip out attributes, or what's left over of them.146if (/__attribute__/) {147s/[ \t]*__attribute__[ \t]*//g;148goto Striparg;149}150# replace return type etc with one token indicating calling convention151if (/CALLCONV/) {152if (/\bKRB5_CALLCONV_WRONG\b/) {153s/^.*KRB5_CALLCONV_WRONG *//;154die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);155push @convW, $_;156push @vararg, $_ if $vararg;157} elsif (/\bKRB5_CALLCONV_C\b/) {158s/^.*KRB5_CALLCONV_C *//;159die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);160push @convC, $_;161push @vararg, $_ if $vararg;162} elsif (/\bKRB5_CALLCONV\b/) {163s/^.*KRB5_CALLCONV *//;164die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);165push @convK, $_;166push @vararg, $_ if $vararg;167} else {168die "Unrecognized calling convention while parsing: '$_'\n";169}170goto Hadcallc;171}172# deal with no CALLCONV indicator173s/^.* \**(\w+) *$/$1/;174die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);175push @convD, $_;176push @vararg, $_ if $vararg;177Hadcallc:178goto Skipnotf;179Notfunct:180# probably a variable181s/^/VARIABLE_DECL /;182Skipnotf:183# toss blank lines184if (/^[ \t]*$/) {185next LINE;186}187}188189if ( $verbose ) {190print join("\n\t", "Using default calling convention:", sort(@convD));191print join("\n\t", "\nUsing KRB5_CALLCONV:", sort(@convK));192print join("\n\t", "\nUsing KRB5_CALLCONV_C:", sort(@convC));193print join("\n\t", "\nUsing KRB5_CALLCONV_WRONG:", sort(@convW));194print "\n","-"x70,"\n";195}196197%conv = ();198map { $conv{$_} = "default"; } @convD;199map { $conv{$_} = "KRB5_CALLCONV"; } @convK;200map { $conv{$_} = "KRB5_CALLCONV_C"; } @convC;201map { $conv{$_} = "KRB5_CALLCONV_WRONG"; } @convW;202203my %vararg = ();204map { $vararg{$_} = 1; } @vararg;205206if (!$d) {207print "No .DEF file specified\n" if $verbose;208exit 0;209}210211LINE2:212while (! $d->eof()) {213$_ = $d->getline();214s/[\r\n]+$//;215#216if (/^;/) {217$printit = 0;218next LINE2;219}220if (/^[ \t]*$/) {221$printit = 0;222next LINE2;223}224if (/^EXPORTS/ || /^DESCRIPTION/ || /^HEAPSIZE/) {225$printit = 0;226next LINE2;227}228s/[ \t]*//g;229s/@[0-9]+//;230my($xconv);231if (/PRIVATE/ || /INTERNAL/) {232$xconv = "PRIVATE";233} elsif (/DATA/) {234$xconv = "DATA";235} elsif (/!CALLCONV/ || /KRB5_CALLCONV_WRONG/) {236$xconv = "KRB5_CALLCONV_WRONG";237} elsif ($vararg{$_}) {238$xconv = "KRB5_CALLCONV_C";239} else {240$xconv = "KRB5_CALLCONV";241}242s/;.*$//;243244if ($xconv eq "PRIVATE") {245print "\t private $_\n" if $verbose;246next LINE2;247}248if ($xconv eq "DATA") {249print "\t data $_\n" if $verbose;250next LINE2;251}252if (!defined($conv{$_})) {253print "No calling convention specified for $_!\n";254$error = 1;255} elsif (! ($conv{$_} eq $xconv)) {256print "Function $_ should have calling convention '$xconv', but has '$conv{$_}' instead.\n";257$error = 1;258} else {259# print "Function $_ is okay.\n";260}261}262263#print "Calling conventions defined for: ", keys(%conv);264exit $error;265266267