diff options
Diffstat (limited to 'fips/tools/api_fns.pm')
-rw-r--r-- | fips/tools/api_fns.pm | 336 |
1 files changed, 0 insertions, 336 deletions
diff --git a/fips/tools/api_fns.pm b/fips/tools/api_fns.pm deleted file mode 100644 index d668be12ba..0000000000 --- a/fips/tools/api_fns.pm +++ /dev/null @@ -1,336 +0,0 @@ -package api_data; -use strict; - -use Data::Dumper; -use File::Slurp; - -# The basic data store for a declaration is a hash holding the following -# information (let's simply call this structure "declaration"): -# sym => string (the symbol of the declaration) -# symcomment=> string (if there's a comment about this symbol) or undef -# type => string (type definition text, with a '?' where the symbol should be -# kind => 0 (variable) -# 1 (function) -# params => list reference (list of declarations, one for each parameter) -# [only exists when kind = 1] -# direction => 0 (input) -# 1 (output) -# 2 (input and output) -# 3 (output or input and output) -# +4 (guess) -# [only exists when this symbol is a parameter to a function] - -# Constructor -sub new { - my $class = shift; - my $self = {}; - $self->{DECLARATIONS} = {}; - bless($self, $class); - return $self; -} - -sub read_declaration_db { - my $self = shift; - my $declaration_file = shift; - my $buf = read_file($declaration_file); - $self->{DECLARATIONS} = eval $buf; - die $@ if $@; -} - -sub write_declaration_db { - my $self = shift; - my $declaration_file = shift; - - $Data::Dumper::Purity = 1; - open FILE,">".$declaration_file || - die "Can't open '$declaration_file': $!\n"; - print FILE "my ",Data::Dumper->Dump([ $self->{DECLARATIONS} ], [qw(declaration_db)]); - close FILE; -} - -sub insert_declaration { - my $self = shift; - my %decl = @_; - my $sym = $decl{sym}; - - if ($self->{DECLARATIONS}->{$sym}) { - foreach my $k (('sym', 'symcomment','oldsym','objfile','kind')) { - $self->{DECLARATIONS}->{$sym}->{$k} = $decl{$k}; - } - if ($self->{DECLARATIONS}->{$sym}->{kind} == 1) { - # Replace parameters only if the kind or type has changed - my $oldp = $self->{DECLARATIONS}->{$sym}->{params}; - my $newp = $decl{params}; - my $l = scalar(@{$oldp}); - for my $pn (0..($l - 1)) { - if ($oldp->[$pn]->{kind} != $newp->[$pn]->{kind} - || $oldp->[$pn]->{type} ne $newp->[$pn]->{type}) { - $self->{DECLARATIONS}->{$sym}->{params} = $newp; - } - } - } - } else { - $self->{DECLARATIONS}->{$decl{sym}} = { %decl }; - } -} - -# Input is a simple C declaration, output is a declaration structure -sub _parse_declaration { - my $decl = shift; - my $newname = shift; - my $objfile = shift; - my $namecomment = shift; - my %parsed_decl = (); - - my $debug = 0; - - print "DEBUG: going to parse: $decl\n" if $debug; - - # Start with changing all parens to { and } except the outermost - # Within these, convert all commas to semi-colons - my $s = ""; - do { - print "DEBUG: decl: $decl\n" if $debug; - $s = $decl; - if ($decl =~ m/ - \( - ([^\(\)]*) - \( - ([^\(\)]*) - \) - /x) { - print "DEBUG: \`: $`\n" if $debug; - print "DEBUG: 1: $1\n" if $debug; - print "DEBUG: 2: $2\n" if $debug; - print "DEBUG: \': $'\n" if $debug; - - my $a = "$`"."("."$1"; - my $b = "{"."$2"."}"; - my $c = "$'"; - print "DEBUG: a: $a\n" if $debug; - print "DEBUG: b: $b\n" if $debug; - print "DEBUG: c: $c\n" if $debug; - $b =~ s/,/;/g; - print "DEBUG: b: $b\n" if $debug; - - $decl = $a.$b.$c; - } - } while ($s ne $decl); - - # There are types that we look for. The first is the function pointer - # T (*X)(...) - if ($decl =~ m/ - ^\s* - ([^\(]+) # Return type of the function pointed at - \( - \s*\*\s* - ([^\)]*) # Function returning or variable holding fn ptr - \) - \s* - \( - ([^\)]*) # Parameter for the function pointed at - \) - \s*$ - /x) { - print "DEBUG: function pointer variable or function\n" if $debug; - print "DEBUG: 1: $1\n" if $debug; - print "DEBUG: 2: $2\n" if $debug; - print "DEBUG: 3: $3\n" if $debug; - - my $tmp1 = $1 . "(*?)" . "(" . $3 . ")"; - my $tmp2 = $2; - - $tmp1 =~ tr/\{\}\;/(),/; # Convert all braces and semi-colons - # back to parens and commas - - $tmp2 =~ tr/\{\}\;/(),/; # Convert all braces and semi-colons - # back to parens and commas - - # Parse the symbol part with a fake type. This will determine if - # it's a variable or a function. - my $subdeclaration = _parse_declaration("int " . $tmp2, $newname); - map { $parsed_decl{$_} = $subdeclaration->{$_} } ( "sym", - "kind", - "params" ); - $parsed_decl{symcomment} = $namecomment if $namecomment; - $parsed_decl{type} = $tmp1; - } - # If that wasn't it, check for the simple function declaration - # T X(...) - elsif ($decl =~ m/^\s*(.*?\W)(\w+)\s*\(\s*(.*)\s*\)\s*$/) { - print "DEBUG: function\n" if $debug; - print "DEBUG: 1: $1\n" if $debug; - print "DEBUG: 2: $2\n" if $debug; - print "DEBUG: 3: $3\n" if $debug; - - $parsed_decl{kind} = 1; - $parsed_decl{type} = $1."?"; - $parsed_decl{sym} = $newname ? $newname : $2; - $parsed_decl{symcomment} = $namecomment if $namecomment; - $parsed_decl{oldsym} = $newname ? $2 : undef; - $parsed_decl{params} = [ - map { tr/\{\}\;/(),/; _parse_declaration($_,undef,undef,undef) } - grep { !/^\s*void\s*$/ } - split(/\s*,\s*/, $3) - ]; - } - # If that wasn't it either, try to get a variable - # T X or T X[...] - elsif ($decl =~ m/^\s*(.*\W)(\w+)(\s*\[.*\])?\s*$/) { - print "DEBUG: variable\n" if $debug; - print "DEBUG: 1: $1\n" if $debug; - print "DEBUG: 2: $2\n" if $debug; - - $parsed_decl{kind} = 0; - $parsed_decl{type} = $1."?"; - $parsed_decl{sym} = $newname ? $newname : $2; - $parsed_decl{symcomment} = $namecomment if $namecomment; - $parsed_decl{oldsym} = $newname ? $2 : undef; - } - # Special for the parameter "..." - elsif ($decl =~ m/^\s*\.\.\.\s*$/) { - %parsed_decl = ( kind => 0, type => "?", sym => "..." ); - } - # Otherwise, we got something weird - else { - print "Warning: weird declaration: $decl\n"; - %parsed_decl = ( kind => -1, decl => $decl ); - } - $parsed_decl{objfile} = $objfile; - - print Dumper({ %parsed_decl }) if $debug; - return { %parsed_decl }; -} - -sub add_declaration { - my $self = shift; - my $parsed = _parse_declaration(@_); - $self->insert_declaration( %{$parsed} ); -} - -sub complete_directions { - my $self = shift; - foreach my $sym (keys %{$self->{DECLARATIONS}}) { - if ($self->{DECLARATIONS}->{$sym}->{kind} == 1) { - map { - if (!$_->{direction} || $_->{direction} =~ m/\?/) { - if ($_->{type} =~ m/const/) { - $_->{direction} = '->'; # Input - } elsif ($_->{sym} =~ m/ctx/ || $_->{type} =~ m/ctx/i) { - $_->{direction} = '<-?'; # Guess output - } elsif ($_->{type} =~ m/\*/) { - if ($_->{type} =~ m/(short|int|char|size_t)/) { - $_->{direction} = '<-?'; # Guess output - } else { - $_->{direction} = '<-? <->?'; # Guess output or input/output - } - } else { - $_->{direction} = '->'; # Input - } - } - } @{$self->{DECLARATIONS}->{$sym}->{params}}; - } - } -} - -sub on_all_declarations { - my $self = shift; - my $fn = shift; - foreach my $sym (sort keys %{$self->{DECLARATIONS}}) { - &$fn($self->{DECLARATIONS}->{$sym}); - } -} - -sub get_function_declaration_strings_from_file { - my $fn = shift; - my %declarations = (); - my $line = ""; - my $cppline = ""; - - my $debug = 0; - - foreach my $headerline (`cat $fn`) { - chomp $headerline; - print STDERR "DEBUG0: $headerline\n" if $debug; - # First, treat the line at a CPP level; remove comments, add on more - # lines if there's an ending backslash or an incomplete comment. - # If none of that is true, then remove all comments and check if the - # line starts with a #, skip if it does, otherwise continue. - if ($cppline && $headerline) { $cppline .= " "; } - $cppline .= $headerline; - $cppline =~ s^\"(.|\\\")*\"^@@^g; # Collapse strings - $cppline =~ s^/\*.*?\*/^^g; # Remove all complete comments - print STDERR "DEBUG1: $cppline\n" if $debug; - if ($cppline =~ m/\\$/) { # Keep on reading if the current line ends - # with a backslash - $cppline = $`; - next; - } - next if $cppline =~ m/\/\*/; # Keep on reading if there remains the - # start of a comment - next if $cppline =~ m/"/; # Keep on reading if there remains the - # start of a string - if ($cppline =~ m/^\#/) { - $cppline = ""; - next; - } - - # Done with the preprocessor part, add the resulting line to the - # line we're putting together to get a statement. - if ($line && $cppline) { $line .= " "; } - $line .= $cppline; - $cppline = ""; - $line =~ s%extern\s+\@\@\s+\{%%g; # Remove 'extern "C" {' - $line =~ s%\{[^\{\}]*\}%\$\$%g; # Collapse any compound structure - print STDERR "DEBUG2: $line\n" if $debug; - next if $line =~ m%\{%; # If there is any compound structure start, - # we are not quite done reading. - $line =~ s%\}%%; # Remove a lonely }, it's probably a rest - # from 'extern "C" {' - $line =~ s%^\s+%%; # Remove beginning blanks - $line =~ s%\s+$%%; # Remove trailing blanks - $line =~ s%\s+% %g; # Collapse multiple blanks to one. - if ($line =~ m/;/) { - print STDERR "DEBUG3: $`\n" if $debug; - my $decl = $`; #`; # (emacs is stupid that way) - $line = $'; #'; # (emacs is stupid that way) - - # Find the symbol by taking the declaration and fiddling with it: - # (remember, we're just extracting the symbol, so we're allowed - # to cheat here ;-)) - # 1. Remove all paired parenthesies, innermost first. While doing - # this, if something like "(* foo)(" is found, this is a - # function pointer; change it to "foo(" - # 2. Remove all paired square parenthesies. - # 3. Remove any $$ with surrounding spaces. - # 4. Pick the last word, that's the symbol. - my $tmp; - my $sym = $decl; - print STDERR "DEBUG3.1: $sym\n" if $debug; - do { - $tmp = $sym; - # NOTE: The order of these two is important, and it's also - # important not to use the g modifier. - $sym =~ s/\(\s*\*\s*(\w+)\s*\)\s*\(/$1(/; - $sym =~ s/\([^\(\)]*\)//; - print STDERR "DEBUG3.2: $sym\n" if $debug; - } while ($tmp ne $sym); - do { - $tmp = $sym; - $sym =~ s/\[[^\[\]]*\]//g; - } while ($tmp ne $sym); - $sym =~ s/\s*\$\$\s*//g; - $sym =~ s/.*[\s\*](\w+)\s*$/$1/; - print STDERR "DEBUG4: $sym\n" if $debug; - if ($sym =~ m/\W/) { - print STDERR "Warning[$fn]: didn't find proper symbol in declaration:\n"; - print STDERR " decl: $decl\n"; - print STDERR " sym: $sym\n"; - } - $declarations{$sym} = $decl; - } - } - return %declarations; -} - -1; |