Commit 1c61b3ba authored by Patrik Stridvall's avatar Patrik Stridvall Committed by Alexandre Julliard

Yet another major reorganization and a few new features.

parent 5dda1f7e
...@@ -20,7 +20,7 @@ require Exporter; ...@@ -20,7 +20,7 @@ require Exporter;
use vars qw($current_dir $wine_dir $winapi_dir $winapi_check_dir); use vars qw($current_dir $wine_dir $winapi_dir $winapi_check_dir);
my $output = "output"; use output qw($output);
sub file_type { sub file_type {
local $_ = shift; local $_ = shift;
......
...@@ -6,10 +6,10 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); ...@@ -6,10 +6,10 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter; require Exporter;
@ISA = qw(Exporter); @ISA = qw(Exporter);
@EXPORT = qw(&parse_comma_list); @EXPORT = qw();
@EXPORT_OK = qw(); @EXPORT_OK = qw($options &parse_comma_list);
my $output = "output"; use vars qw($options);
sub parse_comma_list { sub parse_comma_list {
my $prefix = shift; my $prefix = shift;
...@@ -27,27 +27,13 @@ sub parse_comma_list { ...@@ -27,27 +27,13 @@ sub parse_comma_list {
} }
} }
my $_options;
sub new {
my $self = shift;
$_options = _options->new(@_);
return $_options;
}
sub AUTOLOAD {
my $self = shift;
my $name = $options::AUTOLOAD;
$name =~ s/^.*::(.[^:]*)$/$1/;
return $_options->$name(@_);
}
package _options; package _options;
use strict; use strict;
use config qw($current_dir $wine_dir);
use output qw($output);
sub new { sub new {
my $proto = shift; my $proto = shift;
my $class = ref($proto) || $proto; my $class = ref($proto) || $proto;
...@@ -209,8 +195,8 @@ sub new { ...@@ -209,8 +195,8 @@ sub new {
} split(/\n/, `$c_command`)); } split(/\n/, `$c_command`));
} }
if($#h_files != -1) { if($#paths != -1 || $#h_files != -1) {
my $h_command = "find " . join(" ", @h_files) . " -name \\*.h"; my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h";
my %found; my %found;
@$h_files = sort(map { @$h_files = sort(map {
......
...@@ -2,22 +2,16 @@ package output; ...@@ -2,22 +2,16 @@ package output;
use strict; use strict;
my $_output; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
sub new { @ISA = qw(Exporter);
my $self = shift; @EXPORT = qw();
$_output = _output->new(@_); @EXPORT_OK = qw($output);
return $_output;
}
sub AUTOLOAD { use vars qw($output);
my $self = shift;
my $name = $output::AUTOLOAD; $output = '_output'->new;
$name =~ s/^.*::(.[^:]*)$/$1/;
return $_output->$name(@_);
}
package _output; package _output;
...@@ -37,17 +31,18 @@ sub new { ...@@ -37,17 +31,18 @@ sub new {
my $last_time = \${$self->{LAST_TIME}}; my $last_time = \${$self->{LAST_TIME}};
my $progress_count = \${$self->{PROGRESS_COUNT}}; my $progress_count = \${$self->{PROGRESS_COUNT}};
my $prefix = \${$self->{PREFIX}}; my $prefix = \${$self->{PREFIX}};
my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
$$progress = ""; $$progress = "";
$$last_progress = ""; $$last_progress = "";
$$last_time = 0; $$last_time = 0;
$$progress_count = 0; $$progress_count = 0;
$$prefix = ""; $$prefix = undef;
$$prefix_callback = undef;
return $self; return $self;
} }
sub show_progress { sub show_progress {
my $self = shift; my $self = shift;
my $progress = \${$self->{PROGRESS}}; my $progress = \${$self->{PROGRESS}};
...@@ -134,8 +129,20 @@ sub lazy_progress { ...@@ -134,8 +129,20 @@ sub lazy_progress {
sub prefix { sub prefix {
my $self = shift; my $self = shift;
my $prefix = \${$self->{PREFIX}}; my $prefix = \${$self->{PREFIX}};
my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
$$prefix = shift; $$prefix = shift;
$$prefix_callback = undef;
}
sub prefix_callback {
my $self = shift;
my $prefix = \${$self->{PREFIX}};
my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
$$prefix = undef;
$$prefix_callback = shift;
} }
sub write { sub write {
...@@ -144,9 +151,16 @@ sub write { ...@@ -144,9 +151,16 @@ sub write {
my $message = shift; my $message = shift;
my $prefix = \${$self->{PREFIX}}; my $prefix = \${$self->{PREFIX}};
my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
$self->hide_progress if $stdout_isatty; $self->hide_progress if $stdout_isatty;
if(defined($$prefix)) {
print $$prefix . $message; print $$prefix . $message;
} elsif(defined($$prefix_callback)) {
print &{$$prefix_callback}() . $message;
} else {
print $message;
}
$self->show_progress if $stdout_isatty; $self->show_progress if $stdout_isatty;
} }
......
package winapi_check_options;
use base qw(options);
use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw($options);
use config qw($current_dir $wine_dir);
use options qw($options &parse_comma_list);
my %options_long = (
"debug" => { default => 0, description => "debug mode" },
"help" => { default => 0, description => "help mode" },
"verbose" => { default => 0, description => "verbose mode" },
"progress" => { default => 1, description => "show progress" },
"win16" => { default => 1, description => "Win16 checking" },
"win32" => { default => 1, description => "Win32 checking" },
"shared" => { default => 0, description => "show shared functions between Win16 and Win32" },
"shared-segmented" => { default => 0, description => "segmented shared functions between Win16 and Win32 checking" },
"config" => { default => 1, parent => "local", description => "check configuration include consistancy" },
"config-unnessary" => { default => 0, parent => "config", description => "check for unnessary #include \"config.h\"" },
"spec-mismatch" => { default => 0, description => "spec file mismatch checking" },
"local" => { default => 1, description => "local checking" },
"module" => {
default => { active => 1, filter => 0, hash => {} },
parent => "local",
parser => \&parser_comma_list,
description => "module filter"
},
"argument" => { default => 1, parent => "local", description => "argument checking" },
"argument-count" => { default => 1, parent => "argument", description => "argument count checking" },
"argument-forbidden" => {
default => { active => 1, filter => 0, hash => {} },
parent => "argument",
parser => \&parser_comma_list,
description => "argument forbidden checking"
},
"argument-kind" => {
default => { active => 1, filter => 1, hash => { double => 1 } },
parent => "argument",
parser => \&parser_comma_list,
description => "argument kind checking"
},
"calling-convention" => { default => 1, parent => "local", description => "calling convention checking" },
"calling-convention-win16" => { default => 0, parent => "calling-convention", description => "calling convention checking (Win16)" },
"calling-convention-win32" => { default => 1, parent => "calling-convention", description => "calling convention checking (Win32)" },
"misplaced" => { default => 1, parent => "local", description => "check for misplaced functions" },
"statements" => { default => 0, parent => "local", description => "check for statements inconsistances" },
"cross-call" => { default => 0, parent => "statements", description => "check for cross calling functions" },
"cross-call-win32-win16" => {
default => 0, parent => "cross-call", description => "check for cross calls between win32 and win16"
},
"cross-call-unicode-ascii" => {
default => 0, parent => "cross-call", description => "check for cross calls between Unicode and ASCII"
},
"debug-messages" => { default => 0, parent => "statements", description => "check for debug messages inconsistances" },
"documentation" => {
default => 1,
parent => "local",
description => "check for documentation inconsistances"
},
"documentation-pedantic" => {
default => 0,
parent => "documentation",
description => "be pendantic when checking for documentation inconsistances"
},
"documentation-arguments" => {
default => 1,
parent => "documentation",
description => "check for arguments documentation inconsistances\n"
},
"documentation-comment-indent" => {
default => 0,
parent => "documentation", description => "check for documentation comment indent inconsistances"
},
"documentation-comment-width" => {
default => 0,
parent => "documentation", description => "check for documentation comment width inconsistances"
},
"documentation-name" => {
default => 1,
parent => "documentation",
description => "check for documentation name inconsistances\n"
},
"documentation-ordinal" => {
default => 1,
parent => "documentation",
description => "check for documentation ordinal inconsistances\n"
},
"documentation-wrong" => {
default => 1,
parent => "documentation",
description => "check for wrong documentation\n"
},
"prototype" => {default => 0, parent => ["local", "headers"], description => "prototype checking" },
"global" => { default => 1, description => "global checking" },
"declared" => { default => 1, parent => "global", description => "declared checking" },
"implemented" => { default => 0, parent => "local", description => "implemented checking" },
"implemented-win32" => { default => 0, parent => "implemented", description => "implemented as win32 checking" },
"include" => { default => 1, parent => "global", description => "include checking" },
"headers" => { default => 0, description => "headers checking" },
"headers-duplicated" => { default => 0, parent => "headers", description => "duplicated function declarations checking" },
"headers-misplaced" => { default => 0, parent => "headers", description => "misplaced function declarations checking" },
"headers-needed" => { default => 1, parent => "headers", description => "headers needed checking" },
"headers-unused" => { default => 0, parent => "headers", description => "headers unused checking" },
);
my %options_short = (
"d" => "debug",
"?" => "help",
"v" => "verbose"
);
my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
$options = '_winapi_check_options'->new(\%options_long, \%options_short, $options_usage);
my $global = \${$options->{GLOBAL}};
if($wine_dir ne ".") {
$$global = 0;
}
package _winapi_check_options;
use base qw(_options);
use strict;
sub report_module {
my $self = shift;
my $refvalue = $self->{MODULE};
my $name = shift;
if(defined($name)) {
return $$refvalue->{active} && (!$$refvalue->{filter} || $$refvalue->{hash}->{$name});
} else {
return 0;
}
}
sub report_argument_forbidden {
my $self = shift;
my $refargument_forbidden = $self->{ARGUMENT_FORBIDDEN};
my $type = shift;
return $$refargument_forbidden->{active} && (!$$refargument_forbidden->{filter} || $$refargument_forbidden->{hash}->{$type});
}
sub report_argument_kind {
my $self = shift;
my $refargument_kind = $self->{ARGUMENT_KIND};
my $kind = shift;
return $$refargument_kind->{active} && (!$$refargument_kind->{filter} || $$refargument_kind->{hash}->{$kind});
}
1;
...@@ -15,40 +15,12 @@ use config qw( ...@@ -15,40 +15,12 @@ use config qw(
); );
use modules; use modules;
use nativeapi; use nativeapi;
use output; use output qw($output);
use options; use options;
use winapi; use winapi;
use winapi_function; use winapi_function;
use winapi_parser; use winapi_parser;
use winapi_extract_options qw($options);
my $output = 'output'->new;
my %options_long = (
"debug" => { default => 0, description => "debug mode" },
"help" => { default => 0, description => "help mode" },
"verbose" => { default => 0, description => "verbose mode" },
"progress" => { default => 1, description => "show progress" },
"win16" => { default => 1, description => "Win16 extraction" },
"win32" => { default => 1, description => "Win32 extraction" },
"local" => { default => 1, description => "local extraction" },
"global" => { default => 1, description => "global extraction" },
"spec-files" => { default => 1, parent => "global", description => "spec files extraction" },
"stub-statistics" => { default => 0, parent => "global", description => "stub statistics" },
);
my %options_short = (
"d" => "debug",
"?" => "help",
"v" => "verbose"
);
my $options_usage = "usage: winapi_extract [--help] [<files>]\n";
my $options = 'options'->new(\%options_long, \%options_short, $options_usage);
my %module2spec_file; my %module2spec_file;
my %module2type; my %module2type;
...@@ -104,7 +76,6 @@ sub documentation_specifications { ...@@ -104,7 +76,6 @@ sub documentation_specifications {
my $return_type = $function->return_type; my $return_type = $function->return_type;
my $linkage = $function->linkage; my $linkage = $function->linkage;
my $internal_name = $function->internal_name; my $internal_name = $function->internal_name;
my @argument_types = @{$function->argument_types};
if($linkage eq "static") { if($linkage eq "static") {
return; return;
...@@ -203,14 +174,11 @@ foreach my $file (@c_files) { ...@@ -203,14 +174,11 @@ foreach my $file (@c_files) {
my $return_type = $function->return_type; my $return_type = $function->return_type;
my $calling_convention = $function->calling_convention; my $calling_convention = $function->calling_convention;
my $internal_name = $function->internal_name; my $internal_name = $function->internal_name;
my @argument_types = @{$function->argument_types};
my @argument_names = @{$function->argument_names};
my @argument_documentations = @{$function->argument_documentations};
my $statements = $function->statements; my $statements = $function->statements;
$functions{$internal_name} = $function; $functions{$internal_name} = $function;
$output->prefix("$file: " . $function->prefix); $output->prefix_callback(sub { return $function->prefix; });
if($options->spec_files) { if($options->spec_files) {
documentation_specifications($function); documentation_specifications($function);
...@@ -228,7 +196,7 @@ foreach my $file (@c_files) { ...@@ -228,7 +196,7 @@ foreach my $file (@c_files) {
my $argument = shift; my $argument = shift;
}; };
winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor; &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
my @internal_names = keys(%functions); my @internal_names = keys(%functions);
if($#internal_names < 0) { if($#internal_names < 0) {
...@@ -247,18 +215,23 @@ sub output_function { ...@@ -247,18 +215,23 @@ sub output_function {
my $return_kind; my $return_kind;
my $calling_convention; my $calling_convention;
my @argument_kinds; my $refargument_kinds;
if($type eq "win16") { if($type eq "win16") {
$return_kind = $function->return_kind16 || "undef"; $return_kind = $function->return_kind16 || "undef";
$calling_convention = $function->calling_convention16 || "undef"; $calling_convention = $function->calling_convention16 || "undef";
@argument_kinds = map { $_ || "undef"; } @{$function->argument_kinds16}; $refargument_kinds = $function->argument_kinds16;
} elsif($type eq "win32") { } elsif($type eq "win32") {
$return_kind = $function->return_kind32 || "undef"; $return_kind = $function->return_kind32 || "undef";
$calling_convention = $function->calling_convention32 || "undef"; $calling_convention = $function->calling_convention32 || "undef";
@argument_kinds = map { $_ || "undef"; } @{$function->argument_kinds32}; $refargument_kinds = $function->argument_kinds32;
} }
if(defined($refargument_kinds)) {
my @argument_kinds = map { $_ || "undef"; } @$refargument_kinds;
print OUT "$ordinal $calling_convention $external_name(@argument_kinds) $internal_name\n"; print OUT "$ordinal $calling_convention $external_name(@argument_kinds) $internal_name\n";
} else {
print OUT "$ordinal $calling_convention $external_name() $internal_name # FIXME: arguments undefined\n";
}
} }
if($options->spec_files) { if($options->spec_files) {
......
package winapi_extract_options;
use base qw(options);
use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw($options);
use options qw($options &parse_comma_list);
my %options_long = (
"debug" => { default => 0, description => "debug mode" },
"help" => { default => 0, description => "help mode" },
"verbose" => { default => 0, description => "verbose mode" },
"progress" => { default => 1, description => "show progress" },
"win16" => { default => 1, description => "Win16 extraction" },
"win32" => { default => 1, description => "Win32 extraction" },
"local" => { default => 1, description => "local extraction" },
"global" => { default => 1, description => "global extraction" },
"spec-files" => { default => 1, parent => "global", description => "spec files extraction" },
"stub-statistics" => { default => 0, parent => "global", description => "stub statistics" },
);
my %options_short = (
"d" => "debug",
"?" => "help",
"v" => "verbose"
);
my $options_usage = "usage: winapi_extract [--help] [<files>]\n";
$options = '_options'->new(\%options_long, \%options_short, $options_usage);
1;
...@@ -16,47 +16,12 @@ use config qw( ...@@ -16,47 +16,12 @@ use config qw(
&get_spec_files &get_spec_files
$current_dir $wine_dir $winapi_dir $winapi_check_dir $current_dir $wine_dir $winapi_dir $winapi_check_dir
); );
use output; use output qw($output);
use options;
use modules; use modules;
use util; use util;
use winapi; use winapi;
use winapi_parser; use winapi_parser;
use winapi_fixup_options qw($options);
my $output = 'output'->new;
my %options_long = (
"debug" => { default => 0, description => "debug mode" },
"help" => { default => 0, description => "help mode" },
"verbose" => { default => 0, description => "verbose mode" },
"progress" => { default => 1, description => "show progress" },
"win16" => { default => 1, description => "Win16 fixup" },
"win32" => { default => 1, description => "Win32 fixup" },
"local" => { default => 1, description => "local fixup" },
"documentation" => { default => 1, parent => "local", description => "documentation fixup" },
"documentation-missing" => { default => 1, parent => "documentation", description => "documentation missing fixup" },
"documentation-name" => { default => 1, parent => "documentation", description => "documentation name fixup" },
"documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" },
"documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" },
"stub" => { default => 0, parent => "local", description => "stub fixup" },
"global" => { default => 1, description => "global fixup" },
"modify" => { default => 0, description => "actually perform the fixups" },
);
my %options_short = (
"d" => "debug",
"?" => "help",
"v" => "verbose"
);
my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
my $options = 'options'->new(\%options_long, \%options_short, $options_usage);
my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat"); my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat");
...@@ -91,6 +56,8 @@ foreach my $file (@c_files) { ...@@ -91,6 +56,8 @@ foreach my $file (@c_files) {
$output->progress("$file: file $progress_current of $progress_max"); $output->progress("$file: file $progress_current of $progress_max");
} }
my %documentation_line_used;
my $found_function = sub { my $found_function = sub {
my $function = shift; my $function = shift;
...@@ -101,12 +68,12 @@ foreach my $file (@c_files) { ...@@ -101,12 +68,12 @@ foreach my $file (@c_files) {
my $return_type = $function->return_type; my $return_type = $function->return_type;
my $calling_convention = $function->calling_convention; my $calling_convention = $function->calling_convention;
my $internal_name = $function->internal_name; my $internal_name = $function->internal_name;
my @argument_types = @{$function->argument_types};
my @argument_names = @{$function->argument_names};
my @argument_documentations = @{$function->argument_documentations};
my $statements = $function->statements; my $statements = $function->statements;
if($linkage eq "static" || ($linkage eq "" && !defined($statements))) { if($linkage eq "static" ||
($linkage eq "extern" && !defined($statements)) ||
($linkage eq "" && !defined($statements)))
{
return; return;
} }
...@@ -115,7 +82,12 @@ foreach my $file (@c_files) { ...@@ -115,7 +82,12 @@ foreach my $file (@c_files) {
return; return;
} }
$output->prefix("$file: " . $function->prefix); if($documentation_line_used{$documentation_line}) {
$documentation = undef;
}
$documentation_line_used{$documentation_line}++;
$output->prefix_callback(sub { return $function->prefix; });
my @module_ordinal_entries = (); my @module_ordinal_entries = ();
foreach my $entry2 ($function->get_all_module_ordinal) { foreach my $entry2 ($function->get_all_module_ordinal) {
...@@ -131,7 +103,7 @@ foreach my $file (@c_files) { ...@@ -131,7 +103,7 @@ foreach my $file (@c_files) {
my $spec_modified = 0; my $spec_modified = 0;
if($options->stub && $documentation) { if($options->stub && defined($documentation)) {
my $calling_convention16 = $function->calling_convention16; my $calling_convention16 = $function->calling_convention16;
my $calling_convention32 = $function->calling_convention32; my $calling_convention32 = $function->calling_convention32;
...@@ -170,6 +142,12 @@ foreach my $file (@c_files) { ...@@ -170,6 +142,12 @@ foreach my $file (@c_files) {
foreach my $entry (@entries) { foreach my $entry (@entries) {
(my $external_name, my $module, my $ordinal) = @$entry; (my $external_name, my $module, my $ordinal) = @$entry;
my $refargument_types = $function->argument_types;
if(!defined($refargument_types)) {
next;
}
my $abort = 0; my $abort = 0;
my $n; my $n;
my @argument_kinds = map { my @argument_kinds = map {
...@@ -198,7 +176,7 @@ foreach my $file (@c_files) { ...@@ -198,7 +176,7 @@ foreach my $file (@c_files) {
$n++; $n++;
"undef"; "undef";
} }
} @argument_types; } @$refargument_types;
my $substitute = {}; my $substitute = {};
$substitute->{search} = "^\\s*$ordinal\\s+stub\\s+$external_name\\s*(?:#.*?)?\$"; $substitute->{search} = "^\\s*$ordinal\\s+stub\\s+$external_name\\s*(?:#.*?)?\$";
...@@ -229,7 +207,7 @@ foreach my $file (@c_files) { ...@@ -229,7 +207,7 @@ foreach my $file (@c_files) {
my $documentation_modified = 0; my $documentation_modified = 0;
if(!$spec_modified && if(!$spec_modified &&
($documentation && !$documentation_modified) && (defined($documentation) && !$documentation_modified) &&
($options->documentation_name || $options->documentation_ordinal || ($options->documentation_name || $options->documentation_ordinal ||
$options->documentation_missing)) $options->documentation_missing))
{ {
...@@ -337,6 +315,7 @@ foreach my $file (@c_files) { ...@@ -337,6 +315,7 @@ foreach my $file (@c_files) {
# $output->write("@external_names\n"); # $output->write("@external_names\n");
} else { } else {
$documentation_modified = 1; $documentation_modified = 1;
$substitute_line{$line3}{search} = $search; $substitute_line{$line3}{search} = $search;
$substitute_line{$line3}{replace} = $replace; $substitute_line{$line3}{replace} = $replace;
...@@ -345,7 +324,7 @@ foreach my $file (@c_files) { ...@@ -345,7 +324,7 @@ foreach my $file (@c_files) {
} }
if(!$spec_modified && !$documentation_modified && if(!$spec_modified && !$documentation_modified &&
$options->documentation_missing && $documentation) $options->documentation_missing && defined($documentation))
{ {
my $part1; my $part1;
my $part2; my $part2;
...@@ -385,6 +364,8 @@ foreach my $file (@c_files) { ...@@ -385,6 +364,8 @@ foreach my $file (@c_files) {
!$win32api->is_function_stub_in_module($module2, $internal_name)) !$win32api->is_function_stub_in_module($module2, $internal_name))
{ {
if($line3 > 0) { if($line3 > 0) {
$documentation_modified = 1;
$part2 = $external_name2 . " " x (length($part2) - length($external_name2)); $part2 = $external_name2 . " " x (length($part2) - length($external_name2));
$insert_line{$line3} = "$part1$part2$part3\U$module2\E.$ordinal2$part4\n"; $insert_line{$line3} = "$part1$part2$part3\U$module2\E.$ordinal2$part4\n";
} else { } else {
...@@ -395,6 +376,7 @@ foreach my $file (@c_files) { ...@@ -395,6 +376,7 @@ foreach my $file (@c_files) {
} }
if(!$documentation_modified && if(!$documentation_modified &&
defined($documentation) &&
$options->documentation_wrong) $options->documentation_wrong)
{ {
my $line2 = $documentation_line - 1; my $line2 = $documentation_line - 1;
...@@ -418,6 +400,8 @@ foreach my $file (@c_files) { ...@@ -418,6 +400,8 @@ foreach my $file (@c_files) {
} }
if(!$found) { if(!$found) {
if(1) { if(1) {
$documentation_modified = 1;
$delete_line{$line2} = "^\Q$_\E\$"; $delete_line{$line2} = "^\Q$_\E\$";
} else { } else {
$output->write("$external_name (\U$module\E.$ordinal) wrong (fixup not supported)\n"); $output->write("$external_name (\U$module\E.$ordinal) wrong (fixup not supported)\n");
...@@ -427,24 +411,22 @@ foreach my $file (@c_files) { ...@@ -427,24 +411,22 @@ foreach my $file (@c_files) {
} }
} }
if(0) # !$spec_modified && !$documentation if(!$spec_modified && !$documentation_modified && !defined($documentation))
{ {
# FIXME: Not correct my $insert = "";
my $external_name;
my $module;
my $ordinal;
foreach my $winapi (@winapis) { foreach my $winapi (@winapis) {
$external_name = ($winapi->function_external_name($internal_name) || $external_name); my $external_name = $winapi->function_external_name($internal_name);
$module = ($winapi->function_internal_module($internal_name) || $module); my $module = $winapi->function_internal_module($internal_name);
$ordinal = ($winapi->function_internal_ordinal($internal_name) || $ordinal); my $ordinal = $winapi->function_internal_ordinal($internal_name);
if(defined($external_name) || defined($module) || defined($ordinal)) { last; }
}
if(defined($external_name) && defined($module) && defined($ordinal)) { if(defined($external_name) && defined($module) && defined($ordinal)) {
$insert .= " *\t\t$external_name (\U$module\E.$ordinal)\n";
}
}
if($insert) {
$insert_line{$function_line} = $insert_line{$function_line} =
"/" . "*" x 71 . "\n" . "/" . "*" x 71 . "\n" .
" *\t\t$external_name (\U$module\E.$ordinal)\n" . "$insert" .
" */\n"; " */\n";
} }
} }
...@@ -457,7 +439,7 @@ foreach my $file (@c_files) { ...@@ -457,7 +439,7 @@ foreach my $file (@c_files) {
my $argument = shift; my $argument = shift;
}; };
winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor; &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
my $editor = sub { my $editor = sub {
local *IN = shift; local *IN = shift;
...@@ -617,5 +599,3 @@ foreach my $file (@c_files) { ...@@ -617,5 +599,3 @@ foreach my $file (@c_files) {
} }
$output->hide_progress; $output->hide_progress;
package winapi_fixup_options;
use base qw(options);
use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw($options);
use options qw($options &parse_comma_list);
my %options_long = (
"debug" => { default => 0, description => "debug mode" },
"help" => { default => 0, description => "help mode" },
"verbose" => { default => 0, description => "verbose mode" },
"progress" => { default => 1, description => "show progress" },
"win16" => { default => 1, description => "Win16 fixup" },
"win32" => { default => 1, description => "Win32 fixup" },
"local" => { default => 1, description => "local fixup" },
"documentation" => { default => 1, parent => "local", description => "documentation fixup" },
"documentation-missing" => { default => 1, parent => "documentation", description => "documentation missing fixup" },
"documentation-name" => { default => 1, parent => "documentation", description => "documentation name fixup" },
"documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" },
"documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" },
"stub" => { default => 0, parent => "local", description => "stub fixup" },
"global" => { default => 1, description => "global fixup" },
"modify" => { default => 0, description => "actually perform the fixups" },
);
my %options_short = (
"d" => "debug",
"?" => "help",
"v" => "verbose"
);
my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
$options = '_options'->new(\%options_long, \%options_short, $options_usage);
1;
...@@ -26,7 +26,7 @@ use config qw( ...@@ -26,7 +26,7 @@ use config qw(
); );
use modules; use modules;
use nativeapi; use nativeapi;
use output; use output qw($output);
use preprocessor; use preprocessor;
use util qw(&is_subset); use util qw(&is_subset);
use winapi; use winapi;
...@@ -34,21 +34,9 @@ use winapi_documentation; ...@@ -34,21 +34,9 @@ use winapi_documentation;
use winapi_function; use winapi_function;
use winapi_local; use winapi_local;
use winapi_global; use winapi_global;
use winapi_options; use winapi_check_options qw($options);
use winapi_parser; use winapi_parser;
my $output = 'output'->new;
my $options = winapi_options->new($output, \@ARGV, $wine_dir);
if(!defined($options)) {
$output->write("usage: winapi_check [--help] [<files>]\n");
exit 1;
} elsif($options->help) {
$options->show_help;
exit;
}
my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat"); my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat");
my $win16api = 'winapi'->new($options, $output, "win16", "$winapi_check_dir/win16"); my $win16api = 'winapi'->new($options, $output, "win16", "$winapi_check_dir/win16");
...@@ -140,10 +128,12 @@ if($options->headers) { ...@@ -140,10 +128,12 @@ if($options->headers) {
my $found_function = sub { my $found_function = sub {
my $function = shift; my $function = shift;
$output->prefix($function->prefix); $output->prefix_callback(sub { return $function->prefix; });
my $function_line = $function->function_line; my $function_line = $function->function_line;
my $linkage = $function->linkage;
my $internal_name = $function->internal_name; my $internal_name = $function->internal_name;
my $external_name = $function->external_name;
my $statements = $function->statements; my $statements = $function->statements;
if($options->headers_misplaced && if($options->headers_misplaced &&
...@@ -154,7 +144,9 @@ if($options->headers) { ...@@ -154,7 +144,9 @@ if($options->headers) {
$output->write("declaration misplaced\n"); $output->write("declaration misplaced\n");
} }
if(!defined($statements)) { if(defined($external_name) && !defined($statements) &&
($linkage eq "" || $linkage eq "extern"))
{
my $previous_function = $declared_functions{$internal_name}; my $previous_function = $declared_functions{$internal_name};
if(!defined($previous_function)) { if(!defined($previous_function)) {
$declared_functions{$internal_name} = $function; $declared_functions{$internal_name} = $function;
...@@ -171,7 +163,7 @@ if($options->headers) { ...@@ -171,7 +163,7 @@ if($options->headers) {
my $argument = shift; my $argument = shift;
}; };
winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor; &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
} }
} }
...@@ -182,6 +174,8 @@ foreach my $file (@c_files) { ...@@ -182,6 +174,8 @@ foreach my $file (@c_files) {
my %functions = (); my %functions = ();
my %includes = (); my %includes = ();
$includes{$file}++;
my $file_module16 = $modules->allowed_modules_in_file("$current_dir/$file"); my $file_module16 = $modules->allowed_modules_in_file("$current_dir/$file");
my $file_module32 = $modules->allowed_modules_in_file("$current_dir/$file"); my $file_module32 = $modules->allowed_modules_in_file("$current_dir/$file");
...@@ -198,7 +192,7 @@ foreach my $file (@c_files) { ...@@ -198,7 +192,7 @@ foreach my $file (@c_files) {
my $found_function = sub { my $found_function = sub {
my $function = shift; my $function = shift;
$output->prefix($function->prefix); $output->prefix_callback(sub { return $function->prefix; });
my $internal_name = $function->internal_name; my $internal_name = $function->internal_name;
$functions{$internal_name} = $function; $functions{$internal_name} = $function;
...@@ -210,20 +204,44 @@ foreach my $file (@c_files) { ...@@ -210,20 +204,44 @@ foreach my $file (@c_files) {
my $linkage = $function->linkage; my $linkage = $function->linkage;
my $return_type = $function->return_type; my $return_type = $function->return_type;
my $calling_convention = $function->calling_convention; my $calling_convention = $function->calling_convention;
my @argument_types = @{$function->argument_types};
my @argument_names = @{$function->argument_names};
my @argument_documentations = @{$function->argument_documentations};
my $statements = $function->statements; my $statements = $function->statements;
my $module16 = $function->module16; my $module16 = $function->module16;
my $module32 = $function->module32; my $module32 = $function->module32;
my $external_name = $function->external_name;
my $external_name16 = $function->external_name16; my $external_name16 = $function->external_name16;
my $external_name32 = $function->external_name32; my $external_name32 = $function->external_name32;
if(defined($external_name) && !defined($statements) &&
($linkage eq "" || $linkage eq "extern"))
{
my $previous_function = $declared_functions{$internal_name};
if(!defined($previous_function)) {
$declared_functions{$internal_name} = $function;
} else {
my $file = $previous_function->file;
my $function_line = $previous_function->function_line;
my $header = $file;
$header =~ s%^(include|$file_dir)/%%;
if($header !~ m%^msvcrt/% || $file_dir =~ m%^dlls/msvcrt%) {
$output->write("duplicate declaration (first declaration at $file:$function_line)\n");
}
}
}
foreach my $module ($function->modules) { foreach my $module ($function->modules) {
$module2functions{$module}{$internal_name} = $function; $module2functions{$module}{$internal_name} = $function;
for my $type ($return_type, @argument_types) {
my @types = ($return_type);
my $refargument_types = $function->argument_types;
if(defined($refargument_types)) {
push @types, @$refargument_types;
}
for my $type (@types) {
$type_found{$module}{$type}++; $type_found{$module}{$type}++;
} }
} }
...@@ -240,15 +258,35 @@ foreach my $file (@c_files) { ...@@ -240,15 +258,35 @@ foreach my $file (@c_files) {
} }
} }
if($options->headers_needed && defined($declared_function)) { if($options->headers && $options->headers_needed &&
defined($declared_function) && defined($external_name) &&
defined($statements))
{
my $needed_include = $declared_function->file; my $needed_include = $declared_function->file;
if(!defined($includes{$needed_include})) { if(!defined($includes{$needed_include})) {
my $header = $needed_include; my $header = $needed_include;
$header =~ s%^(include|$file_dir)/%%; $header =~ s%^(include|$file_dir)/%%;
if($header !~ m%^msvcrt/% || $file_dir =~ m%^dlls/msvcrt%) {
$output->write("prototype not included: #include \"$header\" is needed\n"); $output->write("prototype not included: #include \"$header\" is needed\n");
} }
} }
}
if($options->local && $options->argument) {
&winapi_local::check_function($function);
}
if($options->local && $options->statements) {
&winapi_local::check_statements(\%functions, $function);
}
if($options->local && $options->documentation &&
(defined($module16) || defined($module32)) &&
$linkage ne "static" && ($linkage ne "" || defined($statements)))
{
&winapi_documentation::check_documentation($function);
}
if(1) { if(1) {
# FIXME: Not correct # FIXME: Not correct
...@@ -316,36 +354,9 @@ foreach my $file (@c_files) { ...@@ -316,36 +354,9 @@ foreach my $file (@c_files) {
} }
} }
} }
if($options->local && $options->argument) {
if($options->win16 && $options->report_module($module16)) {
winapi_local::check_function $options, $output,
$return_type, $calling_convention, $external_name16, $internal_name, [@argument_types], $nativeapi, $win16api;
}
if($options->win32 && $options->report_module($module32)) {
winapi_local::check_function $options, $output,
$return_type, $calling_convention, $external_name32, $internal_name, [@argument_types], $nativeapi, $win32api;
}
} }
if($options->local && $options->statements) {
if($options->win16 && $options->report_module($module16)) {
winapi_local::check_statements $options, $output, $win16api, \%functions, $function;
}
if($options->win32 && $options->report_module($module32)) {
winapi_local::check_statements $options, $output, $win32api, \%functions, $function;
}
}
if($options->local && $options->documentation &&
(defined($module16) || defined($module32)) &&
$linkage ne "static" && ($linkage ne "" || defined($statements)))
{
winapi_documentation::check_documentation $options, $output, $win16api, $win32api, $modules, $function;
}
$output->prefix(""); $output->prefix("");
}
}; };
my $config = 0; my $config = 0;
...@@ -500,7 +511,7 @@ foreach my $file (@c_files) { ...@@ -500,7 +511,7 @@ foreach my $file (@c_files) {
} }
}; };
winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor; &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
if($options->config_unnessary) { if($options->config_unnessary) {
if($config && $conditional == 0) { if($config && $conditional == 0) {
...@@ -508,7 +519,7 @@ foreach my $file (@c_files) { ...@@ -508,7 +519,7 @@ foreach my $file (@c_files) {
} }
} }
winapi_local::check_file $options, $output, $file, \%functions; &winapi_local::check_file($file, \%functions);
} }
$output->hide_progress; $output->hide_progress;
...@@ -565,7 +576,7 @@ if($options->declared) { ...@@ -565,7 +576,7 @@ if($options->declared) {
} }
if($options->global) { if($options->global) {
winapi_documentation::report_documentation $options, $output; &winapi_documentation::report_documentation;
if($options->headers_unused) { if($options->headers_unused) {
foreach my $name (sort(keys(%include2info))) { foreach my $name (sort(keys(%include2info))) {
...@@ -577,8 +588,7 @@ if($options->global) { ...@@ -577,8 +588,7 @@ if($options->global) {
} }
} }
winapi_global::check $options, $output, $win16api, $nativeapi, \%type_found if $options->win16; &winapi_global::check(\%type_found);
winapi_global::check $options, $output, $win32api, $nativeapi, \%type_found if $options->win32;
$modules->global_report; $modules->global_report;
$nativeapi->global_report; $nativeapi->global_report;
......
...@@ -3,7 +3,11 @@ package winapi_documentation; ...@@ -3,7 +3,11 @@ package winapi_documentation;
use strict; use strict;
use config qw($current_dir $wine_dir); use config qw($current_dir $wine_dir);
use modules qw($modules);
use nativeapi qw($nativeapi); use nativeapi qw($nativeapi);
use options qw($options);
use output qw($output);
use winapi qw($win16api $win32api @winapis);
my %comment_width; my %comment_width;
my %comment_indent; my %comment_indent;
...@@ -12,11 +16,6 @@ my %comment_spacing; ...@@ -12,11 +16,6 @@ my %comment_spacing;
sub check_documentation { sub check_documentation {
local $_; local $_;
my $options = shift;
my $output = shift;
my $win16api = shift;
my $win32api = shift;
my $modules = shift;
my $function = shift; my $function = shift;
my $file = $function->file; my $file = $function->file;
...@@ -29,7 +28,6 @@ sub check_documentation { ...@@ -29,7 +28,6 @@ sub check_documentation {
my $ordinal32 = $function->ordinal32; my $ordinal32 = $function->ordinal32;
my $documentation = $function->documentation; my $documentation = $function->documentation;
my $documentation_line = $function->documentation_line; my $documentation_line = $function->documentation_line;
my @argument_documentations = @{$function->argument_documentations};
my $documentation_error = 0; my $documentation_error = 0;
my $documentation_warning = 0; my $documentation_warning = 0;
...@@ -159,8 +157,11 @@ sub check_documentation { ...@@ -159,8 +157,11 @@ sub check_documentation {
} }
if($options->documentation_arguments) { if($options->documentation_arguments) {
my $refargument_documentations = $function->argument_documentations;
if(defined($refargument_documentations)) {
my $n = 0; my $n = 0;
for my $argument_documentation (@argument_documentations) { for my $argument_documentation (@$refargument_documentations) {
$n++; $n++;
if($argument_documentation ne "") { if($argument_documentation ne "") {
if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) { if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) {
...@@ -169,12 +170,10 @@ sub check_documentation { ...@@ -169,12 +170,10 @@ sub check_documentation {
} }
} }
} }
}
} }
sub report_documentation { sub report_documentation {
my $options = shift;
my $output = shift;
if($options->documentation_comment_indent) { if($options->documentation_comment_indent) {
foreach my $indent (sort(keys(%comment_indent))) { foreach my $indent (sort(keys(%comment_indent))) {
my $count = $comment_indent{$indent}; my $count = $comment_indent{$indent};
......
...@@ -74,13 +74,27 @@ sub _external_names { ...@@ -74,13 +74,27 @@ sub _external_names {
} }
} }
sub external_name {
my $self = shift;
foreach my $winapi (@winapis) {
my $external_name = $self->_external_name($winapi, @_);
if(defined($external_name)) {
return $external_name;
}
}
return undef;
}
sub external_name16 { my $self = shift; return $self->_external_name($win16api, @_); } sub external_name16 { my $self = shift; return $self->_external_name($win16api, @_); }
sub external_name32 { my $self = shift; return $self->_external_name($win32api, @_); } sub external_name32 { my $self = shift; return $self->_external_name($win32api, @_); }
sub external_names16 { my $self = shift; return $self->_external_names($win16api, @_); } sub external_names16 { my $self = shift; return $self->_external_names($win16api, @_); }
sub external_names32 { my $self = shift; return $self->_external_names($win32api, @_); } sub external_names32 { my $self = shift; return $self->_external_names($win32api, @_); }
sub external_names { my $self = shift; return ($self->external_names16,$self->external_names32); } sub external_names { my $self = shift; return ($self->external_names16, $self->external_names32); }
######################################################################## ########################################################################
# module # module
...@@ -201,11 +215,15 @@ sub prefix { ...@@ -201,11 +215,15 @@ sub prefix {
my $return_type = $self->return_type; my $return_type = $self->return_type;
my $internal_name = $self->internal_name; my $internal_name = $self->internal_name;
my $calling_convention = $self->calling_convention; my $calling_convention = $self->calling_convention;
my @argument_types = @{$self->argument_types};
my $refargument_types = $self->argument_types;
my @argument_types = ();
if(defined($refargument_types)) {
@argument_types = @$refargument_types;
if($#argument_types < 0) { if($#argument_types < 0) {
@argument_types = ("void"); @argument_types = ("void");
} }
}
my $prefix = ""; my $prefix = "";
...@@ -326,10 +344,14 @@ sub return_kind32 { ...@@ -326,10 +344,14 @@ sub return_kind32 {
sub _argument_kinds { sub _argument_kinds {
my $self = shift; my $self = shift;
my $winapi = shift; my $winapi = shift;
my @argument_types = @{$self->argument_types}; my $refargument_types = $self->argument_types;
if(!defined($refargument_types)) {
return undef;
}
my @argument_kinds; my @argument_kinds;
foreach my $argument_type (@argument_types) { foreach my $argument_type (@$refargument_types) {
my $argument_kind = $winapi->translate_argument($argument_type); my $argument_kind = $winapi->translate_argument($argument_type);
if(defined($argument_kind) && $argument_kind eq "longlong") { if(defined($argument_kind) && $argument_kind eq "longlong") {
......
...@@ -2,11 +2,25 @@ package winapi_global; ...@@ -2,11 +2,25 @@ package winapi_global;
use strict; use strict;
use nativeapi qw($nativeapi);
use options qw($options);
use output qw($output);
use winapi qw($win16api $win32api @winapis);
sub check { sub check {
my $options = shift; my $type_found = shift;
my $output = shift;
if($options->win16) {
_check($win16api, $type_found);
}
if($options->win32) {
_check($win32api, $type_found);
}
}
sub _check {
my $winapi = shift; my $winapi = shift;
my $nativeapi = shift;
my $type_found = shift; my $type_found = shift;
my $winver = $winapi->name; my $winver = $winapi->name;
......
...@@ -2,16 +2,51 @@ package winapi_local; ...@@ -2,16 +2,51 @@ package winapi_local;
use strict; use strict;
use nativeapi qw($nativeapi);
use options qw($options);
use output qw($output);
use winapi qw($win16api $win32api @winapis);
sub check_function { sub check_function {
my $options = shift; my $function = shift;
my $output = shift;
my $return_type = $function->return_type;
my $calling_convention = $function->calling_convention;
my $calling_convention16 = $function->calling_convention16;
my $calling_convention32 = $function->calling_convention32;
my $internal_name = $function->internal_name;
my $external_name16 = $function->external_name16;
my $external_name32 = $function->external_name32;
my $module16 = $function->module16;
my $module32 = $function->module32;
my $refargument_types = $function->argument_types;
if(!defined($refargument_types)) {
return;
}
if($options->win16 && $options->report_module($module16)) {
_check_function($return_type,
$calling_convention, $external_name16,
$internal_name, $refargument_types,
$win16api);
}
if($options->win32 && $options->report_module($module32)) {
_check_function($return_type,
$calling_convention, $external_name32,
$internal_name, $refargument_types,
$win32api);
}
}
sub _check_function {
my $return_type = shift; my $return_type = shift;
my $calling_convention = shift; my $calling_convention = shift;
my $external_name = shift; my $external_name = shift;
my $internal_name = shift; my $internal_name = shift;
my $refargument_types = shift; my $refargument_types = shift;
my @argument_types = @$refargument_types; my @argument_types = @$refargument_types;
my $nativeapi = shift;
my $winapi = shift; my $winapi = shift;
my $module = $winapi->function_internal_module($internal_name); my $module = $winapi->function_internal_module($internal_name);
...@@ -212,8 +247,22 @@ sub check_function { ...@@ -212,8 +247,22 @@ sub check_function {
} }
sub check_statements { sub check_statements {
my $options = shift; my $functions = shift;
my $output = shift; my $function = shift;
my $module16 = $function->module16;
my $module32 = $function->module32;
if($options->win16 && $options->report_module($module16)) {
_check_statements($win16api, $functions, $function);
}
if($options->win32 && $options->report_module($module32)) {
_check_statements($win16api, $functions, $function);
}
}
sub _check_statements {
my $winapi = shift; my $winapi = shift;
my $functions = shift; my $functions = shift;
my $function = shift; my $function = shift;
...@@ -288,8 +337,6 @@ sub check_statements { ...@@ -288,8 +337,6 @@ sub check_statements {
} }
sub check_file { sub check_file {
my $options = shift;
my $output = shift;
my $file = shift; my $file = shift;
my $functions = shift; my $functions = shift;
......
...@@ -2,6 +2,18 @@ package winapi_options; ...@@ -2,6 +2,18 @@ package winapi_options;
use strict; use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(&parse_comma_list);
@EXPORT_OK = qw($options);
use vars qw($options);
use config qw($current_dir $wine_dir);
use output qw($output);
sub parser_comma_list { sub parser_comma_list {
my $prefix = shift; my $prefix = shift;
my $value = shift; my $value = shift;
...@@ -138,12 +150,6 @@ sub new { ...@@ -138,12 +150,6 @@ sub new {
my $self = {}; my $self = {};
bless ($self, $class); bless ($self, $class);
my $output = \${$self->{OUTPUT}};
$$output = shift;
my $refarguments = shift;
my $wine_dir = shift;
$self->options_set("default"); $self->options_set("default");
my $c_files = \@{$self->{C_FILES}}; my $c_files = \@{$self->{C_FILES}};
...@@ -160,7 +166,7 @@ sub new { ...@@ -160,7 +166,7 @@ sub new {
$$global = 0; $$global = 0;
} }
while(defined($_ = shift @$refarguments)) { while(defined($_ = shift @ARGV)) {
if(/^--(all|none)$/) { if(/^--(all|none)$/) {
$self->options_set("$1"); $self->options_set("$1");
next; next;
...@@ -185,7 +191,7 @@ sub new { ...@@ -185,7 +191,7 @@ sub new {
$name = $1; $name = $1;
$prefix = "no"; $prefix = "no";
if(defined($value)) { if(defined($value)) {
$$output->write("options with prefix 'no' can't take parameters\n"); $output->write("options with prefix 'no' can't take parameters\n");
return undef; return undef;
} }
...@@ -258,12 +264,12 @@ sub new { ...@@ -258,12 +264,12 @@ sub new {
$$module = { active => 1, filter => 1, hash => \%names }; $$module = { active => 1, filter => 1, hash => \%names };
} }
elsif(/^-(.*)$/) { elsif(/^-(.*)$/) {
$$output->write("unknown option: $_\n"); $output->write("unknown option: $_\n");
return undef; return undef;
} else { } else {
if(!-e $_) { if(!-e $_) {
$$output->write("$_: no such file or directory\n"); $output->write("$_: no such file or directory\n");
return undef; return undef;
} }
...@@ -329,6 +335,9 @@ sub new { ...@@ -329,6 +335,9 @@ sub new {
} }
} split(/\n/, `$h_command`)); } split(/\n/, `$h_command`));
} }
$options = $self;
return $self; return $self;
} }
......
...@@ -2,11 +2,11 @@ package winapi_parser; ...@@ -2,11 +2,11 @@ package winapi_parser;
use strict; use strict;
use output qw($output);
use winapi_function; use winapi_function;
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;
...@@ -39,13 +39,17 @@ sub parse_c_file { ...@@ -39,13 +39,17 @@ sub parse_c_file {
$argument_names = shift; $argument_names = shift;
$argument_documentations = shift; $argument_documentations = shift;
if($#$argument_names == -1) { if(defined($argument_names) && defined($argument_types) &&
$#$argument_names == -1)
{
foreach my $n (0..$#$argument_types) { foreach my $n (0..$#$argument_types) {
push @$argument_names, ""; push @$argument_names, "";
} }
} }
if($#$argument_documentations == -1) { if(defined($argument_documentations) &&
$#$argument_documentations == -1)
{
foreach my $n (0..$#$argument_documentations) { foreach my $n (0..$#$argument_documentations) {
push @$argument_documentations, ""; push @$argument_documentations, "";
} }
...@@ -69,9 +73,15 @@ sub parse_c_file { ...@@ -69,9 +73,15 @@ sub parse_c_file {
$function->return_type($return_type); $function->return_type($return_type);
$function->calling_convention($calling_convention); $function->calling_convention($calling_convention);
$function->internal_name($internal_name); $function->internal_name($internal_name);
if(defined($argument_types)) {
$function->argument_types([@$argument_types]); $function->argument_types([@$argument_types]);
}
if(defined($argument_names)) {
$function->argument_names([@$argument_names]); $function->argument_names([@$argument_names]);
}
if(defined($argument_documentations)) {
$function->argument_documentations([@$argument_documentations]); $function->argument_documentations([@$argument_documentations]);
}
$function->statements($statements); $function->statements($statements);
&$function_found_callback($function); &$function_found_callback($function);
...@@ -351,53 +361,89 @@ sub parse_c_file { ...@@ -351,53 +361,89 @@ sub parse_c_file {
&$function_end; &$function_end;
} }
} elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) { } elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) {
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments = ();
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "void", "__asm", $1, \@arguments); $function_line, "", "void", "__asm", $1);
$statements = "";
&$function_end; &$function_end;
} elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/DC_(GET_X_Y_16|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s){
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $again = 1; $_ = $'; $again = 1;
my $return16 = $2 . "16";
my $name16 = $3 . "16";
$return16 =~ s/^(COLORREF|DWORD)16$/$1/;
my @arguments = ("HDC16"); my @arguments = ("HDC16");
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", $2, "WINAPI", $3, \@arguments); $function_line, "", $return16, "WINAPI", $name16, \@arguments);
$statements = "";
&$function_end; &$function_end;
} elsif(/DC_(GET_VAL)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) { } elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $again = 1; $_ = $'; $again = 1;
my $return16 = $3 . "16";
my $return32 = $3;
my $name16 = $2 . "16";
my $name32 = $2;
my @arguments16 = ("HDC16");
my @arguments32 = ("HDC");
if($name16 eq "COLORREF16") { $name16 = "COLORREF"; } my $return32 = $2;
my $name32 = $3;
my @arguments32 = ("HDC");
&$function_begin($documentation_line, $documentation,
$function_line, "", $name16, "WINAPI", $return16, \@arguments16);
&$function_end; &$function_end;
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", $name32, "WINAPI", $return32, \@arguments32); $function_line, "", $return32, "WINAPI", $name32, \@arguments32);
$statements = "";
&$function_end; &$function_end;
} elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/DC_(GET_VAL_EX_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments16 = ("HDC16", "LP" . $5 . "16"); my @arguments16 = ("HDC16", "LP" . $5 . "16");
my @arguments32 = ("HDC", "LP" . $5);
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "BOOL16", "WINAPI", $2 . "16", \@arguments16); $function_line, "", "BOOL16", "WINAPI", $2 . "16", \@arguments16);
$statements = "";
&$function_end; &$function_end;
} elsif(/DC_(GET_VAL_EX_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $again = 1;
my @arguments32 = ("HDC", "LP" . $5);
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "BOOL", "WINAPI", $2, \@arguments32); $function_line, "", "BOOL", "WINAPI", $2, \@arguments32);
$statements = "";
&$function_end; &$function_end;
} elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/DC_(SET_MODE_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments16 = ("HDC16", "INT16"); my @arguments16 = ("HDC16", "INT16");
my @arguments32 = ("HDC", "INT");
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "INT16", "WINAPI", $2 . "16", \@arguments16); $function_line, "", "INT16", "WINAPI", $2 . "16", \@arguments16);
$statements = "";
&$function_end; &$function_end;
} elsif(/DC_(SET_MODE_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $again = 1;
my @arguments32 = ("HDC", "INT");
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "INT", "WINAPI", $2, \@arguments32); $function_line, "", "INT", "WINAPI", $2, \@arguments32);
$statements = "";
&$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;
...@@ -405,27 +451,39 @@ sub parse_c_file { ...@@ -405,27 +451,39 @@ sub parse_c_file {
my @arguments32 = ("HWAVEIN"); my @arguments32 = ("HWAVEIN");
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16); $function_line, "", "UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
$statements = "";
&$function_end; &$function_end;
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "UINT", "WINAPI", "waveIn" . $1, \@arguments32); $function_line, "", "UINT", "WINAPI", "waveIn" . $1, \@arguments32);
$statements = "";
&$function_end; &$function_end;
} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) { } elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $again = 1; $_ = $'; $again = 1;
my @arguments16 = ("HWAVEOUT16"); my @arguments16 = ("HWAVEOUT16");
my @arguments32 = ("HWAVEOUT"); my @arguments32 = ("HWAVEOUT");
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16); $function_line, "", "UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
$statements = "";
&$function_end; &$function_end;
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "UINT", "WINAPI", "waveOut" . $1, \@arguments32); $function_line, "", "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) {
my @lines = split(/\n/, $&);
my $function_line = $. - scalar(@lines) + 1;
$_ = $'; $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($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16); $function_line, "", "UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
$statements = "";
&$function_end; &$function_end;
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32); $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
...@@ -435,6 +493,7 @@ sub parse_c_file { ...@@ -435,6 +493,7 @@ sub parse_c_file {
my @arguments32 = ("UINT", $4); my @arguments32 = ("UINT", $4);
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16); $function_line, "", "UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
$statements = "";
&$function_end; &$function_end;
&$function_begin($documentation_line, $documentation, &$function_begin($documentation_line, $documentation,
$function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32); $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
......
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