Several additions and bug fixes.
diff --git a/tools/winapi/config.pm b/tools/winapi/config.pm
index 9b46378..6e7aa8e 100644
--- a/tools/winapi/config.pm
+++ b/tools/winapi/config.pm
@@ -12,7 +12,7 @@
&file_absolutize &file_normalize
&file_type &files_filter
&file_skip &files_skip
- &get_spec_files
+ &get_c_files &get_h_files &get_spec_files
);
@EXPORT_OK = qw(
$current_dir $wine_dir $winapi_dir $winapi_check_dir
@@ -98,20 +98,27 @@
return $_;
}
-sub get_spec_files {
- $output->progress("$wine_dir: searching for *.spec");
+sub _get_files {
+ my $extension = shift;
+ my $type = shift;
- my @spec_files = map {
+ $output->progress("$wine_dir: searching for *.$extension");
+
+ my @files = map {
s%^\./%%;
s%^$wine_dir/%%;
- if(file_type($_) eq "winelib") {
+ if(file_type($_) eq $type) {
$_;
} else {
();
}
- } split(/\n/, `find $wine_dir -name \\*.spec`);
+ } split(/\n/, `find $wine_dir -name \\*.$extension`);
- return @spec_files;
+ return @files;
}
+sub get_c_files { return _get_files("c", @_); }
+sub get_h_files { return _get_files("h", @_); }
+sub get_spec_files { return _get_files("spec", @_); }
+
1;
diff --git a/tools/winapi/output.pm b/tools/winapi/output.pm
index 6234d6c..1b46172 100644
--- a/tools/winapi/output.pm
+++ b/tools/winapi/output.pm
@@ -34,11 +34,13 @@
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
+ my $last_time = \${$self->{LAST_TIME}};
my $progress_count = \${$self->{PROGRESS_COUNT}};
my $prefix = \${$self->{PREFIX}};
$$progress = "";
$$last_progress = "";
+ $$last_time = 0;
$$progress_count = 0;
$$prefix = "";
@@ -107,10 +109,26 @@
sub progress {
my $self = shift;
my $progress = \${$self->{PROGRESS}};
+ my $last_time = \${$self->{LAST_TIME}};
$$progress = shift;
$self->update_progress;
+ $$last_time = 0;
+}
+
+sub lazy_progress {
+ my $self = shift;
+ my $progress = \${$self->{PROGRESS}};
+ my $last_time = \${$self->{LAST_TIME}};
+
+ $$progress = shift;
+
+ my $time = time();
+ if($time - $$last_time > 0) {
+ $self->update_progress;
+ $$last_time = $time;
+ }
}
sub prefix {
diff --git a/tools/winapi/setup.pm b/tools/winapi/setup.pm
index 15d2e16..9c0961f 100644
--- a/tools/winapi/setup.pm
+++ b/tools/winapi/setup.pm
@@ -50,9 +50,7 @@
exit 1;
}
- push @INC, ($winapi_check_dir, $winapi_dir) if $tool eq "winapi_check";
- push @INC, ($winapi_dir, $winapi_check_dir) if $tool eq "winapi_extract";
- push @INC, ($winapi_dir, $winapi_check_dir) if $tool eq "winapi_fixup";
+ push @INC, ($winapi_dir, $winapi_check_dir);
}
1;
diff --git a/tools/winapi/winapi_extract b/tools/winapi/winapi_extract
index 981a4b4..3680bdb 100755
--- a/tools/winapi/winapi_extract
+++ b/tools/winapi/winapi_extract
@@ -55,7 +55,7 @@
{
local $_;
- foreach my $spec_file (get_spec_files) {
+ foreach my $spec_file (get_spec_files("winelib")) {
my $module;
my $type;
@@ -177,13 +177,15 @@
}
}
-my @files = files_skip($options->c_files);
+my @c_files = $options->c_files;
+@c_files = files_skip(@c_files);
+@c_files = files_filter("winelib", @c_files);
my $progress_output;
my $progress_current = 0;
-my $progress_max = scalar(@files);
+my $progress_max = scalar(@c_files);
-foreach my $file (@files) {
+foreach my $file (@c_files) {
my %functions;
$progress_current++;
diff --git a/tools/winapi_check/modules.pm b/tools/winapi_check/modules.pm
index 1252422..34f338e 100644
--- a/tools/winapi_check/modules.pm
+++ b/tools/winapi_check/modules.pm
@@ -133,6 +133,10 @@
my $dir = $file;
$dir =~ s/\/[^\/]*$//;
+ if($dir =~ m%^include%) {
+ return 1;
+ }
+
foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
if($$spec_file2module{$spec_file} eq $module) {
return 1;
diff --git a/tools/winapi_check/output.pm b/tools/winapi_check/output.pm
deleted file mode 100644
index c6347ee..0000000
--- a/tools/winapi_check/output.pm
+++ /dev/null
@@ -1,114 +0,0 @@
-package output;
-
-use strict;
-
-my $stdout_isatty = -t STDOUT;
-my $stderr_isatty = -t STDERR;
-
-sub new {
- my $proto = shift;
- my $class = ref($proto) || $proto;
- my $self = {};
- bless ($self, $class);
-
- my $progress = \${$self->{PROGRESS}};
- my $last_progress = \${$self->{LAST_PROGRESS}};
- my $progress_count = \${$self->{PROGRESS_COUNT}};
- my $prefix = \${$self->{PREFIX}};
-
- $$progress = "";
- $$last_progress = "";
- $$progress_count = 0;
- $$prefix = "";
-
- return $self;
-}
-
-
-sub show_progress {
- my $self = shift;
- 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;
- }
-}
-
-sub hide_progress {
- my $self = shift;
- 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 .= " ";
- }
- print STDERR $message;
- undef $$last_progress;
- }
-}
-
-sub update_progress {
- my $self = shift;
- 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 .= " ";
- }
- for (1..$diff) {
- $suffix .= "";
- }
- }
- }
- print STDERR $prefix . $$progress . $suffix;
- $$last_progress = $$progress;
-}
-
-sub progress {
- my $self = shift;
- my $progress = \${$self->{PROGRESS}};
-
- $$progress = shift;
-
- $self->update_progress;
-}
-
-sub prefix {
- my $self = shift;
- my $prefix = \${$self->{PREFIX}};
-
- $$prefix = shift;
-}
-
-sub write {
- my $self = shift;
-
- my $message = shift;
-
- my $prefix = \${$self->{PREFIX}};
-
- $self->hide_progress if $stdout_isatty;
- print $$prefix . $message;
- $self->show_progress if $stdout_isatty;
-}
-
-1;
diff --git a/tools/winapi_check/win32/msvcrt.api b/tools/winapi_check/win32/msvcrt.api
index 6399e02..3549303 100644
--- a/tools/winapi_check/win32/msvcrt.api
+++ b/tools/winapi_check/win32/msvcrt.api
@@ -14,8 +14,6 @@
WCHAR
int
long
-size_t
-time_t
unsigned int
unsigned long
@@ -56,7 +54,6 @@
char *
char **
char ***
-double *
exception *
int *
jmp_buf
@@ -66,13 +63,12 @@
struct _timeb *
struct _utimbuf *
struct _wfinddata_t *
-struct tm *
terminate_function
-time_t *
type_info *
unexpected_function
unsigned char *
unsigned int *
+unsigned long *
va_list
void *
diff --git a/tools/winapi_check/win32/ole32.api b/tools/winapi_check/win32/ole32.api
index cae3612..1540f51 100644
--- a/tools/winapi_check/win32/ole32.api
+++ b/tools/winapi_check/win32/ole32.api
@@ -84,7 +84,6 @@
REFIID
SNB
STGMEDIUM *
-WCHAR *
WORD *
void *
void **
diff --git a/tools/winapi_check/win32/shell32.api b/tools/winapi_check/win32/shell32.api
index 483c0e5..6f23aca 100644
--- a/tools/winapi_check/win32/shell32.api
+++ b/tools/winapi_check/win32/shell32.api
@@ -89,6 +89,10 @@
REFIID
UINT *
+%ptr # --forbidden
+
+int *
+
%str
LPCSTR
diff --git a/tools/winapi_check/winapi.pm b/tools/winapi_check/winapi.pm
index fd681cb..e58e1fe 100644
--- a/tools/winapi_check/winapi.pm
+++ b/tools/winapi_check/winapi.pm
@@ -26,6 +26,10 @@
$$name = shift;
my $path = shift;
+ if($$options->progress) {
+ $$output->progress("$path: searching for *.api");
+ }
+
my @files = map {
s%^\./%%;
$_;
@@ -33,6 +37,11 @@
foreach my $file (@files) {
my $module = $file;
+
+ if($$options->progress) {
+ $$output->lazy_progress("$file");
+ }
+
$module =~ s/.*?\/([^\/]*?)\.api$/$1/;
$self->parse_api_file($file,$module);
}
@@ -289,7 +298,7 @@
my $module_file;
if($$options->progress) {
- $$output->progress("$file");
+ $$output->lazy_progress("$file");
}
open(IN, "< $file") || die "$file: $!\n";
@@ -585,24 +594,6 @@
return sort(keys(%$translate_argument));
}
-sub found_type {
- my $self = shift;
- my $type_found = \%{$self->{TYPE_FOUND}};
-
- my $name = shift;
-
- $$type_found{$name}++;
-}
-
-sub type_found {
- my $self = shift;
- my $type_found= \%{$self->{TYPE_FOUND}};
-
- my $name = shift;
-
- return $$type_found{$name};
-}
-
sub is_allowed_type_format {
my $self = shift;
my $type_format = \%{$self->{TYPE_FORMAT}};
@@ -734,13 +725,6 @@
return sort(keys(%{$$function_stub{$module}}));
}
-sub all_internal_functions_found {
- my $self = shift;
- my $function_found = \%{$self->{FUNCTION_FOUND}};
-
- return sort(keys(%$function_found));
-}
-
sub function_internal_ordinal {
my $self = shift;
my $function_internal_ordinal = \%{$self->{FUNCTION_INTERNAL_ORDINAL}};
@@ -892,24 +876,6 @@
return $$function_stub{$module}{$name};
}
-sub found_internal_function {
- my $self = shift;
- my $function_found = \%{$self->{FUNCTION_FOUND}};
-
- my $name = shift;
-
- $$function_found{$name}++;
-}
-
-sub internal_function_found {
- my $self = shift;
- my $function_found = \%{$self->{FUNCTION_FOUND}};
-
- my $name = shift;
-
- return $$function_found{$name};
-}
-
########################################################################
# class methods
#
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index 9f24692..22d2ee9 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
-# Copyright 1999-2000 Patrik Stridvall
+# Copyright 1999-2001 Patrik Stridvall
# Note that winapi_check are using heuristics quite heavily.
# So always remember that:
@@ -20,10 +20,8 @@
}
use config qw(
- &file_absolutize &file_normalize
- &file_type &files_filter
- &file_skip &files_skip
- &get_spec_files
+ &file_type &files_filter &files_skip
+ &get_h_files
$current_dir $wine_dir $winapi_dir $winapi_check_dir
);
use modules;
@@ -66,31 +64,42 @@
my $nativeapi = 'nativeapi'->new($options, $output, "$winapi_check_dir/nativeapi.dat", "$wine_dir/configure.in", "$wine_dir/include/config.h.in");
-my %includes;
+my %declared_functions;
+
+my %include2info;
{
- my @files = map {
- s/^.\/(.*)$/$1/;
- $_;
- } split(/\n/, `find . -name \\*.h`);
-
+ my @files = get_h_files("winelib");
+
+ my $progress_current = 0;
+ my $progress_max = scalar(@files);
+
foreach my $file (@files) {
+ $progress_current++;
+ if($options->progress) {
+ $output->lazy_progress("$file: file $progress_current of $progress_max");
+ }
+
my $file_dir = $file;
- if(!($file_dir =~ s/(.*?)\/[^\/]*$/$1/)) {
+ if(!($file_dir =~ s%(.*?)/[^/]+$%$1%)) {
$file_dir = ".";
}
-
- $includes{$file} = { name => $file };
- open(IN, "< $file");
+ $include2info{$file} = { name => $file };
+
+ open(IN, "< $wine_dir/$file");
while(<IN>) {
if(/^\s*\#\s*include\s*\"(.*?)\"/) {
my $header = $1;
- if(-e "$file_dir/$header") {
- $includes{$file}{includes}{"$file_dir/$header"}++;
- } elsif(-e "$file_dir/../$header") { # FIXME: This is not correct
- $includes{$file}{includes}{"$file_dir/../$header"}++; # FIXME: This is not correct
+ if(-e "$wine_dir/$file_dir/$header") {
+ $include2info{$file}{includes}{"$file_dir/$header"}++;
+ } elsif(-e "$wine_dir/$file_dir/../$header") {
+ if($file_dir =~ m%^(.*?)/[^/]+$%) {
+ $include2info{$file}{includes}{"$1/$header"}++;
+ } else {
+ $include2info{$file}{includes}{"$header"}++;
+ }
} elsif(-e "$wine_dir/include/$header") {
- $includes{$file}{includes}{"include/$header"}++;
+ $include2info{$file}{includes}{"include/$header"}++;
} else {
$output->write("$file: #include \"$header\" is not a local include\n");
}
@@ -102,18 +111,20 @@
my @files2 = ("acconfig.h", "poppack.h", "pshpack1.h", "pshpack2.h", "pshpack4.h", "pshpack8.h",
"storage.h", "ver.h");
foreach my $file2 (@files2) {
- $includes{"include/$file2"}{used}++;
+ $include2info{"include/$file2"}{used}++;
}
}
-my %declared_functions;
+my @c_files = $options->c_files;
+@c_files = files_skip(@c_files);
+@c_files = files_filter("winelib", @c_files);
-my @c_files = files_skip($options->c_files);
-my @h_files = files_skip($options->h_files);
+my @h_files = $options->h_files;
+@h_files = files_skip(@h_files);
+@h_files = files_filter("winelib", @h_files);
-my $progress_output;
-my $progress_current=0;
-my $progress_max=scalar(@c_files);
+my $progress_current = 0;
+my $progress_max = scalar(@c_files);
if($options->headers) {
$progress_max += scalar(@h_files);
@@ -125,77 +136,52 @@
if($options->progress) {
$output->progress("$file: file $progress_current of $progress_max");
}
-
+
my $found_function = sub {
my $function = shift;
- my $documentation_line = $function->documentation_line;
- my $documentation = $function->documentation;
+ $output->prefix($function->prefix);
+
my $function_line = $function->function_line;
- my $linkage = $function->linkage;
- my $return_type = $function->return_type;
- my $calling_convention = $function->calling_convention;
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;
-
- foreach my $winapi (@winapis) {
- my $module = $winapi->function_internal_module($internal_name);
- if(!defined($module)) { next }
- # FIXME: Not correct
- my $external_name = $winapi->function_external_name($internal_name);
+ if($options->headers_misplaced &&
+ !($function->is_win16 && $function->is_win32) &&
+ (($function->is_win16 && $file =~ /^include\/[^\/]*$/) ||
+ ($function->is_win32 && $file =~ /^include\/wine\/[^\/]*$/)))
+ {
+ $output->write("declaration misplaced\n");
+ }
- if(defined($external_name)) {
- $external_name = (split(/\s*&\s*/, $external_name))[0];
- }
-
- # FIXME: Kludge because of the THUNK variants
- if(!defined($external_name)) {
- next;
- }
-
- my $output_function = sub {
- my $message = shift;
-
- $output->write("$file: $module: $return_type ");
- $output->write("$calling_convention ") if $calling_convention;
- $output->write("$internal_name(" . join(",", @argument_types) . "): $message\n");
- };
-
- if(!defined($declared_functions{$winapi->name}{$external_name})) {
- $declared_functions{$winapi->name}{$external_name} = "$file";
+ if(!defined($statements)) {
+ my $previous_function = $declared_functions{$internal_name};
+ if(!defined($previous_function)) {
+ $declared_functions{$internal_name} = $function;
} elsif($options->headers_duplicated) {
- my $message = "declared more than once";
- if($file ne $declared_functions{$winapi->name}{$external_name}) {
- $message .= ", first declaration in '" . $declared_functions{$winapi->name}{$external_name} . "'";
- }
- &$output_function("$message");
- }
-
- if($options->headers_misplaced) {
- if($file =~ /^include\/[^\/]*$/ && $winapi->name eq "win16") {
- &$output_function("declaration misplaced");
- } elsif($file =~ /^include\/wine\/[^\/]*$/ && $winapi->name eq "win32") {
- &$output_function("declaration misplaced");
- }
+ my $file = $previous_function->file;
+ my $function_line = $previous_function->function_line;
+ $output->write("duplicate declaration (first declaration at $file:$function_line)\n");
}
}
};
-
+
my $found_preprocessor = sub {
my $directive = shift;
my $argument = shift;
};
-
+
winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor;
}
}
+my %module2functions = ();
+my %type_found = ();
+
foreach my $file (@c_files) {
my %functions = ();
+ my @includes = ();
+ my %needed_includes = ();
my $file_module16 = $modules->allowed_modules_in_file("$current_dir/$file");
my $file_module32 = $modules->allowed_modules_in_file("$current_dir/$file");
@@ -210,14 +196,16 @@
$file_dir = ".";
}
- my $file_type = file_type($file);
-
my $found_function = sub {
my $function = shift;
+ $output->prefix($function->prefix);
+
my $internal_name = $function->internal_name;
$functions{$internal_name} = $function;
+ my $declared_function = $declared_functions{$internal_name};
+
my $documentation_line = $function->documentation_line;
my $documentation = $function->documentation;
my $linkage = $function->linkage;
@@ -228,41 +216,36 @@
my @argument_documentations = @{$function->argument_documentations};
my $statements = $function->statements;
+ my $module16 = $function->module16;
+ my $module32 = $function->module32;
+
my $external_name16 = $function->external_name16;
my $external_name32 = $function->external_name32;
- if($options->global) {
- $win16api->found_type($return_type) if $options->win16;
- $win32api->found_type($return_type) if $options->win32;
- for my $argument (@argument_types) {
- $win16api->found_type($argument) if $options->win16;
- $win32api->found_type($argument) if $options->win32;
+ foreach my $module ($function->modules) {
+ $module2functions{$module}{$internal_name} = $function;
+ for my $type ($return_type, @argument_types) {
+ $type_found{$module}{$type}++;
}
}
- if($options->declared) {
- $win16api->found_internal_function($internal_name) if $options->win16;
- $win32api->found_internal_function($internal_name) if $options->win32;
+ foreach my $module ($function->modules) {
+ $modules->found_module_in_dir($module, $file_dir);
}
- if($file_type eq "winelib") {
- my $module16 = $function->module16;
- my $module32 = $function->module32;
-
- foreach my $module ($function->modules) {
- $modules->found_module_in_dir($module, $file_dir);
+ if($options->shared) {
+ if($win16api->is_shared_internal_function($internal_name) ||
+ $win32api->is_shared_internal_function($internal_name))
+ {
+ $output->write("is shared between Win16 and Win32\n");
}
+ }
- $output->prefix("$file: " . $function->prefix);
+ if(defined($declared_function)) {
+ $needed_includes{$declared_function->file}++;
+ }
- if($options->shared) {
- if($win16api->is_shared_internal_function($internal_name) ||
- $win32api->is_shared_internal_function($internal_name))
- {
- $output->write("is shared between Win16 and Win32\n");
- }
- }
-
+ if(1) {
# FIXME: Not correct
if(defined($external_name16)) {
$external_name16 = (split(/\s*&\s*/, $external_name16))[0];
@@ -307,20 +290,15 @@
if($options->local && $options->headers && $options->prototype) {
if($options->win16 && $options->report_module($module16)) {
- if(!defined($external_name16) || (!$nativeapi->is_function($external_name16) &&
- !defined($declared_functions{$win16api->name}{$external_name16})))
+ if(!$nativeapi->is_function($internal_name) &&
+ !defined($declared_functions{$internal_name}))
{
- if(!defined($external_name16) || ($external_name16 !~ /^DllEntryPoint$/ &&
- $internal_name !~ /^I(?:Malloc|Storage)16_fn/ &&
- $internal_name !~ /^(?:\Q$module16\E|THUNK|WIN16)_\Q$external_name16\E(?:16)?$/))
- {
- $output->write("no prototype\n");
- }
+ $output->write("no prototype\n");
}
}
if($options->win32 && $options->report_module($module32)) {
- if(!defined($external_name32) || (!$nativeapi->is_function($external_name32) && !defined($declared_functions{$win32api->name}{$external_name32})))
+ if(!defined($external_name32) || (!$nativeapi->is_function($external_name32) && !defined($declared_functions{$external_name32})))
{
if(!defined($external_name32) || ($external_name32 !~ /^Dll(?:
Install|CanUnloadNow|GetClassObject|GetVersion|
@@ -379,17 +357,15 @@
$nativeapi->found_conditional($_);
if($options->config) {
- if($file_type ne "application") {
- if(!$nativeapi->is_conditional($_)) {
- if(/^HAVE_/ && !/^HAVE_(IPX|MESAGL|BUGGY_MESAGL|WINE_CONSTRUCTOR)$/)
- {
- $output->write("$file: $_ is not declared as a conditional\n");
- }
- } else {
- $conditional++;
- if(!$config) {
- $output->write("$file: conditional $_ used but config.h is not included\n");
- }
+ if(!$nativeapi->is_conditional($_)) {
+ if(/^HAVE_/ && !/^HAVE_(IPX|MESAGL|BUGGY_MESAGL|WINE_CONSTRUCTOR)$/)
+ {
+ $output->write("$file: $_ is not declared as a conditional\n");
+ }
+ } else {
+ $conditional++;
+ if(!$config) {
+ $output->write("$file: conditional $_ used but config.h is not included\n");
}
}
}
@@ -407,21 +383,41 @@
my $check_protection;
my $check_local;
if($argument =~ /^<(.*?)>$/) {
- $header = $1;
- if($file_type ne "application") {
- $check_protection = 1;
- } else {
- $check_protection = 0;
- }
- $check_local = 0;
- } elsif($argument =~ /^"(.*?)"$/) {
- $header = $1;
- $check_protection = 0;
- $check_local = 1;
+ $header = $1;
+ $check_protection = 1;
+ $check_local = 0;
+ } elsif($argument =~ /^\"(.*?)\"$/) {
+ $header = $1;
+ $check_protection = 0;
+ $check_local = 1;
+ } else {
+ $output->write("$file: #$directive $argument: is unparsable\n");
+
+ $header = undef;
+ $check_protection = 0;
+ $check_local = 0;
}
- if($check_protection) {
- if((-e "$wine_dir/include/$header" || -e "$file_dir/$header")) {
+ if(defined($header)) {
+ if(-e "$wine_dir/include/$header") {
+ push @includes, "include/$header";
+ } elsif(-e "$file_dir/$header") {
+ push @includes, "$file_dir/$header";
+ } elsif(-e "$file_dir/../$header") {
+ if($file_dir =~ m%^(.*?)/[^/]+$%) {
+ push @includes, "$1/$header";
+ } else {
+ push @includes, "$header";
+ }
+ } elsif($header eq "controls.h") { # FIXME: Kludge
+ push @includes, "dlls/user/controls.h";
+ } elsif($check_local) {
+ $output->write("$file: #include \"$header\": file not found\n");
+ }
+ }
+
+ if($check_protection && $header) {
+ if((-e "$wine_dir/include/$header" || -e "$wine_dir/$file_dir/$header")) {
if($header !~ /^ctype.h$/) {
$output->write("$file: #include \<$header\> is a local include\n");
}
@@ -448,26 +444,40 @@
}
}
- if($check_local) {
+ if($check_local && $header) {
if(-e "$file_dir/$header") {
- $includes{"$file_dir/$header"}{used}++;
- foreach my $name (keys(%{$includes{"$file_dir/$header"}{includes}})) {
- $includes{$name}{used}++;
+ if($file_dir ne ".") {
+ $include2info{"$file_dir/$header"}{used}++;
+ foreach my $name (keys(%{$include2info{"$file_dir/$header"}{includes}})) {
+ $include2info{$name}{used}++;
+ }
+ } else {
+ $include2info{"$header"}{used}++;
+ foreach my $name (keys(%{$include2info{"$header"}{includes}})) {
+ $include2info{$name}{used}++;
+ }
}
- } elsif(-e "$file_dir/../$header") { # FIXME: Kludge
- $includes{"$file_dir/../$header"}{used}++; # FIXME: This is not correct
- foreach my $name (keys(%{$includes{"$file_dir/../$header"}{includes}})) { # FIXME: This is not correct
- $includes{$name}{used}++;
+ } elsif(-e "$wine_dir/$file_dir/../$header") {
+ if($file_dir =~ m%^(.*?)/[^/]+$%) {
+ $include2info{"$1/$header"}{used}++;
+ foreach my $name (keys(%{$include2info{"$1/$header"}{includes}})) {
+ $include2info{$name}{used}++;
+ }
+ } else {
+ $include2info{"$header"}{used}++;
+ foreach my $name (keys(%{$include2info{"$header"}{includes}})) {
+ $include2info{$name}{used}++;
+ }
}
} elsif($header eq "controls.h") { # FIXME: Kludge
- $includes{"dlls/user/$header"}{used}++;
- foreach my $name (keys(%{$includes{"dlls/user/$header"}{includes}})) {
- $includes{$name}{used}++;
+ $include2info{"dlls/user/$header"}{used}++;
+ foreach my $name (keys(%{$include2info{"dlls/user/$header"}{includes}})) {
+ $include2info{$name}{used}++;
}
} elsif(-e "$wine_dir/include/$header") {
- $includes{"include/$header"}{used}++;
- foreach my $name (keys(%{$includes{"include/$header"}{includes}})) {
- $includes{$name}{used}++;
+ $include2info{"include/$header"}{used}++;
+ foreach my $name (keys(%{$include2info{"include/$header"}{includes}})) {
+ $include2info{$name}{used}++;
}
} else {
$output->write("$file: #include \"$header\" is not a local include\n");
@@ -481,10 +491,32 @@
if($options->config_unnessary) {
if($config && $conditional == 0) {
- $output->write("$file: includes config.h but do not use any conditionals\n");
+ $output->write("$file: include2info config.h but do not use any conditionals\n");
}
}
+ if($options->headers_needed) {
+ my %includes2;
+ foreach my $include (@includes) {
+ $includes2{$include}++;
+ foreach my $include (keys(%{$include2info{$include}{includes}})) {
+ $includes2{$include}++;
+ }
+ }
+ foreach my $needed_include (sort(keys(%needed_includes))) {
+ my $found = 0;
+ foreach my $include (sort(keys(%includes2))) {
+ if($needed_include eq $include) {
+ $found = 1;
+ }
+ }
+ if(!$found) {
+ $output->write("$file: file '$needed_include' needed but not included\n");
+ }
+ }
+ }
+
+
winapi_local::check_file $options, $output, $file, \%functions;
}
@@ -523,8 +555,14 @@
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)) {
- if(!$winapi->internal_function_found($internal_name)) {
+ 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");
}
@@ -538,9 +576,9 @@
if($options->global) {
winapi_documentation::report_documentation $options, $output;
- if($options->headers) {
- foreach my $name (sort(keys(%includes))) {
- if(!$includes{$name}{used}) {
+ 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");
}
@@ -548,8 +586,8 @@
}
}
- winapi_global::check $options, $output, $win16api, $nativeapi if $options->win16;
- winapi_global::check $options, $output, $win32api, $nativeapi if $options->win32;
+ winapi_global::check $options, $output, $win16api, $nativeapi, \%type_found if $options->win16;
+ winapi_global::check $options, $output, $win32api, $nativeapi, \%type_found if $options->win32;
$modules->global_report;
$nativeapi->global_report;
diff --git a/tools/winapi_check/winapi_function.pm b/tools/winapi_check/winapi_function.pm
index b43f7ab..a43ff57 100644
--- a/tools/winapi_check/winapi_function.pm
+++ b/tools/winapi_check/winapi_function.pm
@@ -22,6 +22,13 @@
}
########################################################################
+# is_win
+#
+
+sub is_win16 { my $self = shift; return defined($self->_module($win16api, @_)); }
+sub is_win32 { my $self = shift; return defined($self->_module($win32api, @_)); }
+
+########################################################################
# external_name
#
@@ -190,6 +197,7 @@
my $module32 = $self->module32;
my $file = $self->file;
+ my $function_line = $self->function_line;
my $return_type = $self->return_type;
my $internal_name = $self->internal_name;
my $calling_convention = $self->calling_convention;
@@ -208,7 +216,12 @@
push @modules, $module;
$used{$module}++;
}
- $prefix .= "$file: ";
+ $prefix .= "$file:";
+ if(defined($function_line)) {
+ $prefix .= "$function_line: ";
+ } else {
+ $prefix .= "<>: ";
+ }
if($#modules >= 0) {
$prefix .= join(" & ", @modules) . ": ";
} else {
diff --git a/tools/winapi_check/winapi_global.pm b/tools/winapi_check/winapi_global.pm
index b926101..7249062 100644
--- a/tools/winapi_check/winapi_global.pm
+++ b/tools/winapi_check/winapi_global.pm
@@ -7,12 +7,13 @@
my $output = shift;
my $winapi = shift;
my $nativeapi = shift;
+ my $type_found = shift;
my $winver = $winapi->name;
if($options->argument) {
foreach my $type ($winapi->all_declared_types) {
- if(!$winapi->type_found($type) && !$winapi->is_limited_type($type) && $type ne "CONTEXT86 *") {
+ if(!$$type_found{$type} && !$winapi->is_limited_type($type) && $type ne "CONTEXT86 *") {
$output->write("*.c: $winver: ");
$output->write("type ($type) not used\n");
}
diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm
index e137f00..21b9f2a 100644
--- a/tools/winapi_check/winapi_options.pm
+++ b/tools/winapi_check/winapi_options.pm
@@ -118,9 +118,12 @@
"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, parent => "global", description => "headers 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 %short_options = (
@@ -147,6 +150,7 @@
my $h_files = \@{$self->{H_FILES}};
my $module = \${$self->{MODULE}};
my $global = \${$self->{GLOBAL}};
+ my $headers = \${$self->{HEADERS}};
my @files;
@@ -285,11 +289,14 @@
}
}
+ if($#h_files >= 0) {
+ $$headers = 1;
+ }
+
if($#c_files == -1 && $#h_files == -1 &&
($#paths == -1 || ($#paths == 0 && $paths[0] eq $wine_dir)))
{
@paths = ".";
- push @h_files, "$wine_dir/include";
} else {
$$global = 0;
}
@@ -308,8 +315,8 @@
} split(/\n/, `$c_command`));
}
- if($#h_files != -1) {
- my $h_command = "find " . join(" ", @h_files) . " -name \\*.h";
+ if($#paths != -1 || $#h_files != -1) {
+ my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h";
my %found;
@$h_files = sort(map {
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index 3ecda04..8e99f83 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -62,8 +62,9 @@
$function->file($file);
$function->debug_channels([@$debug_channels]);
- $function->documentation($documentation);
$function->documentation_line($documentation_line);
+ $function->documentation($documentation);
+ $function->function_line($function_line);
$function->linkage($linkage);
$function->return_type($return_type);
$function->calling_convention($calling_convention);
@@ -255,8 +256,8 @@
if($internal_name && $level == 0) {
&$function_end;
}
- next;
- } elsif(/(extern\s+|static\s+)?((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))
+ next;
+ } elsif(/(extern\s+|static\s+)?((struct\s+|union\s+|enum\s+|signed\s+|unsigned\s+)?\w+((\s*\*)+\s*|\s+))
((__cdecl|__stdcall|CDECL|VFWAPIV|VFWAPI|WINAPIV|WINAPI|CALLBACK)\s+)?
(\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/sx)
{