Several additions and bug fixes.
diff --git a/tools/winapi/output.pm b/tools/winapi/output.pm
index a085f95..6234d6c 100644
--- a/tools/winapi/output.pm
+++ b/tools/winapi/output.pm
@@ -23,6 +23,9 @@
use strict;
+my $stdout_isatty = -t STDOUT;
+my $stderr_isatty = -t STDERR;
+
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
@@ -51,7 +54,7 @@
$$progress_count++;
- if($$progress_count > 0 && $$progress) {
+ if($$progress_count > 0 && $$progress && $stderr_isatty) {
print STDERR $$progress;
$$last_progress = $$progress;
}
@@ -65,7 +68,7 @@
$$progress_count--;
- if($$last_progress) {
+ if($$last_progress && $stderr_isatty) {
my $message;
for (1..length($$last_progress)) {
$message .= " ";
@@ -124,9 +127,9 @@
my $prefix = \${$self->{PREFIX}};
- $self->hide_progress;
+ $self->hide_progress if $stdout_isatty;
print $$prefix . $message;
- $self->show_progress;
+ $self->show_progress if $stdout_isatty;
}
1;
diff --git a/tools/winapi/winapi_extract b/tools/winapi/winapi_extract
index c725ab4..981a4b4 100755
--- a/tools/winapi/winapi_extract
+++ b/tools/winapi/winapi_extract
@@ -14,6 +14,7 @@
$current_dir $wine_dir $winapi_dir $winapi_check_dir
);
use modules;
+use nativeapi;
use output;
use options;
use winapi;
@@ -89,6 +90,9 @@
'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 {
diff --git a/tools/winapi/winapi_fixup b/tools/winapi/winapi_fixup
index 3b214d8..a10dc4c 100755
--- a/tools/winapi/winapi_fixup
+++ b/tools/winapi/winapi_fixup
@@ -106,7 +106,7 @@
my @argument_documentations = @{$function->argument_documentations};
my $statements = $function->statements;
- if($linkage eq "static" || $linkage eq "extern" || !defined($statements)) {
+ if($linkage eq "static" || ($linkage eq "" && !defined($statements))) {
return;
}
@@ -137,10 +137,10 @@
foreach my $winapi (@winapis) {
my @entries = ();
- if($winapi->function_stub($internal_name)) {
- my $module = $winapi->function_internal_module($internal_name);
- my $ordinal = $winapi->function_internal_ordinal($internal_name);
+ my $module = $winapi->function_internal_module($internal_name);
+ my $ordinal = $winapi->function_internal_ordinal($internal_name);
+ if($winapi->is_function_stub_in_module($module, $internal_name)) {
my $external_name = $internal_name;
if($winapi->name eq "win16") {
$external_name =~ s/(?:_)?16([AW]?)$//;
@@ -159,7 +159,7 @@
if($external_name ne "@" &&
$winapi->is_module($module) &&
- $winapi->function_stub($external_name) &&
+ $winapi->is_function_stub_in_module($module, $external_name) &&
$internal_name !~ /^\U$module\E_\Q$external_name\E$/)
{
push @entries, [$external_name, $module, $ordinal];
@@ -381,8 +381,8 @@
}
# FIXME: Not 100% correct
if(!$found &&
- !$win16api->function_stub($internal_name) &&
- !$win32api->function_stub($internal_name))
+ !$win16api->is_function_stub_in_module($module2, $internal_name) &&
+ !$win32api->is_function_stub_in_module($module2, $internal_name))
{
if($line3 > 0) {
$part2 = $external_name2 . " " x (length($part2) - length($external_name2));
diff --git a/tools/winapi_check/modules.dat b/tools/winapi_check/modules.dat
index fdbb405..eb72aba 100644
--- a/tools/winapi_check/modules.dat
+++ b/tools/winapi_check/modules.dat
@@ -346,7 +346,6 @@
controls
dlls/kernel
dlls/user
-memory
misc
windows
diff --git a/tools/winapi_check/modules.pm b/tools/winapi_check/modules.pm
index 25f109e..1252422 100644
--- a/tools/winapi_check/modules.pm
+++ b/tools/winapi_check/modules.pm
@@ -19,7 +19,8 @@
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
- my $spec_files = \%{$self->{SPEC_FILES}};
+ my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
+ my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
$$options = shift;
@@ -71,12 +72,13 @@
} else {
$all_spec_files{"$wine_dir/$spec_file"}--;
}
- $$spec_files{""}{$spec_file}++; # FIXME: Kludge
+ $$dir2spec_file{""}{$spec_file}++; # FIXME: Kludge
next;
} else {
$allowed_dir = $1;
+ $$spec_file2dir{$spec_file}{$allowed_dir}++;
}
- $$spec_files{$allowed_dir}{$spec_file}++;
+ $$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");
@@ -95,6 +97,14 @@
return $self;
}
+sub all_modules {
+ my $self = shift;
+
+ my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
+
+ return sort(keys(%$module2spec_file));
+}
+
sub spec_file_module {
my $self = shift;
@@ -106,14 +116,14 @@
my $module = shift;
- $$spec_file2module{$spec_file}{$module}++;
- $$module2spec_file{$module}{$spec_file}++;
+ $$spec_file2module{$spec_file} = $module;
+ $$module2spec_file{$module} = $spec_file;
}
sub is_allowed_module_in_file {
my $self = shift;
- my $spec_files = \%{$self->{SPEC_FILES}};
+ my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
my $module = shift;
@@ -123,8 +133,8 @@
my $dir = $file;
$dir =~ s/\/[^\/]*$//;
- foreach my $spec_file (sort(keys(%{$$spec_files{$dir}}))) {
- if($$spec_file2module{$spec_file}{$module}) {
+ foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
+ if($$spec_file2module{$spec_file} eq $module) {
return 1;
}
}
@@ -135,7 +145,7 @@
sub allowed_modules_in_file {
my $self = shift;
- my $spec_files = \%{$self->{SPEC_FILES}};
+ my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
my $file = shift;
@@ -145,21 +155,33 @@
$dir =~ s/\/[^\/]*$//;
my %allowed_modules = ();
- foreach my $spec_file (sort(keys(%{$$spec_files{$dir}}))) {
- foreach my $module (sort(keys(%{$$spec_file2module{$spec_file}}))) {
- $allowed_modules{$module}++;
- }
+ foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
+ my $module = $$spec_file2module{$spec_file};
+ $allowed_modules{$module}++;
}
return join(" & ", sort(keys(%allowed_modules)));
}
+sub allowed_dirs_for_module {
+ my $self = shift;
+
+ my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
+ my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
+
+ my $module = shift;
+
+ my $spec_file = $$module2spec_file{$module};
+
+ return sort(keys(%{$$spec_file2dir{$spec_file}}));
+}
+
sub allowed_spec_files {
my $self = shift;
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
- my $spec_files = \%{$self->{SPEC_FILES}};
+ my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
my $wine_dir = shift;
my $current_dir = shift;
@@ -179,7 +201,7 @@
my %allowed_spec_files = ();
foreach my $dir (sort(@dirs)) {
- foreach my $spec_file (sort(keys(%{$$spec_files{$dir}}))) {
+ foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
$allowed_spec_files{$spec_file}++;
}
}
@@ -202,18 +224,17 @@
my $self = shift;
my $output = \${$self->{OUTPUT}};
- my $spec_files = \%{$self->{SPEC_FILES}};
+ my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
my @messages;
- foreach my $dir (sort(keys(%$spec_files))) {
+ foreach my $dir (sort(keys(%$dir2spec_file))) {
if($dir eq "") { next; }
- foreach my $spec_file (sort(keys(%{$$spec_files{$dir}}))) {
- foreach my $module (sort(keys(%{$$spec_file2module{$spec_file}}))) {
- if(!$$used_module_dirs{$module}{$dir}) {
- push @messages, "modules.dat: $spec_file: directory ($dir) is not used\n";
- }
+ foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
+ my $module = $$spec_file2module{$spec_file};
+ if(!$$used_module_dirs{$module}{$dir}) {
+ push @messages, "modules.dat: $spec_file: directory ($dir) is not used\n";
}
}
}
diff --git a/tools/winapi_check/nativeapi.pm b/tools/winapi_check/nativeapi.pm
index 5c5c338..e73a6ca 100644
--- a/tools/winapi_check/nativeapi.pm
+++ b/tools/winapi_check/nativeapi.pm
@@ -2,6 +2,15 @@
use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw($nativeapi);
+
+use vars qw($nativeapi);
+
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
@@ -32,10 +41,10 @@
open(IN, "< $api_file");
local $/ = "\n";
while(<IN>) {
- s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
- s/^(.*?)\s*#.*$/$1/; # remove comments
- /^$/ && next; # skip empty lines
-
+ s/^\s*(.*?)\s*$/$1/; # remove whitespace at begin and end of line
+ s/^(.*?)\s*#.*$/$1/; # remove comments
+ /^$/ && next; # skip empty lines
+
$$functions{$_}++;
}
close(IN);
@@ -110,6 +119,8 @@
}
close(IN);
+ $nativeapi = $self;
+
return $self;
}
diff --git a/tools/winapi_check/output.pm b/tools/winapi_check/output.pm
index f5241af..c6347ee 100644
--- a/tools/winapi_check/output.pm
+++ b/tools/winapi_check/output.pm
@@ -2,6 +2,9 @@
use strict;
+my $stdout_isatty = -t STDOUT;
+my $stderr_isatty = -t STDERR;
+
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
@@ -30,7 +33,7 @@
$$progress_count++;
- if($$progress_count > 0 && $$progress) {
+ if($$progress_count > 0 && $$progress && $stderr_isatty) {
print STDERR $$progress;
$$last_progress = $$progress;
}
@@ -44,7 +47,7 @@
$$progress_count--;
- if($$last_progress) {
+ if($$last_progress && $stderr_isatty) {
my $message;
for (1..length($$last_progress)) {
$message .= " ";
@@ -103,9 +106,9 @@
my $prefix = \${$self->{PREFIX}};
- $self->hide_progress;
+ $self->hide_progress if $stdout_isatty;
print $$prefix . $message;
- $self->show_progress;
+ $self->show_progress if $stdout_isatty;
}
1;
diff --git a/tools/winapi_check/win32/msvcrt.api b/tools/winapi_check/win32/msvcrt.api
index 173aba2..6399e02 100644
--- a/tools/winapi_check/win32/msvcrt.api
+++ b/tools/winapi_check/win32/msvcrt.api
@@ -15,6 +15,7 @@
int
long
size_t
+time_t
unsigned int
unsigned long
@@ -55,6 +56,7 @@
char *
char **
char ***
+double *
exception *
int *
jmp_buf
@@ -64,7 +66,9 @@
struct _timeb *
struct _utimbuf *
struct _wfinddata_t *
+struct tm *
terminate_function
+time_t *
type_info *
unexpected_function
unsigned char *
diff --git a/tools/winapi_check/winapi.pm b/tools/winapi_check/winapi.pm
index ec47a45..fd681cb 100644
--- a/tools/winapi_check/winapi.pm
+++ b/tools/winapi_check/winapi.pm
@@ -689,6 +689,30 @@
return sort(@names);
}
+sub all_external_functions {
+ my $self = shift;
+ my $function_internal_name = \%{$self->{FUNCTION_INTERNAL_NAME}};
+
+ return sort(keys(%$function_internal_name));
+}
+
+sub all_external_functions_in_module {
+ my $self = shift;
+ my $function_internal_name = \%{$self->{FUNCTION_INTERNAL_NAME}};
+ my $function_external_module = \%{$self->{FUNCTION_EXTERNAL_MODULE}};
+
+ my $module = shift;
+
+ my @names;
+ foreach my $name (keys(%$function_internal_name)) {
+ if($$function_external_module{$name} eq $module) {
+ push @names, $name;
+ }
+ }
+
+ return sort(@names);
+}
+
sub all_functions_stub {
my $self = shift;
my $function_stub = \%{$self->{FUNCTION_STUB}};
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index dfa13e2..9f24692 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -238,7 +238,9 @@
$win16api->found_type($argument) if $options->win16;
$win32api->found_type($argument) if $options->win32;
}
+ }
+ if($options->declared) {
$win16api->found_internal_function($internal_name) if $options->win16;
$win32api->found_internal_function($internal_name) if $options->win32;
}
@@ -355,7 +357,7 @@
if($options->local && $options->documentation &&
(defined($module16) || defined($module32)) &&
- $linkage ne "extern" && defined($statements))
+ $linkage ne "static" && ($linkage ne "" || defined($statements)))
{
winapi_documentation::check_documentation $options, $output, $win16api, $win32api, $modules, $function;
}
@@ -488,6 +490,51 @@
$output->hide_progress;
+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 ($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; }
+ foreach my $internal_name ($winapi->all_internal_functions_in_module($module)) {
+ if(!$winapi->internal_function_found($internal_name)) {
+ $output->write("*.c: $module: $internal_name: " .
+ "function declared but not implemented or declared external\n");
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
if($options->global) {
winapi_documentation::report_documentation $options, $output;
diff --git a/tools/winapi_check/winapi_documentation.pm b/tools/winapi_check/winapi_documentation.pm
index 78abc2b..36eb438 100644
--- a/tools/winapi_check/winapi_documentation.pm
+++ b/tools/winapi_check/winapi_documentation.pm
@@ -3,6 +3,7 @@
use strict;
use config qw($current_dir $wine_dir);
+use nativeapi qw($nativeapi);
my %comment_width;
my %comment_indent;
diff --git a/tools/winapi_check/winapi_function.pm b/tools/winapi_check/winapi_function.pm
index ed334ae..b43f7ab 100644
--- a/tools/winapi_check/winapi_function.pm
+++ b/tools/winapi_check/winapi_function.pm
@@ -68,7 +68,7 @@
}
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_names32 { my $self = shift; return $self->_external_names($win32api, @_); }
diff --git a/tools/winapi_check/winapi_global.pm b/tools/winapi_check/winapi_global.pm
index 99621b7..b926101 100644
--- a/tools/winapi_check/winapi_global.pm
+++ b/tools/winapi_check/winapi_global.pm
@@ -19,16 +19,6 @@
}
}
- if($options->declared) {
- foreach my $internal_name ($winapi->all_internal_functions) {
- if(!$winapi->internal_function_found($internal_name) && !$nativeapi->is_function($internal_name)) {
- my $module = $winapi->function_internal_module($internal_name);
- $output->write("*.c: $module: $internal_name: ");
- $output->write("function declared but not implemented: " . $winapi->function_internal_arguments($internal_name) . "\n");
- }
- }
- }
-
if($options->argument && $options->argument_forbidden) {
my $not_used = $winapi->types_not_used;
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index b17e7f7..3ecda04 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -56,6 +56,10 @@
my $function_end = sub {
my $function = 'winapi_function'->new;
+ if(!defined($documentation_line)) {
+ $documentation_line = 0;
+ }
+
$function->file($file);
$function->debug_channels([@$debug_channels]);
$function->documentation($documentation);