From bda507405e9c6604bc311cfba7af49d3b6f22b4d Mon Sep 17 00:00:00 2001 From: Patrik Stridvall Date: Sat, 14 Jul 2001 00:48:41 +0000 Subject: [PATCH] Several additions and bug fixes. --- tools/winapi/output.pm | 11 ++-- tools/winapi/winapi_extract | 4 ++ tools/winapi/winapi_fixup | 14 ++--- tools/winapi_check/modules.dat | 1 - tools/winapi_check/modules.pm | 65 ++++++++++++++-------- tools/winapi_check/nativeapi.pm | 19 +++++-- tools/winapi_check/output.pm | 11 ++-- tools/winapi_check/win32/msvcrt.api | 4 ++ tools/winapi_check/winapi.pm | 24 ++++++++ tools/winapi_check/winapi_check | 49 +++++++++++++++- tools/winapi_check/winapi_documentation.pm | 1 + tools/winapi_check/winapi_function.pm | 2 +- tools/winapi_check/winapi_global.pm | 10 ---- tools/winapi_check/winapi_parser.pm | 4 ++ 14 files changed, 165 insertions(+), 54 deletions(-) diff --git a/tools/winapi/output.pm b/tools/winapi/output.pm index a085f9527ff..6234d6c9d7a 100644 --- a/tools/winapi/output.pm +++ b/tools/winapi/output.pm @@ -23,6 +23,9 @@ package _output; 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 @@ sub show_progress { $$progress_count++; - if($$progress_count > 0 && $$progress) { + if($$progress_count > 0 && $$progress && $stderr_isatty) { print STDERR $$progress; $$last_progress = $$progress; } @@ -65,7 +68,7 @@ sub hide_progress { $$progress_count--; - if($$last_progress) { + if($$last_progress && $stderr_isatty) { my $message; for (1..length($$last_progress)) { $message .= " "; @@ -124,9 +127,9 @@ sub write { 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 c725ab45563..981a4b40745 100755 --- a/tools/winapi/winapi_extract +++ b/tools/winapi/winapi_extract @@ -14,6 +14,7 @@ use config qw( $current_dir $wine_dir $winapi_dir $winapi_check_dir ); use modules; +use nativeapi; use output; use options; use winapi; @@ -89,6 +90,9 @@ if($wine_dir eq ".") { '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 3b214d8eec7..a10dc4c9f34 100755 --- a/tools/winapi/winapi_fixup +++ b/tools/winapi/winapi_fixup @@ -106,7 +106,7 @@ foreach my $file (@c_files) { 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 $file (@c_files) { 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 @@ foreach my $file (@c_files) { 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 @@ foreach my $file (@c_files) { } # 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 fdbb4058208..eb72aba5dca 100644 --- a/tools/winapi_check/modules.dat +++ b/tools/winapi_check/modules.dat @@ -346,7 +346,6 @@ dlls/user controls dlls/kernel dlls/user -memory misc windows diff --git a/tools/winapi_check/modules.pm b/tools/winapi_check/modules.pm index 25f109e5f95..1252422efab 100644 --- a/tools/winapi_check/modules.pm +++ b/tools/winapi_check/modules.pm @@ -19,7 +19,8 @@ sub new { 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 @@ sub new { } 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 @@ sub new { 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 @@ sub spec_file_module { 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 @@ sub is_allowed_module_in_file { 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 is_allowed_module_in_file { 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 @@ sub allowed_modules_in_file { $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 @@ sub allowed_spec_files { 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 @@ sub global_report { 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 5c5c338b2fe..e73a6ca7136 100644 --- a/tools/winapi_check/nativeapi.pm +++ b/tools/winapi_check/nativeapi.pm @@ -2,6 +2,15 @@ package nativeapi; 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 @@ sub new { open(IN, "< $api_file"); local $/ = "\n"; while() { - 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 @@ sub new { } close(IN); + $nativeapi = $self; + return $self; } diff --git a/tools/winapi_check/output.pm b/tools/winapi_check/output.pm index f5241aff72a..c6347ee8525 100644 --- a/tools/winapi_check/output.pm +++ b/tools/winapi_check/output.pm @@ -2,6 +2,9 @@ package output; 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 @@ sub show_progress { $$progress_count++; - if($$progress_count > 0 && $$progress) { + if($$progress_count > 0 && $$progress && $stderr_isatty) { print STDERR $$progress; $$last_progress = $$progress; } @@ -44,7 +47,7 @@ sub hide_progress { $$progress_count--; - if($$last_progress) { + if($$last_progress && $stderr_isatty) { my $message; for (1..length($$last_progress)) { $message .= " "; @@ -103,9 +106,9 @@ sub write { 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 173aba2587a..6399e023e1c 100644 --- a/tools/winapi_check/win32/msvcrt.api +++ b/tools/winapi_check/win32/msvcrt.api @@ -15,6 +15,7 @@ WCHAR int long size_t +time_t unsigned int unsigned long @@ -55,6 +56,7 @@ bad_typeid * char * char ** char *** +double * exception * int * jmp_buf @@ -64,7 +66,9 @@ struct _stat * 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 ec47a45e7a7..fd681cb91e1 100644 --- a/tools/winapi_check/winapi.pm +++ b/tools/winapi_check/winapi.pm @@ -689,6 +689,30 @@ sub all_internal_functions_in_module { 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 dfa13e21d36..9f2469200e7 100755 --- a/tools/winapi_check/winapi_check +++ b/tools/winapi_check/winapi_check @@ -238,7 +238,9 @@ foreach my $file (@c_files) { $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 @@ foreach my $file (@c_files) { 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 @@ foreach my $file (@c_files) { $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 78abc2b3d2b..36eb4386486 100644 --- a/tools/winapi_check/winapi_documentation.pm +++ b/tools/winapi_check/winapi_documentation.pm @@ -3,6 +3,7 @@ package winapi_documentation; 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 ed334aee2a5..b43f7abe947 100644 --- a/tools/winapi_check/winapi_function.pm +++ b/tools/winapi_check/winapi_function.pm @@ -68,7 +68,7 @@ sub _external_names { } 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 99621b71679..b9261019b84 100644 --- a/tools/winapi_check/winapi_global.pm +++ b/tools/winapi_check/winapi_global.pm @@ -19,16 +19,6 @@ sub check { } } - 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 b17e7f7518a..3ecda0473a1 100644 --- a/tools/winapi_check/winapi_parser.pm +++ b/tools/winapi_check/winapi_parser.pm @@ -56,6 +56,10 @@ sub parse_c_file { 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);