- API files update.

- Add new options --all and --none that enable/disables all check
  respectively.
- Fixed and improved stub statistics.
- Fixed bug that prevented checking of the first function in the .spec files.
- Partial implementation of a more advanced misplaced function checking.
- Minor fixes.
This commit is contained in:
Patrik Stridvall 2000-04-15 20:39:55 +00:00 committed by Alexandre Julliard
parent 1d20af694c
commit 1932d402ec
41 changed files with 774 additions and 115 deletions

View File

@ -0,0 +1,342 @@
% dlls/advapi32/advapi32.spec
dlls/advapi32
% dlls/avifil32/avifil32.spec
dlls/avifil32
% dlls/avifil32/avifile.spec
dlls/avifil32
% dlls/comctl32/comctl32.spec
dlls/comctl32
% dlls/commdlg/comdlg32.spec
dlls/commdlg
% dlls/commdlg/commdlg.spec
dlls/commdlg
% dlls/crtdll/crtdll.spec
dlls/crtdll
% dlls/dciman32/dciman32.spec
dlls/dciman32
% dlls/ddraw/ddraw.spec
dlls/ddraw
% dlls/dinput/dinput.spec
dlls/dinput
% dlls/display/display.spec
dlls/display
% dlls/dplayx/dplay.spec
dlls/dplayx
% dlls/dplayx/dplayx.spec
dlls/dplayx
% dlls/dsound/dsound.spec
dlls/dsound
% dlls/gdi/gdi.spec
dlls/gdi
% dlls/gdi/gdi32.spec
dlls/gdi
% dlls/icmp/icmp.spec
dlls/icmp
% dlls/imagehlp/imagehlp.spec
dlls/imagehlp
% dlls/imm32/imm32.spec
dlls/imm32
% dlls/lzexpand/lz32.spec
dlls/lzexpand
% dlls/lzexpand/lzexpand.spec
dlls/lzexpand
% dlls/mouse/mouse.spec
dlls/mouse
% dlls/mpr/mpr.spec
dlls/mpr
% dlls/msacm/msacm.spec
dlls/msacm
% dlls/msacm32/msacm32.spec
dlls/msacm32
% dlls/msnet32/msnet32.spec
dlls/msnet32
% dlls/msvideo/msvfw32.spec
dlls/msvideo
% dlls/msvideo/msvideo.spec
dlls/msvideo
% dlls/ntdll/ntdll.spec
dlls/ntdll
% dlls/odbc32/odbc32.spec
dlls/odbc32
% dlls/ole32/compobj.spec
dlls/ole32
% dlls/ole32/ole2.spec
dlls/ole32
% dlls/ole32/ole32.spec
dlls/ole32
% dlls/ole32/storage.spec
dlls/ole32
% dlls/oleaut32/ole2disp.spec
dlls/oleaut32
% dlls/oleaut32/oleaut32.spec
dlls/oleaut32
% dlls/oleaut32/typelib.spec
dlls/oleaut32
% dlls/olecli/olecli.spec
dlls/olecli
% dlls/olecli/olecli32.spec
dlls/olecli
% dlls/oledlg/oledlg.spec
dlls/oledlg
% dlls/olepro32/olepro32.spec
dlls/olepro32
% dlls/olesvr/olesvr.spec
dlls/olesvr
% dlls/olesvr/olesvr32.spec
dlls/olesvr
% dlls/psapi/psapi.spec
dlls/psapi
% dlls/rasapi32/rasapi16.spec
dlls/rasapi32
% dlls/rasapi32/rasapi32.spec
dlls/rasapi32
% dlls/setupx/setupx.spec
dlls/setupx
% dlls/shell32/shell.spec
dlls/shell32
% dlls/shell32/shell32.spec
dlls/shell32
% dlls/shell32/shlwapi.spec
dlls/shell32
% dlls/sound/sound.spec
dlls/sound
% dlls/stress/stress.spec
dlls/stress
% dlls/tapi32/tapi32.spec
dlls/tapi32
% dlls/ttydrv/ttydrv.spec
dlls/ttydrv
% dlls/user/keyboard.spec
dlls/user
% dlls/user/user.spec
dlls/user
% dlls/user/user32.spec
dlls/user
% dlls/version/ver.spec
dlls/version
% dlls/version/version.spec
dlls/version
% dlls/win32s/w32skrnl.spec
dlls/win32s
% dlls/win32s/w32sys.spec
dlls/win32s
% dlls/win32s/win32s16.spec
dlls/win32s
% dlls/win87em/win87em.spec
dlls/win87em
% dlls/winaspi/winaspi.spec
dlls/winaspi
% dlls/winaspi/wnaspi32.spec
dlls/winaspi
% dlls/windebug/windebug.spec
dlls/windebug
% dlls/wing/wing.spec
dlls/wing
% dlls/winmm/joystick/joystick.spec
dlls/winmm/joystick
% dlls/winmm/mcianim/mcianim.spec
dlls/winmm/mcianim
% dlls/winmm/mciavi/mciavi.spec
dlls/winmm/mciavi
% dlls/winmm/mcicda/mcicda.spec
dlls/winmm/mcicda
% dlls/winmm/mciseq/mciseq.spec
dlls/winmm/mciseq
% dlls/winmm/mciwave/mciwave.spec
dlls/winmm/mciwave
% dlls/winmm/midimap/midimap.spec
dlls/winmm/midimap
% dlls/winmm/wavemap/msacm.spec
dlls/winmm/wavemap
% dlls/winmm/wineoss/wineoss.spec
dlls/winmm/wineoss
% dlls/winmm/mmsystem.spec
dlls/winmm
% dlls/winmm/winmm.spec
dlls/winmm/winmm
% dlls/winsock/winsock.spec
dlls/winsock
% dlls/winsock/wsock32.spec
dlls/winsock
% dlls/winspool/winspool.spec
dlls/winspool
% dlls/x11drv/x11drv.spec
dlls/x11drv
% if1632/comm.spec
% if1632/ddeml.spec
% if1632/dispdib.spec
% if1632/kernel.spec
% if1632/ole2conv.spec
% if1632/ole2nls.spec
% if1632/ole2prox.spec
% if1632/ole2thk.spec
% if1632/system.spec
% if1632/toolhelp.spec
% if1632/wineps.spec
% if1632/wprocs.spec
% relay32/kernel32.spec
% relay32/wow32.spec

