1 #!/usr/athena/bin/perl -w
3 # Code initially generated by s2p
4 # Code modified to use strict and IO::File
6 eval 'exec /usr/athena/bin/perl -S $0 ${1+"$@"}'
7 if 0; # line above evaluated when running under some shell (i.e., not perl)
14 if ( $ARGV[0] eq "-v" ) { $verbose = 1; shift @ARGV; }
15 my $h_filename = shift @ARGV || die "usage: $0 [-v] header-file [def-file]\n";
16 my $d_filename = shift @ARGV;
18 my $h = open_always($h_filename);
19 my $d = open_always($d_filename) if $d_filename;
23 my $file = shift || die;
24 my $handle = new IO::File "<$file";
25 die "Could not open $file\n" if !$handle;
44 # get calling convention info for function decls
45 # what about function pointer typedefs?
46 # need to verify unhandled syntax actually triggers a report, not ignored
52 # drop KRB5INT_BEGIN_DECLS and KRB5INT_END_DECLS
53 if (/^ *(KRB5INT|GSSAPI[A-Z]*)_(BEGIN|END)_DECLS/) {
56 # drop preprocessor directives
58 while (/\\$/) { $_ .= $h->getline(); }
77 # multi-line comments?
82 chop if $len1 < length;
83 goto Cloop1 if /\/\*./;
89 if (/^ *extern "C" \{/) {
92 s/KRB5_ATTR_DEPRECATED//;
93 # elide struct definitions
104 chop if $len1 < length;
112 chop if $len1 < length;
118 if (/^typedef[^;]*;/) {
122 if (/^struct[^\(\)]*;/) {
123 s/^struct[^\(\)]*;//g;
126 # should just have simple decls now; split lines at semicolons
133 goto Notfunct unless /\(.*\)/;
134 # Get rid of KRB5_PROTOTYPE
137 # here, is probably function decl
138 # strip simple arg list - parens, no parens inside; discard, iterate.
139 # the iteration should deal with function pointer args.
142 if (/ *\([^\(\)]*\)/) {
146 # Also strip out attributes, or what's left over of them.
147 if (/__attribute__/) {
148 s/[ \t]*__attribute__[ \t]*//g;
151 # replace return type etc with one token indicating calling convention
153 if (/\bKRB5_CALLCONV_WRONG\b/) {
154 s/^.*KRB5_CALLCONV_WRONG *//;
155 die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
157 push @vararg, $_ if $vararg;
158 } elsif (/\bKRB5_CALLCONV_C\b/) {
159 s/^.*KRB5_CALLCONV_C *//;
160 die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
162 push @vararg, $_ if $vararg;
163 } elsif (/\bKRB5_CALLCONV\b/) {
164 s/^.*KRB5_CALLCONV *//;
165 die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
167 push @vararg, $_ if $vararg;
169 die "Unrecognized calling convention while parsing: '$_'\n";
173 # deal with no CALLCONV indicator
174 s/^.* \**(\w+) *$/$1/;
175 die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
177 push @vararg, $_ if $vararg;
181 # probably a variable
191 print join("\n\t", "Using default calling convention:", sort(@convD));
192 print join("\n\t", "\nUsing KRB5_CALLCONV:", sort(@convK));
193 print join("\n\t", "\nUsing KRB5_CALLCONV_C:", sort(@convC));
194 print join("\n\t", "\nUsing KRB5_CALLCONV_WRONG:", sort(@convW));
195 print "\n","-"x70,"\n";
199 map { $conv{$_} = "default"; } @convD;
200 map { $conv{$_} = "KRB5_CALLCONV"; } @convK;
201 map { $conv{$_} = "KRB5_CALLCONV_C"; } @convC;
202 map { $conv{$_} = "KRB5_CALLCONV_WRONG"; } @convW;
205 map { $vararg{$_} = 1; } @vararg;
208 print "No .DEF file specified\n" if $verbose;
213 while (! $d->eof()) {
225 if (/^EXPORTS/ || /^DESCRIPTION/ || /^HEAPSIZE/) {
232 if (/PRIVATE/ || /INTERNAL/) {
236 } elsif (/!CALLCONV/ || /KRB5_CALLCONV_WRONG/) {
237 $xconv = "KRB5_CALLCONV_WRONG";
238 } elsif ($vararg{$_}) {
239 $xconv = "KRB5_CALLCONV_C";
241 $xconv = "KRB5_CALLCONV";
245 if ($xconv eq "PRIVATE") {
246 print "\t private $_\n" if $verbose;
249 if ($xconv eq "DATA") {
250 print "\t data $_\n" if $verbose;
253 if (!defined($conv{$_})) {
254 print "No calling convention specified for $_!\n";
256 } elsif (! ($conv{$_} eq $xconv)) {
257 print "Function $_ should have calling convention '$xconv', but has '$conv{$_}' instead.\n";
260 # print "Function $_ is okay.\n";
264 #print "Calling conventions defined for: ", keys(%conv);