- Fixed the long long problem.
- Added configure include consistancy checking.
- Added progress indicator.
- Began splitting up the win16api.dat and win32api.dat files.
- Added various minor checks.
- Minor fixes.
diff --git a/tools/winapi_check/nativeapi.pm b/tools/winapi_check/nativeapi.pm
index 136689d..b59da36 100644
--- a/tools/winapi_check/nativeapi.pm
+++ b/tools/winapi_check/nativeapi.pm
@@ -9,17 +9,59 @@
bless ($self, $class);
my $functions = \%{$self->{FUNCTIONS}};
+ my $conditionals = \%{$self->{CONDITIONALS}};
+ my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
- my $file = shift;
+ my $api_file = shift;
+ my $configure_in_file = shift;
+ my $config_h_in_file = shift;
- open(IN, "< $file");
+ open(IN, "< $api_file");
$/ = "\n";
while(<IN>) {
s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
s/^(.*?)\s*#.*$/$1/; # remove comments
/^$/ && next; # skip empty lines
- $$functions{$_} = 1;
+ $$functions{$_}++;
+ }
+ close(IN);
+
+ my $again = 0;
+ open(IN, "< $configure_in_file");
+ local $/ = "\n";
+ while($again || (defined($_ = <IN>))) {
+ $again = 0;
+ chomp;
+ if(/(.*)\\$/) {
+ my $line = <IN>;
+ if(defined($line)) {
+ $_ = $1 . " " . $line;
+ $again = 1;
+ next;
+ }
+ }
+ # remove leading and trailing whitespace
+ s/^\s*(.*?)\s*$/$1/;
+
+ if(/^AC_CHECK_HEADERS\(\s*(.*?)\)\s*$/) {
+ my @arguments = split(/,/,$1);
+ foreach my $header (split(/\s+/, $arguments[0])) {
+ $$conditional_headers{$header}++;
+ }
+ } elsif(/^AC_FUNC_ALLOCA/) {
+ $$conditional_headers{"alloca.h"}++;
+ }
+
+ }
+ close(IN);
+
+ open(IN, "< $config_h_in_file");
+ local $/ = "\n";
+ while(<IN>) {
+ if(/^\#undef (\S+)$/) {
+ $$conditionals{$1}++;
+ }
}
close(IN);
@@ -35,4 +77,22 @@
return $$functions{$name};
}
+sub is_conditional {
+ my $self = shift;
+ my $conditionals = \%{$self->{CONDITIONALS}};
+
+ my $name = shift;
+
+ return $$conditionals{$name};
+}
+
+sub is_conditional_header {
+ my $self = shift;
+ my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
+
+ my $name = shift;
+
+ return $$conditional_headers{$name};
+}
+
1;
diff --git a/tools/winapi_check/output.pm b/tools/winapi_check/output.pm
new file mode 100644
index 0000000..0c0fb32
--- /dev/null
+++ b/tools/winapi_check/output.pm
@@ -0,0 +1,91 @@
+package output;
+
+use strict;
+
+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}};
+
+ $$progress = "";
+ $$last_progress = "";
+
+ return $self;
+}
+
+
+sub show_progress {
+ my $self = shift;
+ my $progress = \${$self->{PROGRESS}};
+ my $last_progress = \${$self->{LAST_PROGRESS}};
+
+ if($$progress) {
+ print STDERR $$progress;
+ $$last_progress = $$progress;
+ }
+}
+
+sub hide_progress {
+ my $self = shift;
+ my $progress = \${$self->{PROGRESS}};
+ my $last_progress = \${$self->{LAST_PROGRESS}};
+
+ if($$last_progress) {
+ 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 = "";
+ for (1..length($$last_progress)) {
+ $prefix .= "";
+ }
+
+ my $suffix = "";
+ 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 write {
+ my $self = shift;
+ my $last_progress = \${$self->{LAST_PROGRESS}};
+
+ my $message = shift;
+
+ $self->hide_progress;
+ print STDERR $message;
+ $self->show_progress;
+}
+
+1;
diff --git a/tools/winapi_check/preprocessor.pm b/tools/winapi_check/preprocessor.pm
new file mode 100644
index 0000000..dd9fbd4
--- /dev/null
+++ b/tools/winapi_check/preprocessor.pm
@@ -0,0 +1,175 @@
+package preprocessor;
+
+use strict;
+
+sub new {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $self = {};
+ bless ($self, $class);
+
+ my $state = \%{$self->{STATE}};
+ my $stack = \@{$self->{STACK}};
+ my $include_found = \${$self->{INCLUDE_FOUND}};
+ my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
+
+ $$include_found = shift;
+ $$conditional_found = shift;
+
+ return $self;
+}
+
+sub include {
+ my $self = shift;
+ my $include_found = \${$self->{INCLUDE_FOUND}};
+
+ my $argument = shift;
+
+ &$$include_found($argument);
+}
+
+sub define {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+ my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
+
+ my $name = shift;
+
+ $$state{$name} = "def";
+
+ &$$conditional_found($name);
+}
+
+sub undefine {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+ my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
+
+ my $name = shift;
+
+ $$state{$name} = "undef";
+
+ &$$conditional_found($name);
+}
+
+sub begin_if {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+ my $stack = \@{$self->{STACK}};
+
+ my $directive = shift;
+ local $_ = shift;
+
+ while(!/^$/) {
+ if(/^0\s*\&\&/) {
+ $_ = "0";
+ } elsif(/^1\s*\|\|/) {
+ $_ = "1";
+ }
+
+ if(/^(!)?defined\s*\(\s*(.+?)\s*\)\s*((\&\&|\|\|)\s*)?/){
+ $_ = $';
+ if(defined($1) && $1 eq "!") {
+ $self->undefine($2);
+ push @$stack, $2;
+ } else {
+ $self->define($2);
+ push @$stack, $2;
+ }
+ } elsif(/^(\w+)\s*(<|<=|==|!=|>=|>)\s*(\w+)\s*((\&\&|\|\|)\s*)?/) {
+ $_ = $';
+ } elsif(/^(\w+)\s*$/) {
+ $_ = $';
+ } elsif(/^\(|\)/) {
+ $_ = $';
+ } else {
+ print "*** Can't parse '#$directive $_' ***\n";
+ $_ = "";
+ }
+ }
+}
+
+sub else_if {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+ my $stack = \@{$self->{STACK}};
+
+ my $argument = shift;
+
+ $self->end_if;
+
+ if(defined($argument)) {
+ $self->begin_if("elif", $argument);
+ }
+}
+
+sub end_if {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+ my $stack = \@{$self->{STACK}};
+
+ my $macro = pop @$stack;
+ delete $$state{$macro} if defined($macro);
+}
+
+sub directive {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+ my $stack = \@{$self->{STACK}};
+
+ my $directive = shift;
+ my $argument = shift;
+
+ local $_ = $directive;
+ if(/^if$/) {
+ $self->begin_if("if",$argument);
+ } elsif(/^ifdef$/) {
+ $self->begin_if("if", "defined($argument)");
+ } elsif(/^ifndef$/) {
+ $self->begin_if("if", "!defined($argument)");
+ push @$stack, $argument;
+ } elsif(/^elif$/) {
+ $self->else_if($argument);
+ } elsif(/^else$/) {
+ $self->else_if;
+ } elsif(/^endif$/) {
+ $self->end_if;
+ } elsif(/^include/) {
+ $self->include($argument);
+ }
+}
+
+sub is_def {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+
+ my $name = shift;
+
+ my $status = $$state{$name};
+
+ return defined($status) && $status eq "def";
+}
+
+sub is_undef {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+
+ my $name = shift;
+
+ my $status = $$state{$name};
+
+ return defined($status) && $status eq "undef";
+}
+
+sub is_unknown {
+ my $self = shift;
+ my $state = \%{$self->{STATE}};
+
+ my $name = shift;
+
+ my $status = $$state{$name};
+
+ return !defined($status);
+}
+
+1;
diff --git a/tools/winapi_check/win16/display.api b/tools/winapi_check/win16/display.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/display.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16/gdi.api b/tools/winapi_check/win16/gdi.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/gdi.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16/olecli.api b/tools/winapi_check/win16/olecli.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/olecli.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16/user.api b/tools/winapi_check/win16/user.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/user.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16/wing.api b/tools/winapi_check/win16/wing.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/wing.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16api.dat b/tools/winapi_check/win16api.dat
index a9d299b..f946ee6 100644
--- a/tools/winapi_check/win16api.dat
+++ b/tools/winapi_check/win16api.dat
@@ -24,6 +24,7 @@
%longlong
LARGE_INTEGER
+ULARGE_INTEGER
%ptr
@@ -157,6 +158,7 @@
LPPALETTEENTRY
LPPDEVICE
LPPOINT16
+LPPRINTDLG16
LPQUEUESTRUCT16 *
LPRASTERIZER_STATUS
LPRECT16
@@ -290,7 +292,6 @@
HBITMAP16
HBRUSH16
HCURSOR16
-HDC16
HDROP16
HDRVR16
HDWP16
@@ -330,7 +331,7 @@
WORD
WPARAM16
-%unknown --forbidden
+%unknown # --forbidden
BOOL
FARPROC
diff --git a/tools/winapi_check/win32/avifil32.api b/tools/winapi_check/win32/avifil32.api
new file mode 100644
index 0000000..6558fd2
--- /dev/null
+++ b/tools/winapi_check/win32/avifil32.api
@@ -0,0 +1,12 @@
+%ptr
+
+AVICOMPRESSOPTIONS *
+AVISTREAMINFOA *
+AVISTREAMINFOW *
+IAVIFile *
+LPAVIFILEINFOA
+LPAVIFILEINFOW
+PAVIFILE
+PAVIFILE *
+PAVISTREAM
+PAVISTREAM *
diff --git a/tools/winapi_check/win32/comctl32.api b/tools/winapi_check/win32/comctl32.api
new file mode 100644
index 0000000..18ff86f
--- /dev/null
+++ b/tools/winapi_check/win32/comctl32.api
@@ -0,0 +1,7 @@
+%long
+
+COLORREF
+HBITMAP
+HDC
+HICON
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/comdlg32.api b/tools/winapi_check/win32/comdlg32.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/comdlg32.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/gdi32.api b/tools/winapi_check/win32/gdi32.api
new file mode 100644
index 0000000..7454167
--- /dev/null
+++ b/tools/winapi_check/win32/gdi32.api
@@ -0,0 +1,22 @@
+%long
+
+COLORREF
+HBITMAP
+HBRUSH
+HCOLORSPACE
+HDC
+HENHMETAFILE
+HFONT
+HGDIOBJ
+HMETAFILE
+HPALETTE
+HPEN
+HRGN
+HWND
+
+%ptr
+
+BITMAP *
+BITMAPINFO *
+BITMAPINFOHEADER *
+
diff --git a/tools/winapi_check/win32/imm32.api b/tools/winapi_check/win32/imm32.api
new file mode 100644
index 0000000..3f41c3a
--- /dev/null
+++ b/tools/winapi_check/win32/imm32.api
@@ -0,0 +1,4 @@
+%long
+
+HWND
+HIMC
diff --git a/tools/winapi_check/win32/mpr.api b/tools/winapi_check/win32/mpr.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/mpr.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/msacm32.api b/tools/winapi_check/win32/msacm32.api
new file mode 100644
index 0000000..98fe080
--- /dev/null
+++ b/tools/winapi_check/win32/msacm32.api
@@ -0,0 +1,36 @@
+%long
+
+HACMDRIVER
+HACMDRIVERID
+HACMOBJ
+HACMSTREAM
+
+%ptr
+
+ACMDRIVERENUMCB
+ACMFILTERENUMCBA
+ACMFILTERENUMCBW
+ACMFILTERTAGENUMCBA
+ACMFILTERTAGENUMCBW
+ACMFORMATENUMCBA
+ACMFORMATENUMCBW
+ACMFORMATTAGENUMCBA
+ACMFORMATTAGENUMCBW
+PACMDRIVERDETAILSA
+PACMDRIVERDETAILSW
+PACMFILTERCHOOSEA
+PACMFILTERCHOOSEW
+PACMFILTERDETAILSA
+PACMFILTERDETAILSW
+PACMFILTERTAGDETAILSA
+PACMFILTERTAGDETAILSW
+PACMFORMATCHOOSEA
+PACMFORMATCHOOSEW
+PACMFORMATDETAILSA
+PACMFORMATDETAILSW
+PACMFORMATTAGDETAILSA
+PACMFORMATTAGDETAILSW
+PACMSTREAMHEADER
+PHACMDRIVER
+PHACMDRIVERID
+PHACMSTREAM
diff --git a/tools/winapi_check/win32/msvfw32.api b/tools/winapi_check/win32/msvfw32.api
new file mode 100644
index 0000000..05c8b15
--- /dev/null
+++ b/tools/winapi_check/win32/msvfw32.api
@@ -0,0 +1,7 @@
+%long
+
+HDC
+HIC
+HPALETTE
+HWND
+
diff --git a/tools/winapi_check/win32/ole32.api b/tools/winapi_check/win32/ole32.api
new file mode 100644
index 0000000..41888d9
--- /dev/null
+++ b/tools/winapi_check/win32/ole32.api
@@ -0,0 +1,10 @@
+%long
+
+CLIPFORMAT
+HACCEL
+HMENU
+HWND
+
+%ptr
+CLIPFORMAT *
+
diff --git a/tools/winapi_check/win32/oleaut32.api b/tools/winapi_check/win32/oleaut32.api
new file mode 100644
index 0000000..60895c7
--- /dev/null
+++ b/tools/winapi_check/win32/oleaut32.api
@@ -0,0 +1,7 @@
+%long
+
+HPALETTE
+
+%ptr
+
+COLORREF *
diff --git a/tools/winapi_check/win32/olecli32.api b/tools/winapi_check/win32/olecli32.api
new file mode 100644
index 0000000..8c76d1c
--- /dev/null
+++ b/tools/winapi_check/win32/olecli32.api
@@ -0,0 +1,3 @@
+%long
+
+HDC
\ No newline at end of file
diff --git a/tools/winapi_check/win32/oledlg.api b/tools/winapi_check/win32/oledlg.api
new file mode 100644
index 0000000..2a948b0
--- /dev/null
+++ b/tools/winapi_check/win32/oledlg.api
@@ -0,0 +1,4 @@
+%long
+
+HMENU
+HWND
diff --git a/tools/winapi_check/win32/shell32.api b/tools/winapi_check/win32/shell32.api
new file mode 100644
index 0000000..367c116
--- /dev/null
+++ b/tools/winapi_check/win32/shell32.api
@@ -0,0 +1,8 @@
+%long
+
+COLORREF
+HBITMAP
+HMENU
+HICON
+HWND
+
diff --git a/tools/winapi_check/win32/shlwapi.api b/tools/winapi_check/win32/shlwapi.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/shlwapi.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/tapi32.api b/tools/winapi_check/win32/tapi32.api
new file mode 100644
index 0000000..41c0866
--- /dev/null
+++ b/tools/winapi_check/win32/tapi32.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
diff --git a/tools/winapi_check/win32/user32.api b/tools/winapi_check/win32/user32.api
new file mode 100644
index 0000000..a392bb3
--- /dev/null
+++ b/tools/winapi_check/win32/user32.api
@@ -0,0 +1,19 @@
+%long
+
+COLORREF
+HACCEL
+HBITMAP
+HBRUSH
+HCURSOR
+HDC
+HDESK
+HFONT
+HICON
+HMENU
+HMONITOR
+HRGN
+HWND
+
+%ptr
+
+COLORREF *
diff --git a/tools/winapi_check/win32/winmm.api b/tools/winapi_check/win32/winmm.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/winmm.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/winspool.api b/tools/winapi_check/win32/winspool.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/winspool.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/wsock32.api b/tools/winapi_check/win32/wsock32.api
new file mode 100644
index 0000000..41c0866
--- /dev/null
+++ b/tools/winapi_check/win32/wsock32.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
diff --git a/tools/winapi_check/win32api.dat b/tools/winapi_check/win32api.dat
index 88d8673..4d1e0fa 100644
--- a/tools/winapi_check/win32api.dat
+++ b/tools/winapi_check/win32api.dat
@@ -13,8 +13,6 @@
CALID
CALTYPE
CHAR
-CLIPFORMAT
-COLORREF
COORD
DATE
DIGEST_HANDLE
@@ -25,44 +23,25 @@
FOURCC
FS_INFORMATION_CLASS
GET_FILEEX_INFO_LEVELS
-HACCEL
-HACMDRIVER
-HACMDRIVERID
-HACMOBJ
-HACMSTREAM
HANDLE
-HBITMAP
-HBRUSH
HCALL
-HCOLORSPACE
HCONV
HCONVLIST
-HCURSOR
HCRYPTKEY
-HDC
HDDEDATA
-HDESK
HDROP
HDRVR
HDSA
HDWP
-HENHMETAFILE
HFILE
-HFONT
-HGDIOBJ
HGLOBAL
HHOOK
-HIC
-HICON
-HIMC
HINSTANCE
HKEY
HKL
HLINE
HLINEAPP
HLOCAL
-HMENU
-HMETAFILE
HMIDIIN
HMIDIOUT
HMIDISTRM
@@ -70,23 +49,18 @@
HMIXEROBJ
HMMIO
HMODULE
-HMONITOR
HOLEMENU
-HPALETTE
-HPEN
HPHONE
HPHONEAPP
HPROPSHEETPAGE
HPROVIDER
HRESULT
-HRGN
HRSRC
HSZ
HTASK
HWAVEIN
HWAVEOUT
HWINSTA
-HWND
INT
KEY_INFORMATION_CLASS
KEY_VALUE_INFORMATION_CLASS
@@ -106,7 +80,6 @@
OLEOPT_RENDER
OLESTATUS
OLE_SERVER_USE
-OUT
PHANDLE
PHPROVIDER
PIO_APC_ROUTINE
@@ -117,6 +90,7 @@
PROCESSINFOCLASS
PTIME_FIELDS
PTOKEN_PRIVILEGES
+REGKIND
REGSAM
SC_HANDLE
SECTION_INHERIT
@@ -150,37 +124,21 @@
LARGE_INTEGER
POINT
+ULARGE_INTEGER
%ptr
ABORTPROC
-ACMDRIVERENUMCB
-ACMFILTERENUMCBA
-ACMFILTERENUMCBW
-ACMFILTERTAGENUMCBA
-ACMFILTERTAGENUMCBW
-ACMFORMATENUMCBA
-ACMFORMATENUMCBW
-ACMFORMATTAGENUMCBA
-ACMFORMATTAGENUMCBW
-AVICOMPRESSOPTIONS *
-AVISTREAMINFOA *
-AVISTREAMINFOW *
-BITMAP *
-BITMAPINFO *
-BITMAPINFOHEADER *
BOOL *
BSTR *
BYTE *
BY_HANDLE_FILE_INFORMATION *
CALINFO_ENUMPROCA
CHAR *
-CLIPFORMAT *
CLSID *
CODEPAGE_ENUMPROCA
CODEPAGE_ENUMPROCW
COLORADJUSTMENT *
-COLORREF *
CONST
CONTEXT *
COSERVERINFO *
@@ -238,6 +196,7 @@
HMIDIIN *
HMIDIOUT *
HMIDISTRM *
+HMODULE *
HMRU
HOOKPROC
HPCSTR
@@ -254,6 +213,8 @@
ILockBytes *
IMAGEINFO *
IMAGELISTDRAWPARAMS *
+IMoniker *
+IMoniker **
INPUT_RECORD *
INT *
IPersistStream *
@@ -283,8 +244,6 @@
LPAUTHDLGSTRUCTA
LPAUXCAPSA
LPAUXCAPSW
-LPAVIFILEINFOA
-LPAVIFILEINFOW
LPBC *
LPBITMAPINFOHEADER
LPBOOL
@@ -327,6 +286,7 @@
LPDATAADVISEHOLDER *
LPDATAOBJECT
LPDCB
+LPDCB *
LPDDENUMCALLBACKA
LPDDENUMCALLBACKEXA
LPDDENUMCALLBACKEXW
@@ -434,8 +394,10 @@
LPMIXERLINEW
LPMMCKINFO
LPMMIOPROC
+LPMMIOPROC16
LPMMTIME
LPMODULEENTRY
+LPMODULEINFO
LPMONIKER
LPMONIKER *
LPMONITORINFO
@@ -579,31 +541,12 @@
PACE_HEADER *
PACL
PACL *
-PACMDRIVERDETAILSA
-PACMDRIVERDETAILSW
-PACMFILTERCHOOSEA
-PACMFILTERCHOOSEW
-PACMFILTERDETAILSA
-PACMFILTERDETAILSW
-PACMFILTERTAGDETAILSA
-PACMFILTERTAGDETAILSW
-PACMFORMATCHOOSEA
-PACMFORMATCHOOSEW
-PACMFORMATDETAILSA
-PACMFORMATDETAILSW
-PACMFORMATTAGDETAILSA
-PACMFORMATTAGDETAILSW
-PACMSTREAMHEADER
PAINTSTRUCT *
PALETTEENTRY *
PANSI_STRING
PAPCFUNC
PAPI_VERSION
PAPPBARDATA
-PAVIFILE
-PAVIFILE *
-PAVISTREAM
-PAVISTREAM *
PBOOLEAN
PBYTE
PCHAR
@@ -623,9 +566,6 @@
PGENERIC_MAPPING
PGETFRAME
PGET_MODULE_BASE_ROUTINE
-PHACMDRIVER
-PHACMDRIVERID
-PHACMSTREAM
PHONECALLBACK
PIMAGEHLP_MODULE
PIMAGEHLP_STATUS_ROUTINE
@@ -646,7 +586,9 @@
POINT *
PPOLYTEXTA
PPOLYTEXTW
+PPSAPI_WS_WATCH_INFORMATION
PPRIVILEGE_SET
+PPROCESS_MEMORY_COUNTERS
PREAD_PROCESS_MEMORY_ROUTINE
PRTL_HEAP_DEFINITION
PROPENUMPROCA
diff --git a/tools/winapi_check/winapi.pm b/tools/winapi_check/winapi.pm
index dfb3e6d..95af6ff 100644
--- a/tools/winapi_check/winapi.pm
+++ b/tools/winapi_check/winapi.pm
@@ -8,18 +8,48 @@
my $self = {};
bless ($self, $class);
+ my $output = \${$self->{OUTPUT}};
+ my $name = \${$self->{NAME}};
+
+ $$output = shift;
+ $$name = shift;
+ my $file = shift;
+ my $path = shift;
+
+ $file =~ s/^.\/(.*)$/$1/;
+ $self->parse_api_file($file);
+
+ my @files = map {
+ s/^.\/(.*)$/$1/;
+ $_;
+ } split(/\n/, `find $path -name \\*.api`);
+
+ foreach my $file (@files) {
+ my $module = $file;
+ $module =~ s/.*?\/([^\/]*?)\.api$/$1/;
+ $self->parse_api_file($file,$module);
+ }
+
+ return $self;
+}
+
+sub parse_api_file {
+ my $self = shift;
+ my $output = \${$self->{OUTPUT}};
my $allowed_kind = \%{$self->{ALLOWED_KIND}};
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
+ my $allowed_modules_unlimited = \%{$self->{ALLOWED_MODULES_UNLIMITED}};
my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
- $self->{NAME} = shift;
my $file = shift;
+ my $module = shift;
- my @modules;
my $kind;
my $forbidden = 0;
+ $$output->progress("$file");
+
open(IN, "< $file") || die "$file: $!\n";
$/ = "\n";
while(<IN>) {
@@ -29,34 +59,41 @@
if(s/^%(\S+)\s*//) {
$kind = $1;
- @modules = ();
$forbidden = 0;
$$allowed_kind{$kind} = 1;
- if(/^--module=(\S*)/) {
- @modules = split(/,/, $1);
- } elsif(/^--forbidden/) {
+ if(/^--forbidden/) {
$forbidden = 1;
}
} elsif(defined($kind)) {
my $type = $_;
if(!$forbidden) {
- for my $module (@modules) {
- $$allowed_modules_limited{$type} = 1;
- $$allowed_modules{$type}{$module} = 1;
+ if(defined($module)) {
+ if($$allowed_modules_unlimited{$type}) {
+ print "$file: type ($type) already specificed as an unlimited type\n";
+ } elsif(!$$allowed_modules{$type}{$module}) {
+ $$allowed_modules{$type}{$module} = 1;
+ $$allowed_modules_limited{$type} = 1;
+ } else {
+ print "$file: type ($type) already specificed\n";
+ }
+ } else {
+ $$allowed_modules_unlimited{$type} = 1;
}
} else {
$$allowed_modules_limited{$type} = 1;
}
- $$translate_argument{$type} = $kind;
+ if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
+ print "$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n";
+ } else {
+ $$translate_argument{$type} = $kind;
+ }
} else {
print "$file: file must begin with %<type> statement\n";
exit 1;
}
}
close(IN);
-
- return $self;
}
sub get_spec_file_type {
@@ -88,7 +125,12 @@
my $win16api = shift;
my $win32api = shift;
- foreach my $file (split(/\n/, `find $path -name \\*.spec`)) {
+ my @files = map {
+ s/^.\/(.*)$/$1/;
+ $_;
+ } split(/\n/, `find $path -name \\*.spec`);
+
+ foreach my $file (@files) {
my $type = 'winapi'->get_spec_file_type($file);
if($type eq "win16") {
$win16api->parse_spec_file($file);
@@ -100,16 +142,22 @@
sub parse_spec_file {
my $self = shift;
+
+ my $output = \${$self->{OUTPUT}};
my $function_arguments = \%{$self->{FUNCTION_ARGUMENTS}};
my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
my $function_stub = \%{$self->{FUNCTION_STUB}};
my $function_module = \%{$self->{FUNCTION_MODULE}};
+
my $file = shift;
-
+
+ my %ordinals;
my $type;
my $module;
+ $$output->progress("$file");
+
open(IN, "< $file") || die "$file: $!\n";
$/ = "\n";
my $header = 1;
@@ -126,18 +174,24 @@
next;
}
- if(/^\d+\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
- my $calling_convention = $1;
- my $external_name = $2;
- my $arguments = $3;
- my $internal_name = $4;
+ my $ordinal;
+ if(/^(\d+)\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
+ my $calling_convention = $2;
+ my $external_name = $3;
+ my $arguments = $4;
+ my $internal_name = $5;
+
+ $ordinal = $1;
# FIXME: Internal name existing more than once not handled properly
$$function_arguments{$internal_name} = $arguments;
$$function_calling_convention{$internal_name} = $calling_convention;
- $$function_module{$internal_name} = $module;
- } elsif(/^\d+\s+stub\s+(\S+)$/) {
- my $external_name = $1;
+ $$function_module{$internal_name} = "$module";
+ } elsif(/^(\d+)\s+stub\s+(\S+)$/) {
+ my $external_name = $2;
+
+ $ordinal = $1;
+
$$function_stub{$external_name} = 1;
$$function_module{$external_name} = $module;
} elsif(/^\d+\s+(equate|long|word|extern|forward)/) {
@@ -151,13 +205,22 @@
$lookahead = 1;
}
}
+
+ if(defined($ordinal)) {
+ if($ordinals{$ordinal}) {
+ print "$file: ordinal redefined: $_\n";
+ }
+ $ordinals{$ordinal}++;
+ }
}
close(IN);
}
sub name {
my $self = shift;
- return $self->{NAME};
+ my $name = \${$self->{NAME}};
+
+ return $$name;
}
sub is_allowed_kind {
@@ -172,6 +235,15 @@
}
}
+sub is_limited_type {
+ my $self = shift;
+ my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
+
+ my $type = shift;
+
+ return $$allowed_modules_limited{$type};
+}
+
sub allowed_type_in_module {
my $self = shift;
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
@@ -183,6 +255,34 @@
return !$$allowed_modules_limited{$type} || $$allowed_modules{$type}{$module};
}
+sub type_used_in_module {
+ my $self = shift;
+ my $used_modules = \%{$self->{USED_MODULES}};
+
+ my $type = shift;
+ my $module = shift;
+
+ $$used_modules{$type}{$module} = 1;
+
+ return ();
+}
+
+sub types_not_used {
+ my $self = shift;
+ my $used_modules = \%{$self->{USED_MODULES}};
+ my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
+
+ my $not_used;
+ foreach my $type (sort(keys(%$allowed_modules))) {
+ foreach my $module (sort(keys(%{$$allowed_modules{$type}}))) {
+ if(!$$used_modules{$type}{$module}) {
+ $$not_used{$module}{$type} = 1;
+ }
+ }
+ }
+ return $not_used;
+}
+
sub translate_argument {
my $self = shift;
my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
@@ -226,7 +326,7 @@
sub all_functions_found {
my $self = shift;
- my $function_found = \$self->{FUNCTION_FOUND};
+ my $function_found = \%{$self->{FUNCTION_FOUND}};
return sort(keys(%$function_found));
}
@@ -282,11 +382,7 @@
my $name = shift;
- if($self->is_function($name)) {
- return $$function_module{$name};
- } else {
- return undef;
- }
+ return $$function_module{$name};
}
sub function_stub {
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index 564dea2..d6f9e9e 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -20,15 +20,19 @@
}
@INC = ($winapi_check_dir);
- require "winapi.pm";
require "nativeapi.pm";
+ require "output.pm";
+ require "preprocessor.pm";
+ require "winapi.pm";
require "winapi_local.pm";
require "winapi_global.pm";
require "winapi_options.pm";
require "winapi_parser.pm";
- import winapi;
import nativeapi;
+ import output;
+ import preprocessor;
+ import winapi;
import winapi_local;
import winapi_global;
import winapi_options;
@@ -41,11 +45,13 @@
exit;
}
-my $win16api = 'winapi'->new("win16", "$winapi_check_dir/win16api.dat");
-my $win32api = 'winapi'->new("win32", "$winapi_check_dir/win32api.dat");
+my $output = 'output'->new;
+
+my $win16api = 'winapi'->new($output, "win16", "$winapi_check_dir/win16api.dat", "$winapi_check_dir/win16");
+my $win32api = 'winapi'->new($output, "win32", "$winapi_check_dir/win32api.dat", "$winapi_check_dir/win32");
'winapi'->read_spec_files($wine_dir, $win16api, $win32api);
-my $nativeapi = 'nativeapi'->new("$winapi_check_dir/nativeapi.dat");
+my $nativeapi = 'nativeapi'->new("$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);
@@ -61,13 +67,57 @@
}
}
+my %includes;
+{
+ my @files = map {
+ s/^.\/(.*)$/$1/;
+ $_;
+ } split(/\n/, `find . -name \\*.h`);
+
+ foreach my $file (@files) {
+ $includes{$file} = { name => $file };
+ open(IN, "< $file");
+ while(<IN>) {
+ if(/^\s*\#\s*include\s*\"(.*?)\"/) {
+ $includes{$file}{includes}{"include/$1"}++;
+ }
+ }
+ close(IN);
+ }
+}
+
+my %functions;
+
+my $progress_output;
+my $progress_current=0;
+my $progress_max=scalar($options->files);
foreach my $file ($options->files) {
+ $progress_current++;
+ if($options->progress) {
+ $output->progress("$file: file $progress_current of $progress_max");
+ }
+
+ my $file_dir = $file;
+ $file_dir =~ s/(.*?)\/[^\/]*$/$1/;
+
+ my $file_type;
+ if($file_dir =~ /^(libtest|program|rc)/) {
+ $file_type = "application";
+ } elsif($file_dir =~ /^(debug|miscemu)/) {
+ $file_type = "emulator";
+ } elsif($file_dir =~ /^(tools)/) {
+ $file_type = "tool";
+ } else {
+ $file_type = "library";
+ }
+
my $found_function = sub {
my $return_type = shift;
my $calling_convention = shift;
my $name = shift;
my $refarguments = shift;
my @arguments = @$refarguments;
+ my $statements = shift;
if($options->global) {
$win16api->found_type($return_type) if $options->win16;
@@ -84,16 +134,38 @@
if($options->local) {
my $module16 = $win16api->function_module($name);
my $module32 = $win32api->function_module($name);
- my $output = sub {
+
+ my $module;
+ if(defined($module16) && defined($module32)) {
+ $module = "$module16 & $module32";
+ } elsif(defined($module16)) {
+ $module = $module16;
+ } elsif(defined($module32)) {
+ $module = $module32;
+ } else {
+ $module = "";
+ }
+ my $output_module = sub {
my $module = shift;
return sub {
my $msg = shift;
- print "$file: $module: $return_type $calling_convention $name(" . join(",", @arguments) . "): $msg\n";
+ $output->write("$file: $module: $return_type ");
+ $output->write("$calling_convention ") if $calling_convention;
+ $output->write("$name(" . join(",", @arguments) . "): $msg\n");
}
};
- my $output16 = &$output($module16);
- my $output32 = &$output($module32);
+ my $output16 = &$output_module($module16);
+ my $output32 = &$output_module($module32);
+ my $function = $functions{$name};
+ $$function{file} = $file;
+ $$function{return_type} = $return_type;
+ $$function{calling_convention} = $calling_convention;
+ $$function{arguments} = [@arguments];
+ $$function{module} = $module;
+ $$function{module16} = $module16;
+ $$function{module32} = $module32;
+
if($options->argument) {
if($options->win16 && $options->report_module($module16)) {
winapi_local::check_arguments $options, $output16,
@@ -122,12 +194,145 @@
}
}
}
+ if($options->cross_call) {
+ local $_ = $statements;
+ my $called_function_names = {};
+ while(defined($_)) {
+ if(/(\w+)\((.*?)\)/) {
+ $_ = $';
+ my $called_name = $1;
+ if($called_name !~ /^if|for|while|switch|sizeof$/) {
+ $functions{$name}{called_function_names}{$called_name}++;
+ $functions{$called_name}{called_by_function_names}{$name}++;
+ }
+ } else {
+ undef $_
+ }
+ }
+ }
}
- };
- winapi_parser::parse_c_file $options, $file, $found_function;
+ };
+
+ my $config = 0;
+ my $conditional = 0;
+ my $found_include = sub {
+ local $_ = shift;
+ if(/^\"config.h\"/) {
+ $config++;
+ }
+ };
+ my $found_conditional = sub {
+ local $_ = shift;
+ if(!$nativeapi->is_conditional($_)) {
+ if(/^HAVE_/ && !/^HAVE_(IPX|MESAGL|BUGGY_MESAGL|WINE_CONSTRUCTOR)$/)
+ {
+ $output->write("$file: $_ is not a 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 {
+ my $directive = shift;
+ my $argument = shift;
+
+ $preprocessor->directive($directive, $argument);
+
+ if($options->config) {
+ if($directive eq "include") {
+ if($argument =~ /^<(.*?)>$/) {
+ my $header = $1;
+
+ if((-e "$wine_dir/include/$header" || -e "$file_dir/$header") && $file_type ne "application") {
+ $output->write("$file: #include \<$header\> is a local include\n");
+ }
+
+ my $macro = uc($header);
+ $macro =~ y/\.\//__/;
+ $macro = "HAVE_" . $macro;
+
+ if($nativeapi->is_conditional_header($header)) {
+ if(!$preprocessor->is_def($macro)) {
+ if($macro =~ /^HAVE_X11/) {
+ if(!$preprocessor->is_undef("X_DISPLAY_MISSING")) {
+ $output->write("$file: #$directive $argument: is a conditional include, but is not protected\n");
+ }
+ } elsif($macro =~ /^HAVE_(.*?)_H$/) {
+ if($header ne "alloca.h" && !$preprocessor->is_def("STATFS_DEFINED_BY_$1")) {
+ $output->write("$file: #$directive $argument: is a conditional include, but is not protected\n");
+ }
+ }
+ }
+ } elsif($preprocessor->is_def($macro)) {
+ $output->write("$file: #$directive $argument: is protected, but is not a conditional include\n");
+ }
+ } elsif($argument =~ /^"(.*?)"$/) {
+ my $header = $1;
+
+ if(-e "$file_dir/$header") {
+ $includes{"$file_dir/$header"}{used}++;
+ foreach my $name (keys(%{$includes{"$file_dir/$header"}{includes}})) {
+ $includes{$name}{used}++;
+ }
+ } elsif(-e "include/$header") {
+ $includes{"include/$header"}{used}++;
+ foreach my $name (keys(%{$includes{"include/$header"}{includes}})) {
+ $includes{$name}{used}++;
+ }
+ } else {
+ $output->write("$file: #include \"$header\" is not a local include\n");
+ }
+ }
+ }
+ }
+ };
+
+ winapi_parser::parse_c_file $options, $file, $found_function, $found_preprocessor;
+
+ if($options->config_unnessary) {
+ if($config && $conditional == 0) {
+ $output->write("$file: includes config.h but do not use any conditionals\n");
+ }
+ }
+
+ if($options->cross_call) {
+ my @names = sort(keys(%functions));
+ for my $name (@names) {
+ my @called_names = sort(keys(%{$functions{$name}{called_function_names}}));
+ my @called_by_names = sort(keys(%{$functions{$name}{called_by_function_names}}));
+ my $module = $functions{$name}{module};
+ my $module16 = $functions{$name}{module16};
+ my $module32 = $functions{$name}{module32};
+
+ if($#called_names >= 0 && (defined($module16) || defined($module32)) ) {
+ $output->write("$file: $module: $name: \\\n");
+ for my $called_name (@called_names) {
+ my $function;
+ if($function = $functions{$called_name}) {
+ $output->write(" $called_name\n");
+ }
+ }
+ }
+ }
+ }
}
+$output->hide_progress;
+
if($options->global) {
+ foreach my $name (sort(keys(%includes))) {
+ if(!$includes{$name}{used}) {
+ if($options->include) {
+ print "$name: include file is never used\n";
+ }
+ }
+ }
+
winapi_global::check $options, $win16api, $nativeapi if $options->win16;
winapi_global::check $options, $win32api, $nativeapi if $options->win32;
}
+
diff --git a/tools/winapi_check/winapi_global.pm b/tools/winapi_check/winapi_global.pm
index 0c4322d..11f44ab 100644
--- a/tools/winapi_check/winapi_global.pm
+++ b/tools/winapi_check/winapi_global.pm
@@ -11,9 +11,9 @@
if($options->argument) {
foreach my $type ($winapi->all_declared_types) {
- if(!$winapi->type_found($type) && $type ne "CONTEXT86 *") {
- print "*.c: $winver: $type: ";
- print "type not used\n";
+ if(!$winapi->type_found($type) && !$winapi->is_type_limited($type) && $type ne "CONTEXT86 *") {
+ print "*.c: $winver: ";
+ print "type ($type) not used\n";
}
}
}
@@ -21,19 +21,22 @@
if($options->declared) {
foreach my $name ($winapi->all_functions) {
if(!$winapi->function_found($name) && !$nativeapi->is_function($name)) {
- print "*.c: $winver: $name: ";
+ my $module = $winapi->function_module($name);
+ print "*.c: $module: $name: ";
print "function declared but not implemented: " . $winapi->function_arguments($name) . "\n";
}
}
}
- if($options->implemented) {
- foreach my $name ($winapi->all_functions_found) {
- if($winapi->function_stub($name)) {
- print "*.c: $winver: $name: ";
- print "function implemented but not declared\n";
+ if($options->argument_forbidden) {
+ my $not_used = $winapi->types_not_used;
+
+ foreach my $module (sort(keys(%$not_used))) {
+ foreach my $type (sort(keys(%{$$not_used{$module}}))) {
+ print "*.c: $module: type $type not used\n";
}
}
+
}
}
diff --git a/tools/winapi_check/winapi_local.pm b/tools/winapi_check/winapi_local.pm
index 88126bb..fe1d356 100644
--- a/tools/winapi_check/winapi_local.pm
+++ b/tools/winapi_check/winapi_local.pm
@@ -14,8 +14,30 @@
my $module = $winapi->function_module($name);
+ if($winapi->name eq "win16") {
+ my $name16 = $name;
+ $name16 =~ s/16$//;
+ if($name16 ne $name && $winapi->function_stub($name16)) {
+ if($options->implemented) {
+ &$output("function implemented but declared as stub in .spec file");
+ }
+ return;
+ } elsif($winapi->function_stub($name)) {
+ if($options->implemented_win32) {
+ &$output("32-bit variant of function implemented but declared as stub in .spec file");
+ }
+ return;
+ }
+ } elsif($winapi->function_stub($name)) {
+ if($options->implemented) {
+ &$output("function implemented but declared as stub in .spec file");
+ }
+ return;
+ }
+
my $forbidden_return_type = 0;
my $implemented_return_kind;
+ $winapi->type_used_in_module($return_type,$module);
if(!defined($implemented_return_kind = $winapi->translate_argument($return_type))) {
if($return_type ne "") {
&$output("no translation defined: " . $return_type);
@@ -48,8 +70,10 @@
$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$/) {
$implemented_calling_convention = "stdcall";
+ } else {
+ $implemented_calling_convention = "<default>";
}
}
@@ -85,15 +109,12 @@
if($name =~ /^CRTDLL__ftol|CRTDLL__CIpow$/) {
# ignore
- } elsif($#argument_types != $#declared_argument_kinds) {
- if($options->argument_count) {
- &$output("argument count differs: " . ($#argument_types + 1) . " != " . ($#declared_argument_kinds + 1));
- }
} else {
my $n = 0;
my @argument_kinds = map {
my $type = $_;
my $kind = "unknown";
+ $winapi->type_used_in_module($type,$module);
if(!defined($kind = $winapi->translate_argument($type))) {
&$output("no translation defined: " . $type);
} elsif(!$winapi->is_allowed_kind($kind) ||
@@ -102,8 +123,13 @@
&$output("forbidden argument " . ($n + 1) . " type (" . $type . ")");
}
}
- $n++;
- $kind;
+ if(defined($kind) && $kind eq "longlong") {
+ $n+=2;
+ ("long", "long");
+ } else {
+ $n++;
+ $kind;
+ }
} @argument_types;
for my $n (0..$#argument_kinds) {
@@ -123,8 +149,13 @@
$argument_types[$n] . " ($argument_kinds[$n]) != " . $declared_argument_kinds[$n]);
}
}
-
}
+ if($#argument_kinds != $#declared_argument_kinds) {
+ if($options->argument_count) {
+ &$output("argument count differs: " . ($#argument_types + 1) . " != " . ($#declared_argument_kinds + 1));
+ }
+ }
+
}
if($segmented && $options->shared_segmented && $winapi->is_shared_function($name)) {
diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm
index 47f58d6..d85b69d 100644
--- a/tools/winapi_check/winapi_options.pm
+++ b/tools/winapi_check/winapi_options.pm
@@ -23,12 +23,17 @@
"help" => { default => 0, description => "help mode" },
"verbose" => { default => 0, description => "verbose mode" },
+ "progress" => { default => 1, description => "show progress" },
+
"win16" => { default => 1, description => "Win16 checking" },
"win32" => { default => 1, description => "Win32 checking" },
"shared" => { default => 0, description => "show shared functions between Win16 and Win32" },
"shared-segmented" => { default => 0, description => "segmented shared functions between Win16 and Win32 checking" },
+ "config" => { default => 1, description => "check configuration include consistancy" },
+ "config-unnessary" => { default => 0, parent => "config", description => "check for unnessary #include \"config.h\"" },
+
"local" => { default => 1, description => "local checking" },
"module" => {
default => { active => 1, filter => 0, hash => {} },
@@ -40,7 +45,7 @@
"argument" => { default => 1, parent => "local", description => "argument checking" },
"argument-count" => { default => 1, parent => "argument", description => "argument count checking" },
"argument-forbidden" => {
- default => { active => 0, filter => 0, hash => {} },
+ default => { active => 1, filter => 0, hash => {} },
parent => "argument",
parser => \&parser_comma_list,
description => "argument forbidden checking"
@@ -52,12 +57,14 @@
description => "argument kind checking"
},
"calling-convention" => { default => 0, parent => "local", description => "calling convention checking" },
- "misplaced" => { default => 0, parent => "local", description => "checking for misplaced functions" },
+ "misplaced" => { default => 0, parent => "local", description => "check for misplaced functions" },
+ "cross-call" => { default => 0, parent => "local", description => "check for cross calling functions" },
"global" => { default => 1, description => "global checking" },
"declared" => { default => 1, parent => "global", description => "declared checking" },
- "implemented" => { default => 0, parent => "global", description => "implemented checking" }
-
+ "implemented" => { default => 1, parent => "global", description => "implemented checking" },
+ "implemented-win32" => { default => 0, parent => "implemented", description => "implemented as win32 checking" },
+ "include" => { default => 0, parent => "global", description => "include checking" }
);
my %short_options = (
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index d6b9c12..ee5a9fe 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -6,6 +6,27 @@
my $options = shift;
my $file = shift;
my $function_found_callback = shift;
+ my $preprocessor_found_callback = shift;
+
+ my $return_type;
+ my $calling_convention;
+ my $function = "";
+ my $arguments;
+ my $statements;
+
+ my $function_begin = sub {
+ $return_type= shift;
+ $calling_convention = shift;
+ $function = shift;
+ $arguments = shift;
+
+ $statements = "";
+ };
+ my $function_end = sub {
+ &$function_found_callback($return_type,$calling_convention,$function,$arguments,$statements);
+
+ $function = "";
+ };
my $level = 0;
my $again = 0;
@@ -44,34 +65,61 @@
if(/^\s*$/) { next; }
# remove preprocessor directives
- if(s/^\s*\#.*$//m) { $again = 1; next; }
+ if(s/^\s*\#/\#/m) {
+ if(/^\\#.*?\\$/m) {
+ $lookahead = 1;
+ next;
+ } elsif(s/^\#\s*(.*?)(\s+(.*?))?\s*$//m) {
+ if(defined($3)) {
+ &$preprocessor_found_callback($1, $3);
+ } else {
+ &$preprocessor_found_callback($1, "");
+ }
+ $again = 1;
+ next;
+ }
+ }
if($level > 0)
{
- s/^[^\{\}]*//s;
- if(/^\{/) {
+ my $line;
+ s/^([^\{\}]*)//s;
+ $line = $1;
+ if(/^(\{)/) {
$_ = $'; $again = 1;
+ $line .= $1;
print "+1: $_\n" if $options->debug >= 2;
$level++;
- } elsif(/^\}/) {
+ } elsif(/^(\})/) {
$_ = $'; $again = 1;
+ $line .= $1 if $level > 1;
print "-1: $_\n" if $options->debug >= 2;
$level--;
}
+ if($line !~ /^\s*$/) {
+ $statements .= "$line\n";
+ }
+ if($function && $level == 0) {
+ &$function_end;
+ }
next;
- } elsif(/((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))(__cdecl|__stdcall|VFWAPIV|VFWAPI|WINAPIV|WINAPI)\s+(\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/s) {
+ } elsif(/((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))((__cdecl|__stdcall|VFWAPIV|VFWAPI|WINAPIV|WINAPI)\s+)?(\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/s) {
$_ = $'; $again = 1;
- if($9 eq ";") {
+ if($10 eq ";") {
next;
- } elsif($9 eq "{") {
+ } elsif($10 eq "{") {
$level++;
}
my $return_type = $1;
- my $calling_convention = $5;
- my $name = $6;
- my $arguments = $8;
+ my $calling_convention = $6;
+ my $name = $7;
+ my $arguments = $9;
+
+ if(!defined($calling_convention)) {
+ $calling_convention = "";
+ }
$return_type =~ s/\s*$//;
$return_type =~ s/\s*\*\s*/*/g;
@@ -88,7 +136,8 @@
my $argument = $arguments[$n];
$argument =~ s/^\s*(.*?)\s*$/$1/;
#print " " . ($n + 1) . ": '$argument'\n";
- $argument =~ s/^(const(?=\s)|IN(?=\s)|OUT(?=\s)|(\s*))\s*//;
+ $argument =~ s/^(IN OUT(?=\s)|IN(?=\s)|OUT(?=\s)|\s*)\s*//;
+ $argument =~ s/^(const(?=\s)|\s*)\s*//;
if($argument =~ /^...$/) {
$argument = "...";
} elsif($argument =~ /^((struct\s+|union\s+|enum\s+)?\w+)\s*((\*\s*?)*)\s*/) {
@@ -107,52 +156,66 @@
if($options->debug) {
print "$file: $return_type $calling_convention $name(" . join(",", @arguments) . ")\n";
}
- &$function_found_callback($return_type,$calling_convention,$name,\@arguments);
+ &$function_begin($return_type,$calling_convention,$name,\@arguments);
} elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1;
my @arguments = ("HDC16");
- &$function_found_callback($2, "WINAPI", $3, \@arguments);
+ &$function_begin($2, "WINAPI", $3, \@arguments);
+ &$function_end;
} elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
$_ = $'; $again = 1;
my @arguments = ("HDC");
- &$function_found_callback($2, "WINAPI", $3, \@arguments);
+ &$function_begin($2, "WINAPI", $3, \@arguments);
+ &$function_end;
} elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1;
my @arguments16 = ("HDC16", "LP" . $5 . "16");
my @arguments32 = ("HDC", "LP" . $5);
- &$function_found_callback("BOOL16", "WINAPI", $2 . "16", \@arguments16);
- &$function_found_callback("BOOL", "WINAPI", $2, \@arguments32);
+ &$function_begin("BOOL16", "WINAPI", $2 . "16", \@arguments16);
+ &$function_end;
+ &$function_begin("BOOL", "WINAPI", $2, \@arguments32);
+ &$function_end;
} elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1;
my @arguments16 = ("HDC16", "INT16");
my @arguments32 = ("HDC", "INT");
- &$function_found_callback("INT16", "WINAPI", $2 . "16", \@arguments16);
- &$function_found_callback("INT", "WINAPI", $2, \@arguments32);
+ &$function_begin("INT16", "WINAPI", $2 . "16", \@arguments16);
+ &$function_end;
+ &$function_begin("INT", "WINAPI", $2, \@arguments32);
+ &$function_end;
} elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1;
my @arguments16 = ("HWAVEIN16");
my @arguments32 = ("HWAVEIN");
- &$function_found_callback("UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
- &$function_found_callback("UINT", "WINAPI", "waveIn" . $1, \@arguments32);
+ &$function_begin("UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
+ &$function_end;
+ &$function_begin("UINT", "WINAPI", "waveIn" . $1, \@arguments32);
+ &$function_end;
} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1;
my @arguments16 = ("HWAVEOUT16");
my @arguments32 = ("HWAVEOUT");
- &$function_found_callback("UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
- &$function_found_callback("UINT", "WINAPI", "waveOut" . $1, \@arguments32);
+ &$function_begin("UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
+ &$function_end;
+ &$function_begin("UINT", "WINAPI", "waveOut" . $1, \@arguments32);
+ &$function_end;
} elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
$_ = $'; $again = 1;
if($1 eq "1") {
my @arguments16 = ("HWAVEOUT16", $4);
my @arguments32 = ("HWAVEOUT", $4);
- &$function_found_callback("UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
- &$function_found_callback("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
+ &$function_begin("UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
+ &$function_end;
+ &$function_begin("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
+ &$function_end;
} elsif($1 eq 2) {
my @arguments16 = ("UINT16", $4);
my @arguments32 = ("UINT", $4);
- &$function_found_callback("UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
- &$function_found_callback("UINT", "WINAPI", "waveOut" . $2, \@arguments32)
+ &$function_begin("UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
+ &$function_end;
+ &$function_begin("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
+ &$function_end;
}
} elsif(/;/s) {
$_ = $'; $again = 1;