View File

@ -0,0 +1,49 @@
package modules;
use strict;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless ($self, $class);
my $options = \${$self->{OPTIONS}};
my $output = \${$self->{OUTPUT}};
my $modules = \%{$self->{MODULES}};
$$options = shift;
$$output = shift;
my $module_file = shift;
$module_file =~ s/^\.\///;
if($$options->progress) {
$$output->progress("$module_file");
}
my $allowed_dir;
my $spec_file;
open(IN, "< $module_file");
local $/ = "\n";
while(<IN>) {
s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begining and end of line
s/^(.*?)\s*#.*$/$1/; # remove comments
/^$/ && next; # skip empty lines
if(/^%\s+(.*?)$/) {
$spec_file = $1;
next;
} else {
$allowed_dir = $1;
}
$$modules{$allowed_dir}{$spec_file}++;
}
close(IN);
return $self;
}
1;

View File

@ -8,12 +8,14 @@ sub new {
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;
@ -23,10 +25,12 @@ sub new {
$configure_in_file =~ s/^\.\///;
$config_h_in_file =~ s/^\.\///;
$$output->progress("$api_file");
if($$options->progress) {
$$output->progress("$api_file");
}
open(IN, "< $api_file");
$/ = "\n";
local $/ = "\n";
while(<IN>) {
s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
s/^(.*?)\s*#.*$/$1/; # remove comments
@ -36,7 +40,9 @@ sub new {
}
close(IN);
$$output->progress("$configure_in_file");
if($$options->progress) {
$$output->progress("$configure_in_file");
}
my $again = 0;
open(IN, "< $configure_in_file");
@ -72,7 +78,9 @@ sub new {
}
close(IN);
$$output->progress("$config_h_in_file");
if($$options->progress) {
$$output->progress("$config_h_in_file");
}
open(IN, "< $config_h_in_file");
local $/ = "\n";

View File

@ -17,6 +17,7 @@ LPCONVCONTEXT16
LPCONVINFO16
LPDWORD
LPVOID
PFNCALLBACK16
%str

View File

@ -0,0 +1,11 @@
%ptr
LPBITMAPINFO
%str
LPSTR
%word
WORD

View File

@ -6,6 +6,7 @@ LONG
%ptr
LPBYTE
LPKBINFO
LPVOID
%segptr

View File

@ -1,7 +1,15 @@
%ptr
LPMOUSEINFO
%segptr
FARPROC16
%void
VOID
VOID
%word
WORD

View File

@ -6,7 +6,9 @@ LHSERVERDOC
%ptr
BOOL16 *
LHSERVER *
LHSERVERDOC *
LPOLESERVER
LPOLESERVERDOC
%str
@ -15,4 +17,6 @@ LPCSTR
%word
HINSTANCE16
OLE_SERVER_USE
OLESTATUS

View File

@ -1,5 +1,6 @@
%long
DWORD
LONG
%void

View File

@ -4,6 +4,7 @@ int
%ptr
CONTEXT86 *
struct Win87EmInfoStruct *
void *

View File

@ -11,6 +11,10 @@ LPDEVMODEA
LPCSTR
LPSTR
%void
void
%word
HANDLE16

View File

@ -5,6 +5,9 @@ DWORD
%ptr
CONTEXT86 *
FARPROC
LPVOID
SEGPTR *
%segptr

View File

@ -12,6 +12,7 @@ HDSA
HICON
HIMAGELIST
HINSTANCE
HMENU
HPROPSHEETPAGE
HRESULT
HWND
@ -21,6 +22,8 @@ LPARAM
LRESULT
UINT
WORD
WPARAM
%long # --forbidden
@ -38,6 +41,7 @@ LPCVOID
LPINT
LPRECT
LPSTR *
LPUINT
LPVOID
LPWSTR *
POINT *

View File

@ -0,0 +1,10 @@
%long
DWORD
HINSTANCE
HRESULT
%ptr
LPDIRECTINPUTA *
LPUNKNOWN

View File

@ -6,6 +6,7 @@ HRESULT
%ptr
IUnknown *
LPDIRECTPLAY2 *
LPDIRECTPLAYLOBBY *
LPDIRECTPLAYLOBBYA *
LPDPENUMDPCALLBACKA

View File

@ -105,6 +105,10 @@ TEXTMETRICW *
XFORM *
void *
%ptr # --forbidden
FARPROC16
%str
LPCSTR

View File

@ -1,5 +1,6 @@
%long
BOOL
DWORD
HANDLE
IPAddr

View File

@ -0,0 +1,5 @@
%long
DWORD
HDRVR
LONG

View File

@ -53,6 +53,8 @@ CONTEXT86 *
CODEPAGE_ENUMPROCA
CODEPAGE_ENUMPROCW
CRITICAL_SECTION *
CURRENCYFMTA *
CURRENCYFMTW *
DATEFMT_ENUMPROCA
DATEFMT_ENUMPROCW
ENUMRESLANGPROCA

View File

@ -0,0 +1,6 @@
%long
DWORD
HDRVR
LONG

View File

@ -0,0 +1,5 @@
%long
DWORD
HDRVR
LONG

View File

@ -0,0 +1,6 @@
%long
DWORD
HDRVR
LONG

View File

@ -0,0 +1,6 @@
%long
DWORD
HDRVR
LONG

View File

@ -0,0 +1,5 @@
%long
DWORD
HDRVR
LONG

View File

@ -1,5 +1,7 @@
%long
DWORD
HDRVR
LONG
UINT
WORD

View File

@ -1,5 +1,7 @@
%long
DWORD
HDRVR
LONG
UINT
WORD

View File

@ -48,6 +48,7 @@ EXCEPTION_RECORD *
HANDLE *
LPBYTE
LPDWORD
LPDWORD *
LPFILETIME
LPRTL_RWLOCK
LPVOID

View File

@ -19,6 +19,7 @@ SQLRETURNTYPE
SQLCHAR *
SQLHANDLE *
SQLHDBC *
SQLHENV *
SQLHSTMT *
SQLINTEGER *

View File

@ -32,6 +32,7 @@ REFCLSID
%str
LPCSTR
LPSTR
%wstr

View File

@ -22,6 +22,7 @@ LRESULT
UINT
ULONG
WCHAR
WORD
WPARAM
%long # --forbidden
@ -43,6 +44,7 @@ LPBROWSEINFOA
LPBYTE
LPCITEMIDLIST
LPCITEMIDLIST *
LPCNOTIFYREGISTER
LPCVOID
LPDRAWITEMSTRUCT
LPDWORD

View File

@ -10,6 +10,7 @@ HRESULT
HWND
UINT
WCHAR
WORD
%long # --forbidden

View File

@ -0,0 +1,12 @@
%long
HRESULT
%ptr
IMoniker *
IMoniker **
%wstr
LPWSTR

View File

@ -40,10 +40,9 @@ WCHAR
WORD
WPARAM
%long --forbidden
%long # --forbidden
HMODULE16
int
%longlong

View File

@ -1,5 +1,7 @@
%long
DWORD
HDRVR
LONG
UINT
WORD

View File

@ -0,0 +1,20 @@
%long
BOOL
DWORD
HINTERNET
INTERNET_PORT
%ptr
LPCVOID
LPDWORD
LPURL_COMPONENTSA
LPVOID
LPWIN32_FIND_DATAA
INTERNET_STATUS_CALLBACK
%str
LPCSTR
LPSTR

View File

@ -33,6 +33,8 @@ sub new {
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}};
@ -47,7 +49,9 @@ sub parse_api_file {
my $extension = 0;
my $forbidden = 0;
$$output->progress("$file");
if($$options->progress) {
$$output->progress("$file");
}
open(IN, "< $file") || die "$file: $!\n";
$/ = "\n";
@ -124,12 +128,17 @@ sub read_spec_files {
my $class = ref($proto) || $proto;
my $path = shift;
my $file_type = shift;
my $win16api = shift;
my $win32api = shift;
my @files = map {
s/^.\/(.*)$/$1/;
$_;
if(&$file_type($_) eq "library") {
$_;
} else {
();
}
} split(/\n/, `find $path -name \\*.spec`);
foreach my $file (@files) {
@ -151,6 +160,7 @@ sub parse_spec_file {
my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
my $function_stub = \%{$self->{FUNCTION_STUB}};
my $function_module = \%{$self->{FUNCTION_MODULE}};
my $modules = \%{$self->{MODULES}};
my $file = shift;
@ -158,7 +168,9 @@ sub parse_spec_file {
my $type;
my $module;
$$output->progress("$file");
if($$options->progress) {
$$output->progress("$file");
}
open(IN, "< $file") || die "$file: $!\n";
$/ = "\n";
@ -173,7 +185,7 @@ sub parse_spec_file {
if($header) {
if(/^name\s*(\S*)/) { $module = $1; }
if(/^type\s*(\w+)/) { $type = $1; }
if(/^\d+|@/) { $header = 0 };
if(/^\d+|@/) { $header = 0; $lookahead = 1; }
next;
}
@ -249,7 +261,7 @@ sub parse_spec_file {
# ignore
} else {
my $next_line = <IN>;
if($next_line =~ /^\d|@/) {
if(!defined($next_line) || $next_line =~ /^\s*\d|@/) {
die "$file: $.: syntax error: '$_'\n";
} else {
$_ .= $next_line;
@ -265,6 +277,8 @@ sub parse_spec_file {
}
}
close(IN);
$$modules{$module}++;
}
sub name {
@ -401,6 +415,13 @@ sub type_found {
return $$type_found{$name};
}
sub all_modules {
my $self = shift;
my $modules = \%{$self->{MODULES}};
return sort(keys(%$modules));
}
sub all_functions {
my $self = shift;
my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};

View File

@ -21,6 +21,7 @@ BEGIN {
}
@INC = ($winapi_check_dir);
require "modules.pm";
require "nativeapi.pm";
require "output.pm";
require "preprocessor.pm";
@ -31,6 +32,7 @@ BEGIN {
require "winapi_options.pm";
require "winapi_parser.pm";
import modules;
import nativeapi;
import output;
import preprocessor;
@ -50,11 +52,36 @@ if($options->help) {
my $output = 'output'->new;
my $modules = 'modules'->new($options, $output, "$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");
'winapi'->read_spec_files($wine_dir, $win16api, $win32api);
my $nativeapi = 'nativeapi'->new($output, "$winapi_check_dir/nativeapi.dat", "$wine_dir/configure.in", "$wine_dir/include/config.h.in");
sub file_type {
my $file = shift;
my $file_dir = $file;
if(!($file_dir =~ s/(.*?)\/[^\/]*$/$1/)) {
$file_dir = ".";
}
$file_dir =~ s/^$wine_dir\///;
if($file_dir =~ /^(libtest|program|rc|tools)/ ||
$file =~ /dbgmain\.c$/ ||
$file =~ /wineclipsrv\.c$/) # FIXME: Kludge
{
return "application";
} elsif($file_dir =~ /^(debug|miscemu)/) {
return "emulator";
} else {
return "library";
}
}
'winapi'->read_spec_files($wine_dir, \&file_type, $win16api, $win32api);
my $nativeapi = 'nativeapi'->new($options, $output, "$winapi_check_dir/nativeapi.dat", "$wine_dir/configure.in", "$wine_dir/include/config.h.in");
for my $name ($win32api->all_functions) {
my $module16 = $win16api->function_module($name);
@ -94,7 +121,7 @@ my %includes;
} elsif(-e "$wine_dir/include/$header") {
$includes{$file}{includes}{"include/$header"}++;
} else {
$output->write("$file: #include \"$header\" is not a local include ($file_dir)\n");
$output->write("$file: #include \"$header\" is not a local include\n");
}
}
}
@ -153,6 +180,8 @@ my %module_pseudo_stub_count32;
foreach my $file ($options->c_files) {
my %functions = ();
my $file_module16;
my $file_module32;
$progress_current++;
if($options->progress) {
@ -163,18 +192,8 @@ foreach my $file ($options->c_files) {
if(!($file_dir =~ s/(.*?)\/[^\/]*$/$1/)) {
$file_dir = ".";
}
my $file_type;
if($file_dir =~ /^(libtest|program|rc|tools)/ ||
$file =~ /dbgmain\.c$/ ||
$file =~ /wineclipsrv\.c$/) # FIXME: Kludge
{
$file_type = "application";
} elsif($file_dir =~ /^(debug|miscemu)/) {
$file_type = "emulator";
} else {
$file_type = "library";
}
my $file_type = file_type($file);
my $found_function = sub {
my $documentation = shift;
@ -198,7 +217,7 @@ foreach my $file ($options->c_files) {
$win32api->found_function($name) if $options->win32;
}
if($options->local && $file_type ne "application") {
if($file_type ne "application") {
my $module16 = $win16api->function_module($name);
my $module32 = $win32api->function_module($name);
@ -228,7 +247,47 @@ foreach my $file ($options->c_files) {
my $output16 = &$output_module($module16);
my $output32 = &$output_module($module32);
if($options->headers) {
# FIXME: Improve heuristics
if(!defined($file_module16)) {
$file_module16 = $module16;
}
# FIXME: Improve heuristics
if(!defined($file_module32)) {
$file_module32 = $module32;
}
if($options->local && $options->misplaced) {
if($options->win16 && $options->report_module($module16)) {
my $match = 0;
foreach my $module (split(/ & /, $module16)) {
foreach my $file_module (split(/ & /, $file_module16)) {
if($module eq $file_module) {
$match++;
}
}
}
if(!$match) {
&$output16("doesn't belong to file module ($file_module16)");
}
}
if($options->win32 && $options->report_module($module32)) {
my $match = 0;
foreach my $module (split(/ & /, $module32)) {
foreach my $file_module (split(/ & /, $file_module32)) {
if($module eq $file_module) {
$match++;
}
}
}
if(!$match) {
&$output32("doesn't belong to file module ($file_module32)");
}
}
}
if($options->local && $options->headers) {
if(!$declared_functions{$name}) {
if($options->win16 && $options->report_module($module16)) {
&$output16("no prototype");
@ -239,7 +298,7 @@ foreach my $file ($options->c_files) {
}
}
if($options->argument) {
if($options->local && $options->argument) {
if($options->win16 && $options->report_module($module16)) {
winapi_local::check_function $options, $output16,
$return_type, $calling_convention, $name, [@arguments], $win16api;
@ -249,25 +308,8 @@ foreach my $file ($options->c_files) {
$return_type, $calling_convention, $name, [@arguments], $win32api;
}
}
if($options->misplaced) {
my $module;
if($file =~ m'^dlls/(.*)/') {
$module = $1;
}
if($options->win16 && $options->report_module($module16)) {
if(!defined($module) || $module ne $module16) {
&$output16("function misplaced");
}
}
if($options->win32 && $options->report_module($module32)) {
if(!defined($module) || $module ne $module32) {
&$output32("function misplaced");
}
}
}
if($options->cross_call) {
if($options->local && $options->cross_call) {
local $_ = $statements;
my $called_function_names = {};
while(defined($_)) {
@ -277,7 +319,7 @@ foreach my $file ($options->c_files) {
if($called_name !~ /^if|for|while|switch|sizeof$/) {
$functions{$name}->function_called($called_name);
if(!defined($functions{$called_name})) {
$functions{$called_name} = 'function'->new;
$functions{$called_name} = 'winapi_function'->new;
}
$functions{$called_name}->function_called_by($name);
}
@ -302,9 +344,10 @@ foreach my $file ($options->c_files) {
}
}
if($options->documentation && (defined($module16) || defined($module32)) &&
$linkage ne "extern" && $statements ne "")
{
if($options->local && $options->documentation &&
(defined($module16) || defined($module32)) &&
$linkage ne "extern" && $statements ne "")
{
my $name1;
my $name2;
@ -370,20 +413,23 @@ foreach my $file ($options->c_files) {
}
};
my $found_conditional = sub {
if($file_type ne "application") {
local $_ = shift;
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");
}
}
}
local $_ = shift;
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");
}
}
}
}
};
my $preprocessor = 'preprocessor'->new($found_include, $found_conditional);
my $found_preprocessor = sub {
@ -448,6 +494,11 @@ foreach my $file ($options->c_files) {
foreach my $name (keys(%{$includes{"$file_dir/$header"}{includes}})) {
$includes{$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/include/$header") {
$includes{"include/$header"}{used}++;
foreach my $name (keys(%{$includes{"include/$header"}{includes}})) {
@ -496,7 +547,7 @@ if($options->global) {
}
}
foreach my $module (sort(keys(%module_pseudo_stub_count16))) {
foreach my $module ($win16api->all_modules) {
if($options->report_module($module)) {
my $real_stubs = $module_stub_count16{$module};
my $pseudo_stubs = $module_pseudo_stub_count16{$module};
@ -507,9 +558,10 @@ if($options->global) {
my $stubs = $real_stubs + $pseudo_stubs;
my $total = $module_total_count16{$module};
if($stubs) {
$output->write("*.c: $module: $stubs of $total functions are stubs ($real_stubs real, $pseudo_stubs pseudo)\n");
}
if(!defined($total)) { $total = 0;}
$output->write("*.c: $module: ");
$output->write("$stubs of $total functions are stubs ($real_stubs real, $pseudo_stubs pseudo)\n");
}
}
}
@ -527,7 +579,7 @@ if($options->global) {
}
}
foreach my $module (sort(keys(%module_pseudo_stub_count32))) {
foreach my $module ($win32api->all_modules) {
if($options->report_module($module)) {
my $real_stubs = $module_stub_count32{$module};
my $pseudo_stubs = $module_pseudo_stub_count32{$module};
@ -538,9 +590,10 @@ if($options->global) {
my $stubs = $real_stubs + $pseudo_stubs;
my $total = $module_total_count32{$module};
if($stubs) {
$output->write("*.c: $module: $stubs of $total functions are stubs ($real_stubs real, $pseudo_stubs pseudo)\n");
}
if(!defined($total)) { $total = 0;}
$output->write("*.c: $module: ");
$output->write("$stubs of $total functions are stubs ($real_stubs real, $pseudo_stubs pseudo)\n");
}
}
}

View File

@ -29,7 +29,7 @@ sub check {
}
}
if($options->argument_forbidden) {
if($options->argument && $options->argument_forbidden) {
my $not_used = $winapi->types_not_used;
foreach my $module (sort(keys(%$not_used))) {

View File

@ -60,7 +60,7 @@ sub check_function {
$implemented_calling_convention = "cdecl";
} elsif($calling_convention =~ /^VFWAPIV|WINAPIV$/) {
$implemented_calling_convention = "varargs";
} elsif($calling_convention = ~ /^__stdcall|VFWAPI|WINAPI$/) {
} elsif($calling_convention = ~ /^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
if($implemented_return_kind =~ /^s_word|word|void$/) {
$implemented_calling_convention = "pascal16";
} else {
@ -72,7 +72,7 @@ sub check_function {
$implemented_calling_convention = "cdecl";
} elsif($calling_convention =~ /^VFWAPIV|WINAPIV$/) {
$implemented_calling_convention = "varargs";
} elsif($calling_convention =~ /^__stdcall|VFWAPI|WINAPI$/) {
} elsif($calling_convention =~ /^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
$implemented_calling_convention = "stdcall";
} else {
$implemented_calling_convention = "<default>";

View File

@ -89,23 +89,18 @@ sub new {
my @ARGV = @$refarguments;
my $wine_dir = shift;
for my $name (sort(keys(%options))) {
my $option = $options{$name};
my $key = uc($name);
$key =~ tr/-/_/;
$$option{key} = $key;
my $refvalue = \${$self->{$key}};
$$refvalue = $$option{default};
}
$self->options_set("default");
my $c_files = \@{$self->{C_FILES}};
my $h_files = \@{$self->{H_FILES}};
my $module = \${$self->{MODULE}};
my $global = \${$self->{GLOBAL}};
$$global = 0;
while(defined($_ = shift @ARGV)) {
if(/^-([^=]*)(=(.*))?$/) {
if(/^--(all|none)$/) {
$self->options_set("$1");
next;
} elsif(/^-([^=]*)(=(.*))?$/) {
my $name;
my $value;
if(defined($2)) {
@ -122,7 +117,7 @@ sub new {
}
my $prefix;
if($name =~ /^no-(.*)$/) {
if(defined($name) && $name =~ /^no-(.*)$/) {
$name = $1;
$prefix = "no";
if(defined($value)) {
@ -131,12 +126,17 @@ sub new {
}
}
my $option = $options{$name};
my $option;
if(defined($name)) {
$option = $options{$name};
}
if(defined($option)) {
my $key = $$option{key};
my $parser = $$option{parser};
my $parent = $$option{parent};
my $refvalue = \${$self->{$key}};
if(defined($parser)) {
$$refvalue = &$parser($prefix,$value);
} else {
@ -148,12 +148,22 @@ sub new {
$$refvalue = 0;
}
}
if((ref($$refvalue) eq "HASH" && $$refvalue->{active}) || $$refvalue) {
while(defined($parent)) {
my $parentkey = $options{$parent}{key};
my $refparentvalue = \${$self->{$parentkey}};
$$refparentvalue = 1;
$parent = $options{$parent}{parent};
}
}
next;
}
}
if(/^--module-dlls$/) {
my @dirs = `cd dlls && find ./ -type d ! -name CVS`;
my @dirs = `cd dlls && find . -type d ! -name CVS`;
my %names;
for my $dir (@dirs) {
chomp $dir;
@ -173,11 +183,11 @@ sub new {
}
my $c_paths;
if($#$c_files == -1) {
if($#$c_files == -1 || ($#$c_files == 0 && $$c_files[0] eq $wine_dir)) {
$c_paths = ".";
$$global = 1;
} else {
$c_paths = join(" ", @$c_files);
$$global = 0;
}
my $h_paths = "$wine_dir/include $wine_dir/include/wine";
@ -199,6 +209,39 @@ sub new {
return $self;
}
sub options_set {
my $self = shift;
local $_ = shift;
for my $name (sort(keys(%options))) {
my $option = $options{$name};
my $key = uc($name);
$key =~ tr/-/_/;
$$option{key} = $key;
my $refvalue = \${$self->{$key}};
if(/^default$/) {
$$refvalue = $$option{default};
} elsif(/^all$/) {
if($name !~ /^help|debug|verbose|module$/) {
if(ref($$refvalue) ne "HASH") {
$$refvalue = 1;
} else {
$$refvalue = { active => 1, filter => 0, hash => {} };
}
}
} elsif(/^none$/) {
if($name !~ /^help|debug|verbose|module$/) {
if(ref($$refvalue) ne "HASH") {
$$refvalue = 0;
} else {
$$refvalue = { active => 0, filter => 0, hash => {} };
}
}
}
}
}
sub show_help {
my $self = shift;
@ -215,16 +258,19 @@ sub show_help {
my $option = $options{$name};
my $description = $$option{description};
my $default = $$option{default};
my $current = ${$self->{$$option{key}}};
my $value = $current;
my $output;
if(ref($default) ne "HASH") {
if($default) {
if(ref($value) ne "HASH") {
if($value) {
$output = "--no-$name";
} else {
$output = "--$name";
}
} else {
if($default->{active}) {
if($value->{active}) {
$output = "--[no-]$name\[=<value>]";
} else {
$output = "--$name\[=<value>]";
@ -232,22 +278,25 @@ sub show_help {
}
print "$output";
for (0..(($maxname - length($name) + 14) - (length($output) - length($name) + 1))) { print " "; }
if(ref($default) ne "HASH") {
if($default) {
print "Disable $description\n";
for (0..(($maxname - length($name) + 17) - (length($output) - length($name) + 1))) { print " "; }
if(ref($value) ne "HASH") {
if($value) {
print "Disable ";
} else {
print "Enable $description\n";
print "Enable ";
}
} else {
if($default->{active}) {
print "(Disable) $description\n";
if($value->{active}) {
print "(Disable) ";
} else {
print "Enable $description\n";
print "Enable ";
}
}
if($default == $current) {
print "$description (default)\n";
} else {
print "$description\n";
}
}
}
@ -261,7 +310,12 @@ sub AUTOLOAD {
if(!defined($refvalue)) {
die "<internal>: winapi_options.pm: member $name does not exists\n";
}
return $$refvalue;
if(ref($$refvalue) ne "HASH") {
return $$refvalue;
} else {
return $$refvalue->{active};
}
}
sub c_files { my $self = shift; return @{$self->{C_FILES}}; }
@ -270,12 +324,12 @@ sub h_files { my $self = shift; return @{$self->{H_FILES}}; }
sub report_module {
my $self = shift;
my $module = $self->module;
my $refvalue = $self->{MODULE};
my $name = shift;
if(defined($name)) {
return $module->{active} && (!$module->{filter} || $module->{hash}->{$name});
return $$refvalue->{active} && (!$$refvalue->{filter} || $$refvalue->{hash}->{$name});
} else {
return 0;
}
@ -283,20 +337,20 @@ sub report_module {
sub report_argument_forbidden {
my $self = shift;
my $argument_forbidden = $self->argument_forbidden;
my $refargument_forbidden = $self->{ARGUMENT_FORBIDDEN};
my $type = shift;
return $argument_forbidden->{active} && (!$argument_forbidden->{filter} || $argument_forbidden->{hash}->{$type});
return $$refargument_forbidden->{active} && (!$$refargument_forbidden->{filter} || $$refargument_forbidden->{hash}->{$type});
}
sub report_argument_kind {
my $self = shift;
my $argument_kind = $self->argument_kind;
my $refargument_kind = $self->{ARGUMENT_KIND};
my $kind = shift;
return $argument_kind->{active} && (!$argument_kind->{filter} || $argument_kind->{hash}->{$kind});
return $$refargument_kind->{active} && (!$$refargument_kind->{filter} || $$refargument_kind->{hash}->{$kind});
}

View File

@ -179,13 +179,13 @@ sub parse_c_file {
&$function_end;
}
next;
} elsif(/(extern\s+|static\s+)?((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))((__cdecl|__stdcall|VFWAPIV|VFWAPI|WINAPIV|WINAPI)\s+)?(\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/s) {
} elsif(/(extern\s+|static\s+)?((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))((__cdecl|__stdcall|VFWAPIV|VFWAPI|WINAPIV|WINAPI|CALLBACK)\s+)?(\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/s) {
$_ = $'; $again = 1;
if($11 eq "{") {
$level++;
}
my $linkage = $1;
my $return_type = $2;
my $calling_convention = $7;