Commit 67f0a70c authored by Patrik Stridvall's avatar Patrik Stridvall Committed by Alexandre Julliard

- A few more bug fixes

- Reorganization continues - New tool (make_filter) for filtering make output added
parent 9a57ef4d
......@@ -10,9 +10,10 @@ require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(
&file_absolutize &file_normalize
&file_directory
&file_type &files_filter
&file_skip &files_skip
&get_c_files &get_h_files &get_spec_files
&file_skip &files_skip
&get_api_files &get_c_files &get_h_files &get_spec_files
);
@EXPORT_OK = qw(
$current_dir $wine_dir $winapi_dir $winapi_check_dir
......@@ -22,6 +23,8 @@ use vars qw($current_dir $wine_dir $winapi_dir $winapi_check_dir);
use output qw($output);
use File::Find;
sub file_type {
local $_ = shift;
......@@ -30,7 +33,7 @@ sub file_type {
m%^(?:libtest|rc|server|tests|tools)/% && return "";
m%^(?:programs|debugger|miscemu)/% && return "wineapp";
m%^(?:library|tsx11|unicode)/% && return "library";
m%^windows/x11drv/wineclipsrv.c% && return "application";
m%^windows/x11drv/wineclipsrv\.c$% && return "application";
return "winelib";
}
......@@ -56,8 +59,9 @@ sub file_skip {
m%^(?:libtest|programs|rc|server|tests|tools)/% && return 1;
m%^(?:debugger|miscemu|tsx11|server|unicode)/% && return 1;
m%^dlls/wineps/data/% && return 1;
m%^windows/x11drv/wineclipsrv.c% && return 1;
m%^dlls/winmm/wineoss/midipatch.c% && return 1;
m%^windows/x11drv/wineclipsrv\.c$% && return 1;
m%^dlls/winmm/wineoss/midipatch\.c$% && return 1;
m%(?:glue|spec)\.c$% && return 1;
return 0;
}
......@@ -98,25 +102,57 @@ sub file_normalize {
return $_;
}
sub file_directory {
my $file = shift;
$file =~ s%^./%%;
my $dir = $file;
$dir =~ s%/?[^/]*$%%;
if(!$dir) {
$dir = ".";
}
return $dir;
}
sub _get_files {
my $extension = shift;
my $type = shift;
my $dir = shift;
$output->progress("$wine_dir: searching for *.$extension");
my @files = map {
s%^\./%%;
s%^$wine_dir/%%;
if(file_type($_) eq $type) {
$_;
} else {
();
if(!defined($dir)) {
$dir = $wine_dir;
}
my @files;
my @dirs = ($dir);
while(defined(my $dir = shift @dirs)) {
opendir(DIR, $dir);
my @entries= readdir(DIR);
closedir(DIR);
foreach (@entries) {
$_ = "$dir/$_";
if(/\.\.?$/) {
# Nothing
} elsif(-d $_) {
push @dirs, $_;
} elsif(/\.$extension$/ && (!defined($type) || file_type($_) eq $type)) {
s%^$wine_dir/%%;
push @files, $_;
}
}
} split(/\n/, `find $wine_dir -name \\*.$extension`);
}
return @files;
}
sub get_api_files {
my $name = shift;
return _get_files("api", undef, "$winapi_check_dir/$name");
}
sub get_c_files { return _get_files("c", @_); }
sub get_h_files { return _get_files("h", @_); }
sub get_spec_files { return _get_files("spec", @_); }
......
#! /usr/bin/perl -w
use strict;
BEGIN {
$0 =~ m%^(.*?/?tools)/winapi/make_filter$%;
require "$1/winapi/setup.pm";
}
use config qw($current_dir $wine_dir);
use output qw($output);
use make_filter_options qw($options);
use make_parser;
if($options->progress) {
$output->enable_progress;
} else {
$output->disable_progress;
}
########################################################################
# main
########################################################################
my $command = join(" ", $options->arguments);
open(IN, "($command) 2>&1 |");
while(<IN>) {
chomp;
if(!&make_parser::line($_)) {
next;
}
my $directory = &make_parser::directory();
my $file = &make_parser::file_name();
my $line = &make_parser::file_line();
my $message = &make_parser::message();
if(&make_parser::tool() eq "make") {
if($directory && $directory ne ".") {
$output->progress("$directory: make");
}
} elsif($message) {
if($file && $line) {
if($directory) {
$output->write("$directory/$file:$line: $message\n");
} else {
$output->write("$file:$line: $message\n");
}
} elsif($file) {
if($directory) {
$output->write("$directory/$file: $message\n");
} else {
$output->write("$file: $message\n");
}
} else {
if($directory) {
$output->write("$directory: " . &make_parser::tool() . ": $message\n");
} else {
$output->write(".: " . &make_parser::tool() . ": $message\n");
}
}
}
}
close(IN);
$output->hide_progress();
package make_filter_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" },
"pedantic" => { default => 0, description => "be pedantic" },
);
my %options_short = (
"d" => "debug",
"?" => "help",
"v" => "verbose"
);
my $options_usage = "usage: make_filter [--help]\n";
$options = '_options'->new(\%options_long, \%options_short, $options_usage);
1;
......@@ -40,9 +40,9 @@ sub new {
my $self = {};
bless ($self, $class);
my $options_long = \%{$self->{OPTIONS_LONG}};
my $options_short = \%{$self->{OPTIONS_SHORT}};
my $options_usage = \${$self->{OPTIONS_USAGE}};
my $options_long = \%{$self->{_OPTIONS_LONG}};
my $options_short = \%{$self->{_OPTIONS_SHORT}};
my $options_usage = \${$self->{_OPTIONS_USAGE}};
my $refoptions_long = shift;
my $refoptions_short = shift;
......@@ -53,12 +53,16 @@ sub new {
$self->options_set("default");
my $c_files = \@{$self->{C_FILES}};
my $h_files = \@{$self->{H_FILES}};
my @files;
my $arguments = \@{$self->{_ARGUMENTS}};
my $end_of_options = 0;
while(defined($_ = shift @ARGV)) {
if(/^--(all|none)$/) {
if(/^--$/) {
$end_of_options = 1;
next;
} elsif($end_of_options) {
# Nothing
} elsif(/^--(all|none)$/) {
$self->options_set("$1");
next;
} elsif(/^-([^=]*)(=(.*))?$/) {
......@@ -143,17 +147,12 @@ sub new {
}
}
if(/^-(.*)$/) {
if(!$end_of_options && /^-(.*)$/) {
$output->write("unknown option: $_\n");
$output->write($$options_usage);
exit 1;
} else {
if(!-e $_) {
$output->write("$_: no such file or directory\n");
exit 1;
}
push @files, $_;
push @$arguments, $_;
}
}
......@@ -163,6 +162,33 @@ sub new {
exit 0;
}
return $self;
}
sub DESTROY {
}
sub parse_files {
my $self = shift;
my $arguments = \@{$self->{_ARGUMENTS}};
my $c_files = \@{$self->{_C_FILES}};
my $h_files = \@{$self->{_H_FILES}};
my $error = 0;
my @files = ();
foreach (@$arguments) {
if(!-e $_) {
$output->write("$_: no such file or directory\n");
$error = 1;
} else {
push @files, $_;
}
}
if($error) {
exit 1;
}
my @paths = ();
my @c_files = ();
my @h_files = ();
......@@ -186,7 +212,7 @@ sub new {
my %found;
@$c_files = sort(map {
s/^\.\/(.*)$/$1/;
if(defined($found{$_}) || /glue\.c|spec\.c$/) {
if(defined($found{$_})) {
();
} else {
$found{$_}++;
......@@ -209,18 +235,13 @@ sub new {
}
} split(/\n/, `$h_command`));
}
return $self;
}
sub DESTROY {
}
sub options_set {
my $self = shift;
my $options_long = \%{$self->{OPTIONS_LONG}};
my $options_short = \%{$self->{OPTIONS_SHORT}};
my $options_long = \%{$self->{_OPTIONS_LONG}};
my $options_short = \%{$self->{_OPTIONS_SHORT}};
local $_ = shift;
for my $name (sort(keys(%$options_long))) {
......@@ -255,8 +276,8 @@ sub options_set {
sub show_help {
my $self = shift;
my $options_long = \%{$self->{OPTIONS_LONG}};
my $options_short = \%{$self->{OPTIONS_SHORT}};
my $options_long = \%{$self->{_OPTIONS_LONG}};
my $options_short = \%{$self->{_OPTIONS_SHORT}};
my $maxname = 0;
for my $name (sort(keys(%$options_long))) {
......@@ -329,8 +350,36 @@ sub AUTOLOAD {
}
}
sub c_files { my $self = shift; return @{$self->{C_FILES}}; }
sub arguments {
my $self = shift;
my $arguments = \@{$self->{_ARGUMENTS}};
return @$arguments;
}
sub c_files {
my $self = shift;
my $c_files = \@{$self->{_C_FILES}};
if(!defined(@$c_files)) {
$self->parse_files;
}
return @$c_files;
}
sub h_files {
my $self = shift;
my $h_files = \@{$self->{_H_FILES}};
sub h_files { my $self = shift; return @{$self->{H_FILES}}; }
if(!defined(@$h_files)) {
$self->parse_files;
}
return @$h_files;
}
1;
......@@ -26,6 +26,7 @@ sub new {
my $self = {};
bless ($self, $class);
my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
my $last_time = \${$self->{LAST_TIME}};
......@@ -33,6 +34,7 @@ sub new {
my $prefix = \${$self->{PREFIX}};
my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
$$progress_enabled = 1;
$$progress = "";
$$last_progress = "";
$$last_time = 0;
......@@ -43,62 +45,91 @@ sub new {
return $self;
}
sub DESTROY {
my $self = shift;
$self->hide_progress;
}
sub enable_progress {
my $self = shift;
my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
$$progress_enabled = 1;
}
sub disable_progress {
my $self = shift;
my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
$$progress_enabled = 0;
}
sub show_progress {
my $self = shift;
my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
my $progress_count = \${$self->{PROGRESS_COUNT}};
$$progress_count++;
if($$progress_count > 0 && $$progress && $stderr_isatty) {
print STDERR $$progress;
$$last_progress = $$progress;
if($$progress_enabled) {
if($$progress_count > 0 && $$progress && $stderr_isatty) {
print STDERR $$progress;
$$last_progress = $$progress;
}
}
}
sub hide_progress {
my $self = shift;
my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
my $progress_count = \${$self->{PROGRESS_COUNT}};
$$progress_count--;
if($$last_progress && $stderr_isatty) {
my $message;
for (1..length($$last_progress)) {
$message .= " ";
if($$progress_enabled) {
if($$last_progress && $stderr_isatty) {
my $message;
for (1..length($$last_progress)) {
$message .= " ";
}
print STDERR $message;
undef $$last_progress;
}
print STDERR $message;
undef $$last_progress;
}
}
sub update_progress {
my $self = shift;
my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
my $prefix = "";
my $suffix = "";
if($$last_progress) {
for (1..length($$last_progress)) {
$prefix .= "";
}
my $diff = length($$last_progress)-length($$progress);
if($diff > 0) {
for (1..$diff) {
$suffix .= " ";
if($$progress_enabled) {
my $prefix = "";
my $suffix = "";
if($$last_progress) {
for (1..length($$last_progress)) {
$prefix .= "";
}
for (1..$diff) {
$suffix .= "";
my $diff = length($$last_progress)-length($$progress);
if($diff > 0) {
for (1..$diff) {
$suffix .= " ";
}
for (1..$diff) {
$suffix .= "";
}
}
}
print STDERR $prefix . $$progress . $suffix;
$$last_progress = $$progress;
}
print STDERR $prefix . $$progress . $suffix;
$$last_progress = $$progress;
}
sub progress {
......
package type;
use strict;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless ($self, $class);
return $self;
}
1;
......@@ -127,16 +127,10 @@ my %options_short = (
"v" => "verbose"
);
my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
my $options_usage = "usage: winapi_check [--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);
......
......@@ -13,18 +13,18 @@ use config qw(
&file_type &files_skip &files_filter &get_spec_files
$current_dir $wine_dir $winapi_dir $winapi_check_dir
);
use modules;
use nativeapi;
use output qw($output);
use options;
use winapi;
use winapi_extract_options qw($options);
use function;
use type;
use winapi_function;
use winapi_parser;
use winapi_extract_options qw($options);
use winapi qw(@winapis);
my %module2spec_file;
my %module2type;
{
if($options->spec_files) {
local $_;
foreach my $spec_file (get_spec_files("winelib")) {
......@@ -49,22 +49,6 @@ my %module2type;
}
}
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 $win32api = 'winapi'->new($options, $output, "win32", "$winapi_check_dir/win32");
my @winapis = ($win16api, $win32api);
if($wine_dir eq ".") {
'winapi'->read_all_spec_files($modules, $wine_dir, $current_dir, \&file_type, $win16api, $win32api);
} else {
my @spec_files = $modules->allowed_spec_files($wine_dir, $current_dir);
'winapi'->read_spec_files($modules, $wine_dir, $current_dir, \@spec_files, $win16api, $win32api);
}
my $nativeapi = 'nativeapi'->new($options, $output, "$winapi_check_dir/nativeapi.dat",
"$wine_dir/configure.in", "$wine_dir/include/config.h.in");
my %specifications;
sub documentation_specifications {
......@@ -164,6 +148,14 @@ foreach my $file (@c_files) {
$output->progress("$file: file $progress_current of $progress_max");
}
my $create_function = sub {
if($options->stub_statistics) {
return 'winapi_function'->new;
} else {
return 'function'->new;
}
};
my $found_function = sub {
my $function = shift;
......@@ -191,12 +183,20 @@ foreach my $file (@c_files) {
$output->prefix("");
};
my $create_type = sub {
return 'type'->new;
};
my $found_type = sub {
my $type = shift;
};
my $found_preprocessor = sub {
my $directive = shift;
my $argument = shift;
};
&winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
&winapi_parser::parse_c_file($file, $create_function, $found_function, $create_type, $found_type, $found_preprocessor);
my @internal_names = keys(%functions);
if($#internal_names < 0) {
......@@ -342,7 +342,7 @@ if($options->stub_statistics) {
foreach my $internal_name ($winapi->all_internal_functions,$winapi->all_functions_stub) {
foreach my $module (split(/ \& /, $winapi->function_internal_module($internal_name))) {
if($winapi->function_stub($internal_name)) {
if($winapi->is_function_stub_in_module($module, $internal_name)) {
$module_stub_count{$module}++;
}
$module_total_count{$module}++;
......@@ -372,4 +372,3 @@ if($options->stub_statistics) {
}
}
$output->hide_progress;
......@@ -26,7 +26,7 @@ my %options_long = (
"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" },
"stub-statistics" => { default => 1, parent => "global", description => "stub statistics" },
);
my %options_short = (
......
......@@ -17,24 +17,14 @@ use config qw(
$current_dir $wine_dir $winapi_dir $winapi_check_dir
);
use output qw($output);
use modules;
use util;
use winapi;
use winapi_parser;
use winapi_fixup_options qw($options);
use modules qw($modules);
use winapi qw($win16api $win32api @winapis);
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 $win32api = 'winapi'->new($options, $output, "win32", "$winapi_check_dir/win32");
my @winapis = ($win16api, $win32api);
if($wine_dir eq ".") {
'winapi'->read_all_spec_files($modules, $wine_dir, $current_dir, \&file_type, $win16api, $win32api);
} else {
my @spec_files = $modules->allowed_spec_files($wine_dir, $current_dir);
'winapi'->read_spec_files($modules, $wine_dir, $current_dir, \@spec_files, $win16api, $win32api);
}
use type;
use util;
use winapi_function;
use winapi_parser;
my @c_files = $options->c_files;
@c_files = files_skip(@c_files);
......@@ -58,6 +48,10 @@ foreach my $file (@c_files) {
my %documentation_line_used;
my $create_function = sub {
return 'winapi_function'->new;
};
my $found_function = sub {
my $function = shift;
......@@ -434,12 +428,21 @@ foreach my $file (@c_files) {
$output->prefix("");
};
my $create_type = sub {
return 'type'->new;
};
my $found_type = sub {
my $type = shift;
};
my $found_preprocessor = sub {
my $directive = shift;
my $argument = shift;
};
&winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
&winapi_parser::parse_c_file($file, $create_function, $found_function, $create_type, $found_type, $found_preprocessor);
my $editor = sub {
local *IN = shift;
......@@ -598,4 +601,3 @@ foreach my $file (@c_files) {
}
}
$output->hide_progress;
......@@ -344,7 +344,6 @@ dlls/user
% dlls/user/user.spec
controls
dlls/kernel
dlls/user
misc
windows
......
......@@ -11,30 +11,33 @@ require Exporter;
use vars qw($modules);
use config qw(
&file_type &files_skip
&file_directory
&get_c_files
$current_dir $wine_dir
$winapi_check_dir
);
use options qw($options);
use output qw($output);
$modules = 'modules'->new;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless ($self, $class);
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
$$options = shift;
$$output = shift;
my $wine_dir = shift;
my $current_dir = shift;
my $file_type = shift;
my $module_file = shift;
$module_file =~ s/^\.\///;
my $module_file = "$winapi_check_dir/modules.dat";
my @all_spec_files = map {
s/^.\/(.*)$/$1/;
if(&$file_type($_) eq "winelib") {
if(file_type($_) eq "winelib") {
$_;
} else {
();
......@@ -46,8 +49,8 @@ sub new {
$all_spec_files{$file}++ ;
}
if($$options->progress) {
$$output->progress("modules.dat");
if($options->progress) {
$output->progress("modules.dat");
}
my $allowed_dir;
......@@ -64,7 +67,7 @@ sub new {
$spec_file = $1;
if(!-f "$wine_dir/$spec_file") {
$$output->write("modules.dat: $spec_file: file ($spec_file) doesn't exist or is no file\n");
$output->write("modules.dat: $spec_file: file ($spec_file) doesn't exist or is no file\n");
}
if($wine_dir eq ".") {
......@@ -81,14 +84,14 @@ sub new {
$$dir2spec_file{$allowed_dir}{$spec_file}++;
if(!-d "$wine_dir/$allowed_dir") {
$$output->write("modules.dat: $spec_file: directory ($allowed_dir) doesn't exist or is no directory\n");
$output->write("modules.dat: $spec_file: directory ($allowed_dir) doesn't exist or is no directory\n");
}
}
close(IN);
foreach my $spec_file (sort(keys(%all_spec_files))) {
if($all_spec_files{$spec_file} > 0) {
$$output->write("modules.dat: $spec_file: exists but is not specified\n");
$output->write("modules.dat: $spec_file: exists but is not specified\n");
}
}
......@@ -105,6 +108,44 @@ sub all_modules {
return sort(keys(%$module2spec_file));
}
sub complete_modules {
my $self = shift;
my $c_files = shift;
my %dirs;
foreach my $file (@$c_files) {
my $dir = file_directory("$current_dir/$file");
$dirs{$dir}++;
}
my @c_files = get_c_files("winelib");
@c_files = files_skip(@c_files);
foreach my $file (@c_files) {
my $dir = file_directory($file);
if(exists($dirs{$dir})) {
$dirs{$dir}--;
}
}
my @complete_modules = ();
foreach my $module ($self->all_modules) {
my $index = -1;
my @dirs = $self->allowed_dirs_for_module($module);
foreach my $dir (@dirs) {
if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
$index++;
}
}
if($index == $#dirs) {
push @complete_modules, $module;
}
}
return @complete_modules;
}
sub spec_file_module {
my $self = shift;
......@@ -183,13 +224,8 @@ sub allowed_dirs_for_module {
sub allowed_spec_files {
my $self = shift;
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
my $wine_dir = shift;
my $current_dir = shift;
my @dirs = map {
s/^\.\/(.*)$/$1/;
if(/^\.$/) {
......@@ -227,7 +263,6 @@ sub found_module_in_dir {
sub global_report {
my $self = shift;
my $output = \${$self->{OUTPUT}};
my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
......@@ -244,7 +279,7 @@ sub global_report {
}
foreach my $message (sort(@messages)) {
$$output->write($message);
$output->write($message);
}
}
......
......@@ -11,31 +11,33 @@ require Exporter;
use vars qw($nativeapi);
use config qw(&file_type $current_dir $wine_dir $winapi_check_dir);
use options qw($options);
use output qw($output);
$nativeapi = 'nativeapi'->new;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless ($self, $class);
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
my $functions = \%{$self->{FUNCTIONS}};
my $conditionals = \%{$self->{CONDITIONALS}};
my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
my $conditional_functions = \%{$self->{CONDITIONAL_FUNCTIONS}};
$$options = shift;
$$output = shift;
my $api_file = shift;
my $configure_in_file = shift;
my $config_h_in_file = shift;
my $api_file = "$winapi_check_dir/nativeapi.dat";
my $configure_in_file = "$wine_dir/configure.in";
my $config_h_in_file = "$wine_dir/include/config.h.in";
$api_file =~ s/^\.\///;
$configure_in_file =~ s/^\.\///;
$config_h_in_file =~ s/^\.\///;
if($$options->progress) {
$$output->progress("$api_file");
if($options->progress) {
$output->progress("$api_file");
}
open(IN, "< $api_file");
......@@ -49,8 +51,8 @@ sub new {
}
close(IN);
if($$options->progress) {
$$output->progress("$configure_in_file");
if($options->progress) {
$output->progress("$configure_in_file");
}
my $again = 0;
......@@ -100,8 +102,8 @@ sub new {
}
close(IN);
if($$options->progress) {
$$output->progress("$config_h_in_file");
if($options->progress) {
$output->progress("$config_h_in_file");
}
open(IN, "< $config_h_in_file");
......@@ -186,7 +188,7 @@ sub global_report {
}
foreach my $message (sort(@messages)) {
$$output->write($message);
$output->write($message);
}
}
......
......@@ -11,49 +11,53 @@ require Exporter;
use vars qw($win16api $win32api @winapis);
use config qw(
&file_type
&get_api_files &get_spec_files
$current_dir $wine_dir
);
use modules qw($modules);
use options qw($options);
use output qw($output);
$win16api = 'winapi'->new("win16");
$win32api = 'winapi'->new("win32");
@winapis = ($win16api, $win32api);
my @spec_files = get_spec_files("winelib");
foreach my $file (@spec_files) {
(my $type, my $module) = 'winapi'->get_spec_file_type("$wine_dir/$file");
$modules->spec_file_module($file, $module);
}
if($wine_dir eq ".") {
'winapi'->read_spec_files(\@spec_files);
} else {
@spec_files = $modules->allowed_spec_files;
'winapi'->read_spec_files(\@spec_files);
}
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless ($self, $class);
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
my $name = \${$self->{NAME}};
$$options = shift;
$$output = shift;
$$name = shift;
my $path = shift;
if($$options->progress) {
$$output->progress("$path: searching for *.api");
}
my @files = map {
s%^\./%%;
$_;
} split(/\n/, `find $path -name \\*.api`);
foreach my $file (@files) {
foreach my $file (get_api_files($$name)) {
my $module = $file;
if($$options->progress) {
$$output->lazy_progress("$file");
if($options->progress) {
$output->lazy_progress("$file");
}
$module =~ s/.*?\/([^\/]*?)\.api$/$1/;
$self->parse_api_file($file,$module);
}
if($$name eq "win16") {
$win16api = $self;
} elsif($$name eq "win32") {
$win32api = $self;
}
push @winapis, $self;
return $self;
}
......@@ -68,8 +72,6 @@ sub win32api {
sub parse_api_file {
my $self = shift;
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
my $allowed_kind = \%{$self->{ALLOWED_KIND}};
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
......@@ -85,11 +87,11 @@ sub parse_api_file {
my $extension = 0;
my $forbidden = 0;
if($$options->progress) {
$$output->progress("$file");
if($options->progress) {
$output->progress("$file");
}
open(IN, "< $file") || die "$file: $!\n";
open(IN, "< $wine_dir/$file") || die "$wine_dir/$file: $!\n";
$/ = "\n";
while(<IN>) {
s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
......@@ -143,12 +145,12 @@ sub parse_api_file {
if(!$forbidden) {
if(defined($module)) {
if($$allowed_modules_unlimited{$type}) {
$$output->write("$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}) {
$$allowed_modules{$type}{$module} = 1;
$$allowed_modules_limited{$type} = 1;
} else {
$$output->write("$file: type ($type) already specificed\n");
$output->write("$file: type ($type) already specificed\n");
}
} else {
$$allowed_modules_unlimited{$type} = 1;
......@@ -157,14 +159,14 @@ sub parse_api_file {
$$allowed_modules_limited{$type} = 1;
}
if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
$$output->write("$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 {
$$translate_argument{$type} = $kind;
}
$$type_format{$module}{$type} = $format;
} else {
$$output->write("$file: file must begin with %<type> statement\n");
$output->write("$file: file must begin with %<type> statement\n");
exit 1;
}
}
......@@ -201,16 +203,10 @@ sub read_spec_files {
my $proto = shift;
my $class = ref($proto) || $proto;
my $modules = shift;
my $wine_dir = shift;
my $current_dir = shift;
my $files = shift;
my $win16api = shift;
my $win32api = shift;
foreach my $file (@$files) {
(my $type, my $module) = 'winapi'->get_spec_file_type("$wine_dir/$file");
$modules->spec_file_module($file, $module);
if($type eq "win16") {
$win16api->parse_spec_file("$wine_dir/$file");
} elsif($type eq "win32") {
......@@ -246,34 +242,9 @@ sub read_spec_files {
}
}
sub read_all_spec_files {
my $proto = shift;
my $class = ref($proto) || $proto;
my $modules = shift;
my $wine_dir = shift;
my $current_dir = shift;
my $file_type = shift;
my $win16api = shift;
my $win32api = shift;
my @files = map {
s%^$wine_dir/%%;
if(&$file_type($_) eq "winelib") {
$_;
} else {
();
}
} split(/\n/, `find $wine_dir -name \\*.spec`);
'winapi'->read_spec_files($modules, $wine_dir, $current_dir, \@files, $win16api, $win32api);
}
sub parse_spec_file {
my $self = shift;
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
my $function_internal_arguments = \%{$self->{FUNCTION_INTERNAL_ARGUMENTS}};
my $function_external_arguments = \%{$self->{FUNCTION_EXTERNAL_ARGUMENTS}};
my $function_internal_ordinal = \%{$self->{FUNCTION_INTERNAL_ORDINAL}};
......@@ -297,8 +268,8 @@ sub parse_spec_file {
my $module;
my $module_file;
if($$options->progress) {
$$output->lazy_progress("$file");
if($options->progress) {
$output->lazy_progress("$file");
}
open(IN, "< $file") || die "$file: $!\n";
......@@ -366,10 +337,10 @@ sub parse_spec_file {
$$function_external_module{$external_name} .= " & $module";
}
if(0 && $$options->spec_mismatch) {
if(0 && $options->spec_mismatch) {
if($external_name eq "@") {
if($internal_name !~ /^\U$module\E_$ordinal$/) {
$$output->write("$file: $external_name: the internal name ($internal_name) mismatch\n");
$output->write("$file: $external_name: the internal name ($internal_name) mismatch\n");
}
} else {
my $name = $external_name;
......@@ -393,7 +364,7 @@ sub parse_spec_file {
if(uc($internal_name) ne uc($external_name) &&
$internal_name !~ /(\Q$name\E|\Q$name1\E|\Q$name2\E|\Q$name3\E|\Q$name4\E|\Q$name5\E)/)
{
$$output->write("$file: $external_name: internal name ($internal_name) mismatch\n");
$output->write("$file: $external_name: internal name ($internal_name) mismatch\n");
}
}
}
......@@ -466,7 +437,7 @@ sub parse_spec_file {
if(defined($ordinal)) {
if($ordinal ne "@" && $ordinals{$ordinal}) {
$$output->write("$file: ordinal redefined: $_\n");
$output->write("$file: ordinal redefined: $_\n");
}
$ordinals{$ordinal}++;
}
......@@ -556,7 +527,6 @@ sub types_not_used {
sub types_unlimited_used_in_modules {
my $self = shift;
my $output = \${$self->{OUTPUT}};
my $used_modules = \%{$self->{USED_MODULES}};
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
my $allowed_modules_unlimited = \%{$self->{ALLOWED_MODULES_UNLIMITED}};
......
......@@ -20,38 +20,25 @@ BEGIN {
}
use config qw(
&file_type &files_filter &files_skip
&get_h_files
$current_dir $wine_dir $winapi_dir $winapi_check_dir
&files_filter &files_skip
&get_h_files
$current_dir $wine_dir
);
use modules;
use nativeapi;
use output qw($output);
use winapi_check_options qw($options);
use modules qw($modules);
use nativeapi qw($nativeapi);
use winapi qw($win16api $win32api @winapis);
use preprocessor;
use type;
use util qw(&is_subset);
use winapi;
use winapi_documentation;
use winapi_function;
use winapi_local;
use winapi_global;
use winapi_check_options qw($options);
use winapi_parser;
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 $win32api = 'winapi'->new($options, $output, "win32", "$winapi_check_dir/win32");
my @winapis = ($win16api, $win32api);
if($options->global) {
'winapi'->read_all_spec_files($modules, $wine_dir, $current_dir, \&file_type, $win16api, $win32api);
} else {
my @spec_files = $modules->allowed_spec_files($wine_dir, $current_dir);
'winapi'->read_spec_files($modules, $wine_dir, $current_dir, \@spec_files, $win16api, $win32api);
}
my $nativeapi = 'nativeapi'->new($options, $output, "$winapi_check_dir/nativeapi.dat", "$wine_dir/configure.in", "$wine_dir/include/config.h.in");
my %declared_functions;
my %include2info;
......@@ -125,6 +112,10 @@ if($options->headers) {
$output->progress("$file: file $progress_current of $progress_max");
}
my $create_function = sub {
return 'winapi_function'->new;
};
my $found_function = sub {
my $function = shift;
......@@ -156,6 +147,15 @@ if($options->headers) {
$output->write("duplicate declaration (first declaration at $file:$function_line)\n");
}
}
$output->prefix("");
};
my $create_type = sub {
return 'type'->new;
};
my $found_type = sub {
my $type = shift;
};
my $found_preprocessor = sub {
......@@ -163,7 +163,7 @@ if($options->headers) {
my $argument = shift;
};
&winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
&winapi_parser::parse_c_file($file, $create_function, $found_function, $create_type, $found_type, $found_preprocessor);
}
}
......@@ -188,6 +188,10 @@ foreach my $file (@c_files) {
if(!($file_dir =~ s/(.*?)\/[^\/]*$/$1/)) {
$file_dir = ".";
}
my $create_function = sub {
return 'winapi_function'->new;
};
my $found_function = sub {
my $function = shift;
......@@ -273,19 +277,19 @@ foreach my $file (@c_files) {
}
}
if($options->local && $options->argument) {
if($options->local && $options->argument && defined($statements)) {
&winapi_local::check_function($function);
}
if($options->local && $options->statements) {
if($options->local && $options->statements && defined($statements)) {
&winapi_local::check_statements(\%functions, $function);
}
if($options->local && $options->documentation &&
(defined($module16) || defined($module32)) &&
$linkage ne "static" && ($linkage ne "" || defined($statements)))
$linkage eq "" && defined($statements))
{
&winapi_documentation::check_documentation($function);
# &winapi_documentation::check_documentation($function);
}
if(1) {
......@@ -386,6 +390,15 @@ foreach my $file (@c_files) {
}
}
};
my $create_type = sub {
return 'type'->new;
};
my $found_type = sub {
my $type = shift;
};
my $preprocessor = 'preprocessor'->new($found_include, $found_conditional);
my $found_preprocessor = sub {
my $directive = shift;
......@@ -511,7 +524,7 @@ foreach my $file (@c_files) {
}
};
&winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
&winapi_parser::parse_c_file($file, $create_function, $found_function, $create_type, $found_type, $found_preprocessor);
if($options->config_unnessary) {
if($config && $conditional == 0) {
......@@ -522,74 +535,69 @@ foreach my $file (@c_files) {
&winapi_local::check_file($file, \%functions);
}
$output->hide_progress;
if($options->global) {
my @complete_modules = $modules->complete_modules(\@c_files);
my %complete_module;
if($options->declared) {
my %dirs;
foreach my $file (@c_files) {
my $dir = $file;
$dir =~ s%/?[^/]*$%%;
if($dir) {
if($current_dir ne ".") {
$dir = "$current_dir/$dir";
}
} else {
$dir = "$current_dir";
}
$dirs{$dir}++;
foreach my $module (@complete_modules) {
$complete_module{$module}++;
}
foreach my $module ($modules->all_modules) {
my $incomplete = 0;
foreach my $module_dir ($modules->allowed_dirs_for_module($module)) {
my $found = 0;
foreach my $dir (sort(keys(%dirs))) {
if($module_dir eq $dir) {
$found = 1;
last;
}
}
if(!$found) {
$incomplete = 1;
}
}
if(!$incomplete) {
if($options->declared) {
foreach my $winapi (@winapis) {
if(!$winapi->is_module($module)) { next; }
my $functions = $module2functions{$module};
foreach my $internal_name ($winapi->all_internal_functions_in_module($module)) {
my $function = $functions->{$internal_name};
if(!defined($function) && !$nativeapi->is_function($internal_name) &&
!($module eq "user" && $internal_name =~
/^(?:GlobalAddAtomA|GlobalDeleteAtom|GlobalFindAtomA|
GlobalGetAtomNameA|lstrcmpiA)$/x))
{
$output->write("*.c: $module: $internal_name: " .
"function declared but not implemented or declared external\n");
}
if($options->declared) {
foreach my $module (@complete_modules) {
foreach my $winapi (@winapis) {
if(!$winapi->is_module($module)) { next; }
my $functions = $module2functions{$module};
foreach my $internal_name ($winapi->all_internal_functions_in_module($module)) {
my $function = $functions->{$internal_name};
if(!defined($function) && !$nativeapi->is_function($internal_name) &&
!($module eq "user" && $internal_name =~
/^(?:GlobalAddAtomA|GlobalDeleteAtom|GlobalFindAtomA|
GlobalGetAtomNameA|lstrcmpiA)$/x))
{
$output->write("*.c: $module: $internal_name: " .
"function declared but not implemented or declared external\n");
}
}
}
}
}
}
if($options->global) {
&winapi_documentation::report_documentation;
if($options->headers_unused) {
foreach my $name (sort(keys(%include2info))) {
if(!$include2info{$name}{used}) {
if($options->include) {
$output->write("*.c: $name: include file is never used\n");
if($options->argument && $options->argument_forbidden) {
foreach my $winapi (@winapis) {
my $types_not_used = $winapi->types_not_used;
foreach my $module (sort(keys(%$types_not_used))) {
if(!$complete_module{$module}) { next; }
foreach my $type (sort(keys(%{$$types_not_used{$module}}))) {
$output->write("*.c: $module: type ($type) not used\n");
}
}
}
}
&winapi_global::check(\%type_found);
my $all_modules = 1;
foreach my $module ($modules->all_modules) {
if(!$complete_module{$module}) {
$all_modules = 0;
}
}
if($all_modules) {
&winapi_documentation::report_documentation;
if($options->headers_unused) {
foreach my $name (sort(keys(%include2info))) {
if(!$include2info{$name}{used}) {
if($options->include) {
$output->write("*.c: $name: include file is never used\n");
}
}
}
}
&winapi_global::check(\%type_found);
$modules->global_report;
$nativeapi->global_report;
$modules->global_report;
$nativeapi->global_report;
}
}
......@@ -35,14 +35,6 @@ sub _check {
}
if($options->argument && $options->argument_forbidden) {
my $not_used = $winapi->types_not_used;
foreach my $module (sort(keys(%$not_used))) {
foreach my $type (sort(keys(%{$$not_used{$module}}))) {
$output->write("*.c: $module: type ($type) not used\n");
}
}
my $types_used = $winapi->types_unlimited_used_in_modules;
foreach my $type (sort(keys(%$types_used))) {
......
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