|
Packit |
fd8b60 |
#!/usr/athena/bin/perl -w
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Code initially generated by s2p
|
|
Packit |
fd8b60 |
# Code modified to use strict and IO::File
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
eval 'exec /usr/athena/bin/perl -S $0 ${1+"$@"}'
|
|
Packit |
fd8b60 |
if 0; # line above evaluated when running under some shell (i.e., not perl)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
use strict;
|
|
Packit |
fd8b60 |
use IO::File;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
my $verbose = 0;
|
|
Packit |
fd8b60 |
my $error = 0;
|
|
Packit |
fd8b60 |
if ( $ARGV[0] eq "-v" ) { $verbose = 1; shift @ARGV; }
|
|
Packit |
fd8b60 |
my $h_filename = shift @ARGV || die "usage: $0 [-v] header-file [def-file]\n";
|
|
Packit |
fd8b60 |
my $d_filename = shift @ARGV;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
my $h = open_always($h_filename);
|
|
Packit |
fd8b60 |
my $d = open_always($d_filename) if $d_filename;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
sub open_always
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
my $file = shift || die;
|
|
Packit |
fd8b60 |
my $handle = new IO::File "<$file";
|
|
Packit |
fd8b60 |
die "Could not open $file\n" if !$handle;
|
|
Packit |
fd8b60 |
return $handle;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
my @convW = ();
|
|
Packit |
fd8b60 |
my @convC = ();
|
|
Packit |
fd8b60 |
my @convK = ();
|
|
Packit |
fd8b60 |
my @convD = ();
|
|
Packit |
fd8b60 |
my @vararg = ();
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
my $len1;
|
|
Packit |
fd8b60 |
my %conv;
|
|
Packit |
fd8b60 |
my $printit;
|
|
Packit |
fd8b60 |
my $vararg;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
LINE:
|
|
Packit |
fd8b60 |
while (! $h->eof()) {
|
|
Packit |
fd8b60 |
$_ = $h->getline();
|
|
Packit |
fd8b60 |
chop;
|
|
Packit |
fd8b60 |
# get calling convention info for function decls
|
|
Packit |
fd8b60 |
# what about function pointer typedefs?
|
|
Packit |
fd8b60 |
# need to verify unhandled syntax actually triggers a report, not ignored
|
|
Packit |
fd8b60 |
# blank lines
|
|
Packit |
fd8b60 |
if (/^[ \t]*$/) {
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
Top:
|
|
Packit |
fd8b60 |
# drop KRB5INT_BEGIN_DECLS and KRB5INT_END_DECLS
|
|
Packit |
fd8b60 |
if (/^ *(KRB5INT|GSSAPI[A-Z]*)_(BEGIN|END)_DECLS/) {
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# drop preprocessor directives
|
|
Packit |
fd8b60 |
if (/^ *#/) {
|
|
Packit |
fd8b60 |
while (/\\$/) { $_ .= $h->getline(); }
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (/^ *\?==/) {
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
s/#.*$//;
|
|
Packit |
fd8b60 |
if (/^\} *$/) {
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# strip comments
|
|
Packit |
fd8b60 |
Cloop1:
|
|
Packit |
fd8b60 |
if (/\/\*./) {
|
|
Packit |
fd8b60 |
s;/\*[^*]*;/*;;
|
|
Packit |
fd8b60 |
s;/\*\*([^/]);/*$1;;
|
|
Packit |
fd8b60 |
s;/\*\*$;/*;;
|
|
Packit |
fd8b60 |
s;/\*\*/; ;g;
|
|
Packit |
fd8b60 |
goto Cloop1;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# multi-line comments?
|
|
Packit |
fd8b60 |
if (/\/\*$/) {
|
|
Packit |
fd8b60 |
$_ .= " ";
|
|
Packit |
fd8b60 |
$len1 = length;
|
|
Packit |
fd8b60 |
$_ .= $h->getline();
|
|
Packit |
fd8b60 |
chop if $len1 < length;
|
|
Packit |
fd8b60 |
goto Cloop1 if /\/\*./;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# blank lines
|
|
Packit |
fd8b60 |
if (/^[ \t]*$/) {
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (/^ *extern "C" \{/) {
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
s/KRB5_ATTR_DEPRECATED//;
|
|
Packit |
fd8b60 |
# elide struct definitions
|
|
Packit |
fd8b60 |
Struct1:
|
|
Packit |
fd8b60 |
if (/\{[^}]*\}/) {
|
|
Packit |
fd8b60 |
s/\{[^}]*\}/ /g;
|
|
Packit |
fd8b60 |
goto Struct1;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# multi-line defs
|
|
Packit |
fd8b60 |
if (/\{/) {
|
|
Packit |
fd8b60 |
$_ .= "\n";
|
|
Packit |
fd8b60 |
$len1 = length;
|
|
Packit |
fd8b60 |
$_ .= $h->getline();
|
|
Packit |
fd8b60 |
chop if $len1 < length;
|
|
Packit |
fd8b60 |
goto Struct1;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
Semi:
|
|
Packit |
fd8b60 |
unless (/;/) {
|
|
Packit |
fd8b60 |
$_ .= "\n";
|
|
Packit |
fd8b60 |
$len1 = length;
|
|
Packit |
fd8b60 |
$_ .= $h->getline();
|
|
Packit |
fd8b60 |
chop if $len1 < length;
|
|
Packit |
fd8b60 |
s/\n/ /g;
|
|
Packit |
fd8b60 |
s/[ \t]+/ /g;
|
|
Packit |
fd8b60 |
s/^[ \t]*//;
|
|
Packit |
fd8b60 |
goto Top;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (/^typedef[^;]*;/) {
|
|
Packit |
fd8b60 |
s/^typedef[^;]*;//g;
|
|
Packit |
fd8b60 |
goto Semi;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (/^struct[^\(\)]*;/) {
|
|
Packit |
fd8b60 |
s/^struct[^\(\)]*;//g;
|
|
Packit |
fd8b60 |
goto Semi;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# should just have simple decls now; split lines at semicolons
|
|
Packit |
fd8b60 |
s/ *;[ \t]*$//;
|
|
Packit |
fd8b60 |
s/ *;/\n/g;
|
|
Packit |
fd8b60 |
if (/^[ \t]*$/) {
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
s/[ \t]*$//;
|
|
Packit |
fd8b60 |
goto Notfunct unless /\(.*\)/;
|
|
Packit |
fd8b60 |
# Get rid of KRB5_PROTOTYPE
|
|
Packit |
fd8b60 |
s/KRB5_PROTOTYPE//;
|
|
Packit |
fd8b60 |
s/KRB5_STDARG_P//;
|
|
Packit |
fd8b60 |
# here, is probably function decl
|
|
Packit |
fd8b60 |
# strip simple arg list - parens, no parens inside; discard, iterate.
|
|
Packit |
fd8b60 |
# the iteration should deal with function pointer args.
|
|
Packit |
fd8b60 |
$vararg = /\.\.\./;
|
|
Packit |
fd8b60 |
Striparg:
|
|
Packit |
fd8b60 |
if (/ *\([^\(\)]*\)/) {
|
|
Packit |
fd8b60 |
s/ *\([^\(\)]*\)//g;
|
|
Packit |
fd8b60 |
goto Striparg;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# Also strip out attributes, or what's left over of them.
|
|
Packit |
fd8b60 |
if (/__attribute__/) {
|
|
Packit |
fd8b60 |
s/[ \t]*__attribute__[ \t]*//g;
|
|
Packit |
fd8b60 |
goto Striparg;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# replace return type etc with one token indicating calling convention
|
|
Packit |
fd8b60 |
if (/CALLCONV/) {
|
|
Packit |
fd8b60 |
if (/\bKRB5_CALLCONV_WRONG\b/) {
|
|
Packit |
fd8b60 |
s/^.*KRB5_CALLCONV_WRONG *//;
|
|
Packit |
fd8b60 |
die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
|
|
Packit |
fd8b60 |
push @convW, $_;
|
|
Packit |
fd8b60 |
push @vararg, $_ if $vararg;
|
|
Packit |
fd8b60 |
} elsif (/\bKRB5_CALLCONV_C\b/) {
|
|
Packit |
fd8b60 |
s/^.*KRB5_CALLCONV_C *//;
|
|
Packit |
fd8b60 |
die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
|
|
Packit |
fd8b60 |
push @convC, $_;
|
|
Packit |
fd8b60 |
push @vararg, $_ if $vararg;
|
|
Packit |
fd8b60 |
} elsif (/\bKRB5_CALLCONV\b/) {
|
|
Packit |
fd8b60 |
s/^.*KRB5_CALLCONV *//;
|
|
Packit |
fd8b60 |
die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
|
|
Packit |
fd8b60 |
push @convK, $_;
|
|
Packit |
fd8b60 |
push @vararg, $_ if $vararg;
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
die "Unrecognized calling convention while parsing: '$_'\n";
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
goto Hadcallc;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
# deal with no CALLCONV indicator
|
|
Packit |
fd8b60 |
s/^.* \**(\w+) *$/$1/;
|
|
Packit |
fd8b60 |
die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
|
|
Packit |
fd8b60 |
push @convD, $_;
|
|
Packit |
fd8b60 |
push @vararg, $_ if $vararg;
|
|
Packit |
fd8b60 |
Hadcallc:
|
|
Packit |
fd8b60 |
goto Skipnotf;
|
|
Packit |
fd8b60 |
Notfunct:
|
|
Packit |
fd8b60 |
# probably a variable
|
|
Packit |
fd8b60 |
s/^/VARIABLE_DECL /;
|
|
Packit |
fd8b60 |
Skipnotf:
|
|
Packit |
fd8b60 |
# toss blank lines
|
|
Packit |
fd8b60 |
if (/^[ \t]*$/) {
|
|
Packit |
fd8b60 |
next LINE;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if ( $verbose ) {
|
|
Packit |
fd8b60 |
print join("\n\t", "Using default calling convention:", sort(@convD));
|
|
Packit |
fd8b60 |
print join("\n\t", "\nUsing KRB5_CALLCONV:", sort(@convK));
|
|
Packit |
fd8b60 |
print join("\n\t", "\nUsing KRB5_CALLCONV_C:", sort(@convC));
|
|
Packit |
fd8b60 |
print join("\n\t", "\nUsing KRB5_CALLCONV_WRONG:", sort(@convW));
|
|
Packit |
fd8b60 |
print "\n","-"x70,"\n";
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
%conv = ();
|
|
Packit |
fd8b60 |
map { $conv{$_} = "default"; } @convD;
|
|
Packit |
fd8b60 |
map { $conv{$_} = "KRB5_CALLCONV"; } @convK;
|
|
Packit |
fd8b60 |
map { $conv{$_} = "KRB5_CALLCONV_C"; } @convC;
|
|
Packit |
fd8b60 |
map { $conv{$_} = "KRB5_CALLCONV_WRONG"; } @convW;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
my %vararg = ();
|
|
Packit |
fd8b60 |
map { $vararg{$_} = 1; } @vararg;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (!$d) {
|
|
Packit |
fd8b60 |
print "No .DEF file specified\n" if $verbose;
|
|
Packit |
fd8b60 |
exit 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
LINE2:
|
|
Packit |
fd8b60 |
while (! $d->eof()) {
|
|
Packit |
fd8b60 |
$_ = $d->getline();
|
|
Packit |
fd8b60 |
chop;
|
|
Packit |
fd8b60 |
#
|
|
Packit |
fd8b60 |
if (/^;/) {
|
|
Packit |
fd8b60 |
$printit = 0;
|
|
Packit |
fd8b60 |
next LINE2;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (/^[ \t]*$/) {
|
|
Packit |
fd8b60 |
$printit = 0;
|
|
Packit |
fd8b60 |
next LINE2;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (/^EXPORTS/ || /^DESCRIPTION/ || /^HEAPSIZE/) {
|
|
Packit |
fd8b60 |
$printit = 0;
|
|
Packit |
fd8b60 |
next LINE2;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
s/[ \t]*//g;
|
|
Packit |
fd8b60 |
s/@[0-9]+//;
|
|
Packit |
fd8b60 |
my($xconv);
|
|
Packit |
fd8b60 |
if (/PRIVATE/ || /INTERNAL/) {
|
|
Packit |
fd8b60 |
$xconv = "PRIVATE";
|
|
Packit |
fd8b60 |
} elsif (/DATA/) {
|
|
Packit |
fd8b60 |
$xconv = "DATA";
|
|
Packit |
fd8b60 |
} elsif (/!CALLCONV/ || /KRB5_CALLCONV_WRONG/) {
|
|
Packit |
fd8b60 |
$xconv = "KRB5_CALLCONV_WRONG";
|
|
Packit |
fd8b60 |
} elsif ($vararg{$_}) {
|
|
Packit |
fd8b60 |
$xconv = "KRB5_CALLCONV_C";
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
$xconv = "KRB5_CALLCONV";
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
s/;.*$//;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if ($xconv eq "PRIVATE") {
|
|
Packit |
fd8b60 |
print "\t private $_\n" if $verbose;
|
|
Packit |
fd8b60 |
next LINE2;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if ($xconv eq "DATA") {
|
|
Packit |
fd8b60 |
print "\t data $_\n" if $verbose;
|
|
Packit |
fd8b60 |
next LINE2;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (!defined($conv{$_})) {
|
|
Packit |
fd8b60 |
print "No calling convention specified for $_!\n";
|
|
Packit |
fd8b60 |
$error = 1;
|
|
Packit |
fd8b60 |
} elsif (! ($conv{$_} eq $xconv)) {
|
|
Packit |
fd8b60 |
print "Function $_ should have calling convention '$xconv', but has '$conv{$_}' instead.\n";
|
|
Packit |
fd8b60 |
$error = 1;
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
# print "Function $_ is okay.\n";
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#print "Calling conventions defined for: ", keys(%conv);
|
|
Packit |
fd8b60 |
exit $error;
|