Commit 659fcd81 authored by Patrik Stridvall's avatar Patrik Stridvall Committed by Alexandre Julliard

- Minor fixes and reorganizations.

- Added checks for documentation inconsistencies.
parent 2c92835f
...@@ -8,14 +8,19 @@ sub new { ...@@ -8,14 +8,19 @@ sub new {
my $self = {}; my $self = {};
bless ($self, $class); bless ($self, $class);
my $output = \${$self->{OUTPUT}};
my $functions = \%{$self->{FUNCTIONS}}; my $functions = \%{$self->{FUNCTIONS}};
my $conditionals = \%{$self->{CONDITIONALS}}; my $conditionals = \%{$self->{CONDITIONALS}};
my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}}; my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
my $conditional_functions = \%{$self->{CONDITIONAL_FUNCTIONS}};
$$output = shift;
my $api_file = shift; my $api_file = shift;
my $configure_in_file = shift; my $configure_in_file = shift;
my $config_h_in_file = shift; my $config_h_in_file = shift;
$$output->progress("$api_file");
open(IN, "< $api_file"); open(IN, "< $api_file");
$/ = "\n"; $/ = "\n";
while(<IN>) { while(<IN>) {
...@@ -27,8 +32,10 @@ sub new { ...@@ -27,8 +32,10 @@ sub new {
} }
close(IN); close(IN);
$$output->progress("$configure_in_file");
my $again = 0; my $again = 0;
open(IN, "< $configure_in_file"); open(IN, "< $configure_in_file");
local $/ = "\n"; local $/ = "\n";
while($again || (defined($_ = <IN>))) { while($again || (defined($_ = <IN>))) {
$again = 0; $again = 0;
...@@ -46,8 +53,13 @@ sub new { ...@@ -46,8 +53,13 @@ sub new {
if(/^AC_CHECK_HEADERS\(\s*(.*?)\)\s*$/) { if(/^AC_CHECK_HEADERS\(\s*(.*?)\)\s*$/) {
my @arguments = split(/,/,$1); my @arguments = split(/,/,$1);
foreach my $header (split(/\s+/, $arguments[0])) { foreach my $name (split(/\s+/, $arguments[0])) {
$$conditional_headers{$header}++; $$conditional_headers{$name}++;
}
} elsif(/^AC_CHECK_FUNCS\(\s*(.*?)\)\s*$/) {
my @arguments = split(/,/,$1);
foreach my $name (split(/\s+/, $arguments[0])) {
$$conditional_functions{$name}++;
} }
} elsif(/^AC_FUNC_ALLOCA/) { } elsif(/^AC_FUNC_ALLOCA/) {
$$conditional_headers{"alloca.h"}++; $$conditional_headers{"alloca.h"}++;
...@@ -56,10 +68,12 @@ sub new { ...@@ -56,10 +68,12 @@ sub new {
} }
close(IN); close(IN);
$$output->progress("$config_h_in_file");
open(IN, "< $config_h_in_file"); open(IN, "< $config_h_in_file");
local $/ = "\n"; local $/ = "\n";
while(<IN>) { while(<IN>) {
if(/^\#undef (\S+)$/) { if(/^\#undef\s+(\S+)$/) {
$$conditionals{$1}++; $$conditionals{$1}++;
} }
} }
...@@ -95,4 +109,13 @@ sub is_conditional_header { ...@@ -95,4 +109,13 @@ sub is_conditional_header {
return $$conditional_headers{$name}; return $$conditional_headers{$name};
} }
sub is_conditional_function {
my $self = shift;
my $conditional_functions = \%{$self->{CONDITIONAL_FUNCTIONS}};
my $name = shift;
return $$conditional_functions{$name};
}
1; 1;
...@@ -70,12 +70,12 @@ sub parse_api_file { ...@@ -70,12 +70,12 @@ sub parse_api_file {
if(!$forbidden) { if(!$forbidden) {
if(defined($module)) { if(defined($module)) {
if($$allowed_modules_unlimited{$type}) { if($$allowed_modules_unlimited{$type}) {
print "$file: type ($type) already specificed as an unlimited type\n"; $$output->write("$file: type ($type) already specificed as an unlimited type\n");
} elsif(!$$allowed_modules{$type}{$module}) { } elsif(!$$allowed_modules{$type}{$module}) {
$$allowed_modules{$type}{$module} = 1; $$allowed_modules{$type}{$module} = 1;
$$allowed_modules_limited{$type} = 1; $$allowed_modules_limited{$type} = 1;
} else { } else {
print "$file: type ($type) already specificed\n"; $$output->write("$file: type ($type) already specificed\n");
} }
} else { } else {
$$allowed_modules_unlimited{$type} = 1; $$allowed_modules_unlimited{$type} = 1;
...@@ -84,12 +84,12 @@ sub parse_api_file { ...@@ -84,12 +84,12 @@ sub parse_api_file {
$$allowed_modules_limited{$type} = 1; $$allowed_modules_limited{$type} = 1;
} }
if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) { if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
print "$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n"; $$output->write("$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n");
} else { } else {
$$translate_argument{$type} = $kind; $$translate_argument{$type} = $kind;
} }
} else { } else {
print "$file: file must begin with %<type> statement\n"; $$output->write("$file: file must begin with %<type> statement\n");
exit 1; exit 1;
} }
} }
...@@ -208,7 +208,7 @@ sub parse_spec_file { ...@@ -208,7 +208,7 @@ sub parse_spec_file {
if(defined($ordinal)) { if(defined($ordinal)) {
if($ordinals{$ordinal}) { if($ordinals{$ordinal}) {
print "$file: ordinal redefined: $_\n"; $$output->write("$file: ordinal redefined: $_\n");
} }
$ordinals{$ordinal}++; $ordinals{$ordinal}++;
} }
......
...@@ -6,6 +6,7 @@ use strict; ...@@ -6,6 +6,7 @@ use strict;
my $wine_dir; my $wine_dir;
my $winapi_check_dir; my $winapi_check_dir;
BEGIN { BEGIN {
if($0 =~ /^((.*?)\/?tools\/winapi_check)\/winapi_check$/) if($0 =~ /^((.*?)\/?tools\/winapi_check)\/winapi_check$/)
...@@ -24,6 +25,7 @@ BEGIN { ...@@ -24,6 +25,7 @@ BEGIN {
require "output.pm"; require "output.pm";
require "preprocessor.pm"; require "preprocessor.pm";
require "winapi.pm"; require "winapi.pm";
require "winapi_function.pm";
require "winapi_local.pm"; require "winapi_local.pm";
require "winapi_global.pm"; require "winapi_global.pm";
require "winapi_options.pm"; require "winapi_options.pm";
...@@ -33,6 +35,7 @@ BEGIN { ...@@ -33,6 +35,7 @@ BEGIN {
import output; import output;
import preprocessor; import preprocessor;
import winapi; import winapi;
import winapi_function;
import winapi_local; import winapi_local;
import winapi_global; import winapi_global;
import winapi_options; import winapi_options;
...@@ -51,7 +54,7 @@ my $win16api = 'winapi'->new($output, "win16", "$winapi_check_dir/win16api.dat", ...@@ -51,7 +54,7 @@ my $win16api = 'winapi'->new($output, "win16", "$winapi_check_dir/win16api.dat",
my $win32api = 'winapi'->new($output, "win32", "$winapi_check_dir/win32api.dat", "$winapi_check_dir/win32"); my $win32api = 'winapi'->new($output, "win32", "$winapi_check_dir/win32api.dat", "$winapi_check_dir/win32");
'winapi'->read_spec_files($wine_dir, $win16api, $win32api); 'winapi'->read_spec_files($wine_dir, $win16api, $win32api);
my $nativeapi = 'nativeapi'->new("$winapi_check_dir/nativeapi.dat", "$wine_dir/configure.in", "$wine_dir/include/config.h.in"); my $nativeapi = 'nativeapi'->new($output, "$winapi_check_dir/nativeapi.dat", "$wine_dir/configure.in", "$wine_dir/include/config.h.in");
for my $name ($win32api->all_functions) { for my $name ($win32api->all_functions) {
my $module16 = $win16api->function_module($name); my $module16 = $win16api->function_module($name);
...@@ -62,7 +65,7 @@ for my $name ($win32api->all_functions) { ...@@ -62,7 +65,7 @@ for my $name ($win32api->all_functions) {
$win32api->found_shared_function($name); $win32api->found_shared_function($name);
if($options->shared) { if($options->shared) {
print "*.spec: $name: is shared between $module16 (Win16) and $module32 (Win32)\n"; $output->write("*.spec: $name: is shared between $module16 (Win16) and $module32 (Win32)\n");
} }
} }
} }
...@@ -86,19 +89,21 @@ my %includes; ...@@ -86,19 +89,21 @@ my %includes;
} }
} }
my %functions;
my $progress_output; my $progress_output;
my $progress_current=0; my $progress_current=0;
my $progress_max=scalar($options->files); my $progress_max=scalar($options->files);
foreach my $file ($options->files) { foreach my $file ($options->files) {
my %functions;
$progress_current++; $progress_current++;
if($options->progress) { if($options->progress) {
$output->progress("$file: file $progress_current of $progress_max"); $output->progress("$file: file $progress_current of $progress_max");
} }
my $file_dir = $file; my $file_dir = $file;
$file_dir =~ s/(.*?)\/[^\/]*$/$1/; if(!($file_dir =~ s/(.*?)\/[^\/]*$/$1/)) {
$file_dir = ".";
}
my $file_type; my $file_type;
if($file_dir =~ /^(libtest|program|rc)/) { if($file_dir =~ /^(libtest|program|rc)/) {
...@@ -112,6 +117,7 @@ foreach my $file ($options->files) { ...@@ -112,6 +117,7 @@ foreach my $file ($options->files) {
} }
my $found_function = sub { my $found_function = sub {
my $documentation = shift;
my $return_type = shift; my $return_type = shift;
my $calling_convention = shift; my $calling_convention = shift;
my $name = shift; my $name = shift;
...@@ -135,16 +141,19 @@ foreach my $file ($options->files) { ...@@ -135,16 +141,19 @@ foreach my $file ($options->files) {
my $module16 = $win16api->function_module($name); my $module16 = $win16api->function_module($name);
my $module32 = $win32api->function_module($name); my $module32 = $win32api->function_module($name);
my $module; my $function = 'winapi_function'->new;
if(defined($module16) && defined($module32)) { $functions{$name} = $function;
$module = "$module16 & $module32";
} elsif(defined($module16)) { $function->documentation($documentation);
$module = $module16; $function->file($file);
} elsif(defined($module32)) { $function->return_type($return_type);
$module = $module32; $function->calling_convention($calling_convention);
} else { $function->name($name);
$module = ""; $function->arguments([@arguments]);
} $function->statements($statements);
$function->module16($module16);
$function->module32($module32);
my $output_module = sub { my $output_module = sub {
my $module = shift; my $module = shift;
return sub { return sub {
...@@ -157,22 +166,13 @@ foreach my $file ($options->files) { ...@@ -157,22 +166,13 @@ foreach my $file ($options->files) {
my $output16 = &$output_module($module16); my $output16 = &$output_module($module16);
my $output32 = &$output_module($module32); my $output32 = &$output_module($module32);
my $function = $functions{$name};
$$function{file} = $file;
$$function{return_type} = $return_type;
$$function{calling_convention} = $calling_convention;
$$function{arguments} = [@arguments];
$$function{module} = $module;
$$function{module16} = $module16;
$$function{module32} = $module32;
if($options->argument) { if($options->argument) {
if($options->win16 && $options->report_module($module16)) { if($options->win16 && $options->report_module($module16)) {
winapi_local::check_arguments $options, $output16, winapi_local::check_function $options, $output16,
$return_type, $calling_convention, $name, [@arguments], $win16api; $return_type, $calling_convention, $name, [@arguments], $win16api;
} }
if($options->win32 && $options->report_module($module32)) { if($options->win32 && $options->report_module($module32)) {
winapi_local::check_arguments $options, $output32, winapi_local::check_function $options, $output32,
$return_type, $calling_convention, $name, [@arguments], $win32api; $return_type, $calling_convention, $name, [@arguments], $win32api;
} }
} }
...@@ -202,14 +202,42 @@ foreach my $file ($options->files) { ...@@ -202,14 +202,42 @@ foreach my $file ($options->files) {
$_ = $'; $_ = $';
my $called_name = $1; my $called_name = $1;
if($called_name !~ /^if|for|while|switch|sizeof$/) { if($called_name !~ /^if|for|while|switch|sizeof$/) {
$functions{$name}{called_function_names}{$called_name}++; $functions{$name}->function_called($called_name);
$functions{$called_name}{called_by_function_names}{$name}++; if(!defined($functions{$called_name})) {
$functions{$called_name} = 'function'->new;
}
$functions{$called_name}->function_called_by($name);
} }
} else { } else {
undef $_ undef $_
} }
} }
} }
if($options->documentation && (defined($module16) || defined($module32))) {
my $name2 = $name;
my $name3 = $name;
my $name4 = $name;
my $name5 = $name;
if(defined($module16) && !defined($module32)) {
$name2 =~ s/([AW])$/16$1/;
$name3 =~ s/16(([AW])?)$/$1/;
$name4 =~ s/^\U$module16\E\_//;
$name5 =~ s/^WIN16_//;
} elsif(!defined($module16) && defined($module32)) {
$name2 =~ s/([AW])$/32$1/;
$name3 =~ s/32(([AW])?)$/$1/;
$name4 =~ s/^\U$module32\E\_//;
$name5 =~ s/^WIN16_//;
}
if($name !~ /^SMapLS|SUnMapLS/ && $documentation !~ /($name|$name2|$name3|$name4|$name5)/) {
$output->write("$file: $name: \\\n");
$output->write("$documentation\n");
}
}
} }
}; };
...@@ -278,7 +306,7 @@ foreach my $file ($options->files) { ...@@ -278,7 +306,7 @@ foreach my $file ($options->files) {
foreach my $name (keys(%{$includes{"$file_dir/$header"}{includes}})) { foreach my $name (keys(%{$includes{"$file_dir/$header"}{includes}})) {
$includes{$name}{used}++; $includes{$name}{used}++;
} }
} elsif(-e "include/$header") { } elsif(-e "$wine_dir/include/$header") {
$includes{"include/$header"}{used}++; $includes{"include/$header"}{used}++;
foreach my $name (keys(%{$includes{"include/$header"}{includes}})) { foreach my $name (keys(%{$includes{"include/$header"}{includes}})) {
$includes{$name}{used}++; $includes{$name}{used}++;
...@@ -291,7 +319,7 @@ foreach my $file ($options->files) { ...@@ -291,7 +319,7 @@ foreach my $file ($options->files) {
} }
}; };
winapi_parser::parse_c_file $options, $file, $found_function, $found_preprocessor; winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor;
if($options->config_unnessary) { if($options->config_unnessary) {
if($config && $conditional == 0) { if($config && $conditional == 0) {
...@@ -299,26 +327,7 @@ foreach my $file ($options->files) { ...@@ -299,26 +327,7 @@ foreach my $file ($options->files) {
} }
} }
if($options->cross_call) { winapi_local::check_file $options, $output, $file, \%functions;
my @names = sort(keys(%functions));
for my $name (@names) {
my @called_names = sort(keys(%{$functions{$name}{called_function_names}}));
my @called_by_names = sort(keys(%{$functions{$name}{called_by_function_names}}));
my $module = $functions{$name}{module};
my $module16 = $functions{$name}{module16};
my $module32 = $functions{$name}{module32};
if($#called_names >= 0 && (defined($module16) || defined($module32)) ) {
$output->write("$file: $module: $name: \\\n");
for my $called_name (@called_names) {
my $function;
if($function = $functions{$called_name}) {
$output->write(" $called_name\n");
}
}
}
}
}
} }
$output->hide_progress; $output->hide_progress;
...@@ -327,12 +336,12 @@ if($options->global) { ...@@ -327,12 +336,12 @@ if($options->global) {
foreach my $name (sort(keys(%includes))) { foreach my $name (sort(keys(%includes))) {
if(!$includes{$name}{used}) { if(!$includes{$name}{used}) {
if($options->include) { if($options->include) {
print "$name: include file is never used\n"; $output->write("$name: include file is never used\n");
} }
} }
} }
winapi_global::check $options, $win16api, $nativeapi if $options->win16; winapi_global::check $options, $output, $win16api, $nativeapi if $options->win16;
winapi_global::check $options, $win32api, $nativeapi if $options->win32; winapi_global::check $options, $output, $win32api, $nativeapi if $options->win32;
} }
package winapi_function;
use strict;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless ($self, $class);
return $self;
}
sub file {
my $self = shift;
my $file = \${$self->{FILE}};
local $_ = shift;
if(defined($_)) { $$file = $_; }
return $$file;
}
sub documentation {
my $self = shift;
my $documentation = \${$self->{DOCUMENTATION}};
local $_ = shift;
if(defined($_)) { $$documentation = $_; }
return $$documentation;
}
sub return_type {
my $self = shift;
my $return_type = \${$self->{RETURN_TYPE}};
local $_ = shift;
if(defined($_)) { $$return_type = $_; }
return $$return_type;
}
sub calling_convention {
my $self = shift;
my $calling_convention = \${$self->{CALLING_CONVENTION}};
local $_ = shift;
if(defined($_)) { $$calling_convention = $_; }
return $$calling_convention;
}
sub name {
my $self = shift;
my $name = \${$self->{NAME}};
local $_ = shift;
if(defined($_)) { $$name = $_; }
return $$name;
}
sub arguments {
my $self = shift;
my $arguments = \${$self->{ARGUMENTS}};
local $_ = shift;
if(defined($_)) { $$arguments = $_; }
return $$arguments;
}
sub module16 {
my $self = shift;
my $module16 = \${$self->{MODULE16}};
local $_ = shift;
if(defined($_)) { $$module16 = $_; }
return $$module16;
}
sub module32 {
my $self = shift;
my $module32 = \${$self->{MODULE32}};
local $_ = shift;
if(defined($_)) { $$module32 = $_; }
return $$module32;
}
sub statements {
my $self = shift;
my $statements = \${$self->{STATEMENTS}};
local $_ = shift;
if(defined($_)) { $$statements = $_; }
return $$statements;
}
sub module {
my $self = shift;
my $module16 = \${$self->{MODULE16}};
my $module32 = \${$self->{MODULE32}};
my $module;
if(defined($$module16) && defined($$module32)) {
$module = "$$module16 & $$module32";
} elsif(defined($$module16)) {
$module = $$module16;
} elsif(defined($$module32)) {
$module = $$module32;
} else {
$module = "";
}
}
sub function_called {
my $self = shift;
my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
my $name = shift;
$$called_function_names{$name}++;
}
sub function_called_by {
my $self = shift;
my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
my $name = shift;
$$called_by_function_names{$name}++;
}
sub called_function_names {
my $self = shift;
my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
return sort(keys(%$called_function_names));
}
sub called_by_function_names {
my $self = shift;
my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
return sort(keys(%$called_by_function_names));
}
1;
...@@ -4,6 +4,7 @@ use strict; ...@@ -4,6 +4,7 @@ use strict;
sub check { sub check {
my $options = shift; my $options = shift;
my $output = shift;
my $winapi = shift; my $winapi = shift;
my $nativeapi = shift; my $nativeapi = shift;
...@@ -11,9 +12,9 @@ sub check { ...@@ -11,9 +12,9 @@ sub check {
if($options->argument) { if($options->argument) {
foreach my $type ($winapi->all_declared_types) { foreach my $type ($winapi->all_declared_types) {
if(!$winapi->type_found($type) && !$winapi->is_type_limited($type) && $type ne "CONTEXT86 *") { if(!$winapi->type_found($type) && !$winapi->is_limited_type($type) && $type ne "CONTEXT86 *") {
print "*.c: $winver: "; $output->write("*.c: $winver: ");
print "type ($type) not used\n"; $output->write("type ($type) not used\n");
} }
} }
} }
...@@ -22,8 +23,8 @@ sub check { ...@@ -22,8 +23,8 @@ sub check {
foreach my $name ($winapi->all_functions) { foreach my $name ($winapi->all_functions) {
if(!$winapi->function_found($name) && !$nativeapi->is_function($name)) { if(!$winapi->function_found($name) && !$nativeapi->is_function($name)) {
my $module = $winapi->function_module($name); my $module = $winapi->function_module($name);
print "*.c: $module: $name: "; $output->write("*.c: $module: $name: ");
print "function declared but not implemented: " . $winapi->function_arguments($name) . "\n"; $output->write("function declared but not implemented: " . $winapi->function_arguments($name) . "\n");
} }
} }
} }
...@@ -33,10 +34,9 @@ sub check { ...@@ -33,10 +34,9 @@ sub check {
foreach my $module (sort(keys(%$not_used))) { foreach my $module (sort(keys(%$not_used))) {
foreach my $type (sort(keys(%{$$not_used{$module}}))) { foreach my $type (sort(keys(%{$$not_used{$module}}))) {
print "*.c: $module: type $type not used\n"; $output->write("*.c: $module: type $type not used\n");
} }
} }
} }
} }
......
...@@ -2,7 +2,7 @@ package winapi_local; ...@@ -2,7 +2,7 @@ package winapi_local;
use strict; use strict;
sub check_arguments { sub check_function {
my $options = shift; my $options = shift;
my $output = shift; my $output = shift;
my $return_type = shift; my $return_type = shift;
...@@ -163,5 +163,36 @@ sub check_arguments { ...@@ -163,5 +163,36 @@ sub check_arguments {
} }
} }
sub check_file {
my $options = shift;
my $output = shift;
my $file = shift;
my $functions = shift;
if($options->cross_call) {
my @names = sort(keys(%$functions));
for my $name (@names) {
my @called_names = $$functions{$name}->called_function_names;
my @called_by_names = $$functions{$name}->called_by_function_names;
my $module = $$functions{$name}->module;
my $module16 = $$functions{$name}->module16;
my $module32 = $$functions{$name}->module32;
if($#called_names >= 0 && (defined($module16) || defined($module32)) ) {
for my $called_name (@called_names) {
my $called_module16 = $$functions{$called_name}->module16;
my $called_module32 = $$functions{$called_name}->module32;
if(defined($module32) &&
defined($called_module16) && !defined($called_module32) &&
$name ne $called_name)
{
$output->write("$file: $module: $name: illegal call to $called_name (Win16)\n");
}
}
}
}
}
}
1; 1;
...@@ -59,6 +59,7 @@ my %options = ( ...@@ -59,6 +59,7 @@ my %options = (
"calling-convention" => { default => 0, parent => "local", description => "calling convention checking" }, "calling-convention" => { default => 0, parent => "local", description => "calling convention checking" },
"misplaced" => { default => 0, parent => "local", description => "check for misplaced functions" }, "misplaced" => { default => 0, parent => "local", description => "check for misplaced functions" },
"cross-call" => { default => 0, parent => "local", description => "check for cross calling functions" }, "cross-call" => { default => 0, parent => "local", description => "check for cross calling functions" },
"documentation" => { default => 0, parent => "local", description => "check for documentation inconsistances\n" },
"global" => { default => 1, description => "global checking" }, "global" => { default => 1, description => "global checking" },
"declared" => { default => 1, parent => "global", description => "declared checking" }, "declared" => { default => 1, parent => "global", description => "declared checking" },
......
...@@ -4,10 +4,12 @@ use strict; ...@@ -4,10 +4,12 @@ use strict;
sub parse_c_file { sub parse_c_file {
my $options = shift; my $options = shift;
my $output = shift;
my $file = shift; my $file = shift;
my $function_found_callback = shift; my $function_found_callback = shift;
my $preprocessor_found_callback = shift; my $preprocessor_found_callback = shift;
my $documentation;
my $return_type; my $return_type;
my $calling_convention; my $calling_convention;
my $function = ""; my $function = "";
...@@ -15,6 +17,7 @@ sub parse_c_file { ...@@ -15,6 +17,7 @@ sub parse_c_file {
my $statements; my $statements;
my $function_begin = sub { my $function_begin = sub {
$documentation = shift;
$return_type= shift; $return_type= shift;
$calling_convention = shift; $calling_convention = shift;
$function = shift; $function = shift;
...@@ -23,11 +26,12 @@ sub parse_c_file { ...@@ -23,11 +26,12 @@ sub parse_c_file {
$statements = ""; $statements = "";
}; };
my $function_end = sub { my $function_end = sub {
&$function_found_callback($return_type,$calling_convention,$function,$arguments,$statements); &$function_found_callback($documentation,$return_type,$calling_convention,$function,$arguments,$statements);
$function = ""; $function = "";
}; };
my @comments = ();
my $level = 0; my $level = 0;
my $again = 0; my $again = 0;
my $lookahead = 0; my $lookahead = 0;
...@@ -53,9 +57,15 @@ sub parse_c_file { ...@@ -53,9 +57,15 @@ sub parse_c_file {
$lookahead_count = 0; $lookahead_count = 0;
$again = 0; $again = 0;
} }
# Merge conflicts in file?
if(/^(<<<<<<<|=======|>>>>>>>)/) {
$output->write("$file: merge conflicts in file\n");
last;
}
# remove comments # remove comments
if(s/^(.*?)\/\*.*?\*\/(.*)$/$1 $2/s) { $again = 1; next }; if(s/^(.*?)(\/\*.*?\*\/)(.*)$/$1 $3/s) { push @comments, $2; $again = 1; next };
if(/^(.*?)\/\*/s) { if(/^(.*?)\/\*/s) {
$lookahead = 1; $lookahead = 1;
next; next;
...@@ -80,6 +90,17 @@ sub parse_c_file { ...@@ -80,6 +90,17 @@ sub parse_c_file {
} }
} }
my $documentation;
{
my $n = $#comments;
while($n >= 0 && $comments[$n] !~ /\/\*\*/) { $n-- }
if(defined($comments[$n]) && $n >= 0) {
$documentation = $comments[$n];
} else {
$documentation = "";
}
}
if($level > 0) if($level > 0)
{ {
my $line; my $line;
...@@ -110,8 +131,8 @@ sub parse_c_file { ...@@ -110,8 +131,8 @@ sub parse_c_file {
next; next;
} elsif($10 eq "{") { } elsif($10 eq "{") {
$level++; $level++;
} }
my $return_type = $1; my $return_type = $1;
my $calling_convention = $6; my $calling_convention = $6;
my $name = $7; my $name = $7;
...@@ -156,65 +177,65 @@ sub parse_c_file { ...@@ -156,65 +177,65 @@ sub parse_c_file {
if($options->debug) { if($options->debug) {
print "$file: $return_type $calling_convention $name(" . join(",", @arguments) . ")\n"; print "$file: $return_type $calling_convention $name(" . join(",", @arguments) . ")\n";
} }
&$function_begin($return_type,$calling_convention,$name,\@arguments); &$function_begin($documentation,$return_type,$calling_convention,$name,\@arguments);
} elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments = ("HDC16"); my @arguments = ("HDC16");
&$function_begin($2, "WINAPI", $3, \@arguments); &$function_begin($documentation,$2, "WINAPI", $3, \@arguments);
&$function_end; &$function_end;
} elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) { } elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments = ("HDC"); my @arguments = ("HDC");
&$function_begin($2, "WINAPI", $3, \@arguments); &$function_begin($documentation,$2, "WINAPI", $3, \@arguments);
&$function_end; &$function_end;
} elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments16 = ("HDC16", "LP" . $5 . "16"); my @arguments16 = ("HDC16", "LP" . $5 . "16");
my @arguments32 = ("HDC", "LP" . $5); my @arguments32 = ("HDC", "LP" . $5);
&$function_begin("BOOL16", "WINAPI", $2 . "16", \@arguments16); &$function_begin($documentation,"BOOL16", "WINAPI", $2 . "16", \@arguments16);
&$function_end; &$function_end;
&$function_begin("BOOL", "WINAPI", $2, \@arguments32); &$function_begin($documentation,"BOOL", "WINAPI", $2, \@arguments32);
&$function_end; &$function_end;
} elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments16 = ("HDC16", "INT16"); my @arguments16 = ("HDC16", "INT16");
my @arguments32 = ("HDC", "INT"); my @arguments32 = ("HDC", "INT");
&$function_begin("INT16", "WINAPI", $2 . "16", \@arguments16); &$function_begin($documentation,"INT16", "WINAPI", $2 . "16", \@arguments16);
&$function_end; &$function_end;
&$function_begin("INT", "WINAPI", $2, \@arguments32); &$function_begin($documentation,"INT", "WINAPI", $2, \@arguments32);
&$function_end; &$function_end;
} elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments16 = ("HWAVEIN16"); my @arguments16 = ("HWAVEIN16");
my @arguments32 = ("HWAVEIN"); my @arguments32 = ("HWAVEIN");
&$function_begin("UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16); &$function_begin($documentation,"UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
&$function_end; &$function_end;
&$function_begin("UINT", "WINAPI", "waveIn" . $1, \@arguments32); &$function_begin($documentation,"UINT", "WINAPI", "waveIn" . $1, \@arguments32);
&$function_end; &$function_end;
} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments16 = ("HWAVEOUT16"); my @arguments16 = ("HWAVEOUT16");
my @arguments32 = ("HWAVEOUT"); my @arguments32 = ("HWAVEOUT");
&$function_begin("UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16); &$function_begin($documentation,"UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
&$function_end; &$function_end;
&$function_begin("UINT", "WINAPI", "waveOut" . $1, \@arguments32); &$function_begin($documentation,"UINT", "WINAPI", "waveOut" . $1, \@arguments32);
&$function_end; &$function_end;
} elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1; $_ = $'; $again = 1;
if($1 eq "1") { if($1 eq "1") {
my @arguments16 = ("HWAVEOUT16", $4); my @arguments16 = ("HWAVEOUT16", $4);
my @arguments32 = ("HWAVEOUT", $4); my @arguments32 = ("HWAVEOUT", $4);
&$function_begin("UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16); &$function_begin($documentation,"UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
&$function_end; &$function_end;
&$function_begin("UINT", "WINAPI", "waveOut" . $2, \@arguments32); &$function_begin($documentation,"UINT", "WINAPI", "waveOut" . $2, \@arguments32);
&$function_end; &$function_end;
} elsif($1 eq 2) { } elsif($1 eq 2) {
my @arguments16 = ("UINT16", $4); my @arguments16 = ("UINT16", $4);
my @arguments32 = ("UINT", $4); my @arguments32 = ("UINT", $4);
&$function_begin("UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16); &$function_begin($documentation,"UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
&$function_end; &$function_end;
&$function_begin("UINT", "WINAPI", "waveOut" . $2, \@arguments32); &$function_begin($documentation,"UINT", "WINAPI", "waveOut" . $2, \@arguments32);
&$function_end; &$function_end;
} }
} elsif(/;/s) { } elsif(/;/s) {
...@@ -229,7 +250,7 @@ sub parse_c_file { ...@@ -229,7 +250,7 @@ sub parse_c_file {
} }
close(IN); close(IN);
print STDERR "done\n" if $options->verbose; print STDERR "done\n" if $options->verbose;
print "$file: <>: not at toplevel at end of file\n" unless $level == 0; $output->write("$file: not at toplevel at end of file\n") unless $level == 0;
} }
1; 1;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment