- 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.
This commit is contained in:
parent
d7da486c96
commit
5b3b6d981d
|
@ -9,17 +9,59 @@ sub new {
|
|||
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 @@ sub is_function {
|
|||
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;
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -0,0 +1,3 @@
|
|||
%word
|
||||
|
||||
HDC16
|
|
@ -0,0 +1,3 @@
|
|||
%word
|
||||
|
||||
HDC16
|
|
@ -0,0 +1,3 @@
|
|||
%word
|
||||
|
||||
HDC16
|
|
@ -0,0 +1,3 @@
|
|||
%word
|
||||
|
||||
HDC16
|
|
@ -0,0 +1,3 @@
|
|||
%word
|
||||
|
||||
HDC16
|
|
@ -24,6 +24,7 @@ ULONG
|
|||
%longlong
|
||||
|
||||
LARGE_INTEGER
|
||||
ULARGE_INTEGER
|
||||
|
||||
%ptr
|
||||
|
||||
|
@ -157,6 +158,7 @@ LPPAINTSTRUCT16
|
|||
LPPALETTEENTRY
|
||||
LPPDEVICE
|
||||
LPPOINT16
|
||||
LPPRINTDLG16
|
||||
LPQUEUESTRUCT16 *
|
||||
LPRASTERIZER_STATUS
|
||||
LPRECT16
|
||||
|
@ -290,7 +292,6 @@ HANDLE16
|
|||
HBITMAP16
|
||||
HBRUSH16
|
||||
HCURSOR16
|
||||
HDC16
|
||||
HDROP16
|
||||
HDRVR16
|
||||
HDWP16
|
||||
|
@ -330,7 +331,7 @@ WING_DITHER_TYPE
|
|||
WORD
|
||||
WPARAM16
|
||||
|
||||
%unknown --forbidden
|
||||
%unknown # --forbidden
|
||||
|
||||
BOOL
|
||||
FARPROC
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
%ptr
|
||||
|
||||
AVICOMPRESSOPTIONS *
|
||||
AVISTREAMINFOA *
|
||||
AVISTREAMINFOW *
|
||||
IAVIFile *
|
||||
LPAVIFILEINFOA
|
||||
LPAVIFILEINFOW
|
||||
PAVIFILE
|
||||
PAVIFILE *
|
||||
PAVISTREAM
|
||||
PAVISTREAM *
|
|
@ -0,0 +1,7 @@
|
|||
%long
|
||||
|
||||
COLORREF
|
||||
HBITMAP
|
||||
HDC
|
||||
HICON
|
||||
HWND
|
|
@ -0,0 +1,3 @@
|
|||
%long
|
||||
|
||||
HWND
|
|
@ -0,0 +1,22 @@
|
|||
%long
|
||||
|
||||
COLORREF
|
||||
HBITMAP
|
||||
HBRUSH
|
||||
HCOLORSPACE
|
||||
HDC
|
||||
HENHMETAFILE
|
||||
HFONT
|
||||
HGDIOBJ
|
||||
HMETAFILE
|
||||
HPALETTE
|
||||
HPEN
|
||||
HRGN
|
||||
HWND
|
||||
|
||||
%ptr
|
||||
|
||||
BITMAP *
|
||||
BITMAPINFO *
|
||||
BITMAPINFOHEADER *
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
%long
|
||||
|
||||
HWND
|
||||
HIMC
|
|
@ -0,0 +1,3 @@
|
|||
%long
|
||||
|
||||
HWND
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
%long
|
||||
|
||||
HDC
|
||||
HIC
|
||||
HPALETTE
|
||||
HWND
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
%long
|
||||
|
||||
CLIPFORMAT
|
||||
HACCEL
|
||||
HMENU
|
||||
HWND
|
||||
|
||||
%ptr
|
||||
CLIPFORMAT *
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
%long
|
||||
|
||||
HPALETTE
|
||||
|
||||
%ptr
|
||||
|
||||
COLORREF *
|
|
@ -0,0 +1,3 @@
|
|||
%long
|
||||
|
||||
HDC
|
|
@ -0,0 +1,4 @@
|
|||
%long
|
||||
|
||||
HMENU
|
||||
HWND
|
|
@ -0,0 +1,8 @@
|
|||
%long
|
||||
|
||||
COLORREF
|
||||
HBITMAP
|
||||
HMENU
|
||||
HICON
|
||||
HWND
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
%long
|
||||
|
||||
HWND
|
|
@ -0,0 +1,3 @@
|
|||
%long
|
||||
|
||||
HWND
|
|
@ -0,0 +1,19 @@
|
|||
%long
|
||||
|
||||
COLORREF
|
||||
HACCEL
|
||||
HBITMAP
|
||||
HBRUSH
|
||||
HCURSOR
|
||||
HDC
|
||||
HDESK
|
||||
HFONT
|
||||
HICON
|
||||
HMENU
|
||||
HMONITOR
|
||||
HRGN
|
||||
HWND
|
||||
|
||||
%ptr
|
||||
|
||||
COLORREF *
|
|
@ -0,0 +1,3 @@
|
|||
%long
|
||||
|
||||
HWND
|
|
@ -0,0 +1,3 @@
|
|||
%long
|
||||
|
||||
HWND
|
|
@ -0,0 +1,3 @@
|
|||
%long
|
||||
|
||||
HWND
|
|
@ -13,8 +13,6 @@ BYTE
|
|||
CALID
|
||||
CALTYPE
|
||||
CHAR
|
||||
CLIPFORMAT
|
||||
COLORREF
|
||||
COORD
|
||||
DATE
|
||||
DIGEST_HANDLE
|
||||
|
@ -25,44 +23,25 @@ FLOAT
|
|||
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 @@ HMIXER
|
|||
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 @@ OLECLIPFORMAT
|
|||
OLEOPT_RENDER
|
||||
OLESTATUS
|
||||
OLE_SERVER_USE
|
||||
OUT
|
||||
PHANDLE
|
||||
PHPROVIDER
|
||||
PIO_APC_ROUTINE
|
||||
|
@ -117,6 +90,7 @@ POBJDIR_INFORMATION
|
|||
PROCESSINFOCLASS
|
||||
PTIME_FIELDS
|
||||
PTOKEN_PRIVILEGES
|
||||
REGKIND
|
||||
REGSAM
|
||||
SC_HANDLE
|
||||
SECTION_INHERIT
|
||||
|
@ -150,37 +124,21 @@ time_t
|
|||
|
||||
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 @@ HMENU *
|
|||
HMIDIIN *
|
||||
HMIDIOUT *
|
||||
HMIDISTRM *
|
||||
HMODULE *
|
||||
HMRU
|
||||
HOOKPROC
|
||||
HPCSTR
|
||||
|
@ -254,6 +213,8 @@ IDropTarget *
|
|||
ILockBytes *
|
||||
IMAGEINFO *
|
||||
IMAGELISTDRAWPARAMS *
|
||||
IMoniker *
|
||||
IMoniker **
|
||||
INPUT_RECORD *
|
||||
INT *
|
||||
IPersistStream *
|
||||
|
@ -283,8 +244,6 @@ LPACCEL
|
|||
LPAUTHDLGSTRUCTA
|
||||
LPAUXCAPSA
|
||||
LPAUXCAPSW
|
||||
LPAVIFILEINFOA
|
||||
LPAVIFILEINFOW
|
||||
LPBC *
|
||||
LPBITMAPINFOHEADER
|
||||
LPBOOL
|
||||
|
@ -327,6 +286,7 @@ LPCWSTR *
|
|||
LPDATAADVISEHOLDER *
|
||||
LPDATAOBJECT
|
||||
LPDCB
|
||||
LPDCB *
|
||||
LPDDENUMCALLBACKA
|
||||
LPDDENUMCALLBACKEXA
|
||||
LPDDENUMCALLBACKEXW
|
||||
|
@ -434,8 +394,10 @@ LPMIXERLINECONTROLSW
|
|||
LPMIXERLINEW
|
||||
LPMMCKINFO
|
||||
LPMMIOPROC
|
||||
LPMMIOPROC16
|
||||
LPMMTIME
|
||||
LPMODULEENTRY
|
||||
LPMODULEINFO
|
||||
LPMONIKER
|
||||
LPMONIKER *
|
||||
LPMONITORINFO
|
||||
|
@ -579,31 +541,12 @@ PACE_HEADER
|
|||
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 @@ PFUNCTION_TABLE_ACCESS_ROUTINE
|
|||
PGENERIC_MAPPING
|
||||
PGETFRAME
|
||||
PGET_MODULE_BASE_ROUTINE
|
||||
PHACMDRIVER
|
||||
PHACMDRIVERID
|
||||
PHACMSTREAM
|
||||
PHONECALLBACK
|
||||
PIMAGEHLP_MODULE
|
||||
PIMAGEHLP_STATUS_ROUTINE
|
||||
|
@ -646,7 +586,9 @@ POBJECT_ATTRIBUTES
|
|||
POINT *
|
||||
PPOLYTEXTA
|
||||
PPOLYTEXTW
|
||||
PPSAPI_WS_WATCH_INFORMATION
|
||||
PPRIVILEGE_SET
|
||||
PPROCESS_MEMORY_COUNTERS
|
||||
PREAD_PROCESS_MEMORY_ROUTINE
|
||||
PRTL_HEAP_DEFINITION
|
||||
PROPENUMPROCA
|
||||
|
|
|
@ -8,18 +8,48 @@ sub new {
|
|||
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 @@ sub new {
|
|||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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 @@ sub read_spec_files {
|
|||
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 read_spec_files {
|
|||
|
||||
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 @@ sub parse_spec_file {
|
|||
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 @@ sub parse_spec_file {
|
|||
$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_allowed_kind {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ sub allowed_type_in_module {
|
|||
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 {
|
|||
|
||||
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 @@ sub function_module {
|
|||
|
||||
my $name = shift;
|
||||
|
||||
if($self->is_function($name)) {
|
||||
return $$function_module{$name};
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
sub function_stub {
|
||||
|
|
|
@ -20,15 +20,19 @@ BEGIN {
|
|||
}
|
||||
@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 @@ if($options->help) {
|
|||
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 @@ for my $name ($win32api->all_functions) {
|
|||
}
|
||||
}
|
||||
|
||||
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,15 +134,37 @@ foreach my $file ($options->files) {
|
|||
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)) {
|
||||
|
@ -122,12 +194,145 @@ foreach my $file ($options->files) {
|
|||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ sub check {
|
|||
|
||||
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 @@ sub check {
|
|||
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";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,30 @@ sub check_arguments {
|
|||
|
||||
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);
|
||||
|
@ -50,6 +72,8 @@ sub check_arguments {
|
|||
$implemented_calling_convention = "varargs";
|
||||
} elsif($calling_convention =~ /^__stdcall|VFWAPI|WINAPI$/) {
|
||||
$implemented_calling_convention = "stdcall";
|
||||
} else {
|
||||
$implemented_calling_convention = "<default>";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,15 +109,12 @@ sub check_arguments {
|
|||
|
||||
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 @@ sub check_arguments {
|
|||
&$output("forbidden argument " . ($n + 1) . " type (" . $type . ")");
|
||||
}
|
||||
}
|
||||
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 @@ sub check_arguments {
|
|||
$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)) {
|
||||
|
|
|
@ -23,12 +23,17 @@ my %options = (
|
|||
"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 @@ my %options = (
|
|||
"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 @@ my %options = (
|
|||
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 = (
|
||||
|
|
|
@ -6,6 +6,27 @@ sub parse_c_file {
|
|||
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 @@ sub parse_c_file {
|
|||
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 @@ sub parse_c_file {
|
|||
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 @@ sub parse_c_file {
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue