Several additions and bug fixes.

This commit is contained in:
Patrik Stridvall 2001-07-18 20:09:12 +00:00 committed by Alexandre Julliard
parent fcef026169
commit d07a646f0f
15 changed files with 283 additions and 343 deletions

View File

@ -12,7 +12,7 @@ require Exporter;
&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 @@ sub file_normalize {
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;

View File

@ -34,11 +34,13 @@ sub new {
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 update_progress {
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 {

View File

@ -50,9 +50,7 @@ BEGIN {
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;

View File

@ -55,7 +55,7 @@ my %module2type;
{
local $_;
foreach my $spec_file (get_spec_files) {
foreach my $spec_file (get_spec_files("winelib")) {
my $module;
my $type;
@ -177,13 +177,15 @@ sub statements_stub {
}
}
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++;

View File

@ -133,6 +133,10 @@ sub is_allowed_module_in_file {
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;

View File

@ -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;

View File

@ -14,8 +14,6 @@ MSVCRT_time_t
WCHAR
int
long
size_t
time_t
unsigned int
unsigned long
@ -56,7 +54,6 @@ bad_typeid *
char *
char **
char ***
double *
exception *
int *
jmp_buf
@ -66,13 +63,12 @@ struct _stat *
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 *

View File

@ -84,7 +84,6 @@ REFGUID
REFIID
SNB
STGMEDIUM *
WCHAR *
WORD *
void *
void **

View File

@ -89,6 +89,10 @@ REFCLSID
REFIID
UINT *
%ptr # --forbidden
int *
%str
LPCSTR

View File

@ -26,6 +26,10 @@ sub new {
$$name = shift;
my $path = shift;
if($$options->progress) {
$$output->progress("$path: searching for *.api");
}
my @files = map {
s%^\./%%;
$_;
@ -33,6 +37,11 @@ sub new {
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 @@ sub parse_spec_file {
my $module_file;
if($$options->progress) {
$$output->progress("$file");
$$output->lazy_progress("$file");
}
open(IN, "< $file") || die "$file: $!\n";
@ -585,24 +594,6 @@ sub all_declared_types {
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 @@ sub all_functions_stub_in_module {
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 @@ sub is_function_stub_in_module {
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
#

View File

@ -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 @@ BEGIN {
}
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 @@ if($options->global) {
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 %includes;
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->headers) {
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 @@ foreach my $file (@c_files) {
$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 @@ foreach my $file (@c_files) {
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($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(defined($declared_function)) {
$needed_includes{$declared_function->file}++;
}
if(1) {
# FIXME: Not correct
if(defined($external_name16)) {
$external_name16 = (split(/\s*&\s*/, $external_name16))[0];
@ -307,20 +290,15 @@ foreach my $file (@c_files) {
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 @@ foreach my $file (@c_files) {
$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 @@ foreach my $file (@c_files) {
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 @@ foreach my $file (@c_files) {
}
}
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 @@ foreach my $file (@c_files) {
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) {
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->declared) {
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 @@ if($options->global) {
}
}
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;

View File

@ -21,6 +21,13 @@ sub new {
return $self;
}
########################################################################
# 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 @@ sub prefix {
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 @@ sub prefix {
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 {

View File

@ -7,12 +7,13 @@ sub check {
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");
}

View File

@ -118,9 +118,12 @@ my %options = (
"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 @@ sub new {
my $h_files = \@{$self->{H_FILES}};
my $module = \${$self->{MODULE}};
my $global = \${$self->{GLOBAL}};
my $headers = \${$self->{HEADERS}};
my @files;
@ -285,11 +289,14 @@ sub new {
}
}
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 @@ sub new {
} 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 {

View File

@ -62,8 +62,9 @@ sub parse_c_file {
$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 @@ sub parse_c_file {
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)
{