- 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);
|
bless ($self, $class);
|
||||||
|
|
||||||
my $functions = \%{$self->{FUNCTIONS}};
|
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";
|
$/ = "\n";
|
||||||
while(<IN>) {
|
while(<IN>) {
|
||||||
s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
|
s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
|
||||||
s/^(.*?)\s*#.*$/$1/; # remove comments
|
s/^(.*?)\s*#.*$/$1/; # remove comments
|
||||||
/^$/ && next; # skip empty lines
|
/^$/ && 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);
|
close(IN);
|
||||||
|
|
||||||
|
@ -35,4 +77,22 @@ sub is_function {
|
||||||
return $$functions{$name};
|
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;
|
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
|
%longlong
|
||||||
|
|
||||||
LARGE_INTEGER
|
LARGE_INTEGER
|
||||||
|
ULARGE_INTEGER
|
||||||
|
|
||||||
%ptr
|
%ptr
|
||||||
|
|
||||||
|
@ -157,6 +158,7 @@ LPPAINTSTRUCT16
|
||||||
LPPALETTEENTRY
|
LPPALETTEENTRY
|
||||||
LPPDEVICE
|
LPPDEVICE
|
||||||
LPPOINT16
|
LPPOINT16
|
||||||
|
LPPRINTDLG16
|
||||||
LPQUEUESTRUCT16 *
|
LPQUEUESTRUCT16 *
|
||||||
LPRASTERIZER_STATUS
|
LPRASTERIZER_STATUS
|
||||||
LPRECT16
|
LPRECT16
|
||||||
|
@ -290,7 +292,6 @@ HANDLE16
|
||||||
HBITMAP16
|
HBITMAP16
|
||||||
HBRUSH16
|
HBRUSH16
|
||||||
HCURSOR16
|
HCURSOR16
|
||||||
HDC16
|
|
||||||
HDROP16
|
HDROP16
|
||||||
HDRVR16
|
HDRVR16
|
||||||
HDWP16
|
HDWP16
|
||||||
|
@ -330,7 +331,7 @@ WING_DITHER_TYPE
|
||||||
WORD
|
WORD
|
||||||
WPARAM16
|
WPARAM16
|
||||||
|
|
||||||
%unknown --forbidden
|
%unknown # --forbidden
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
FARPROC
|
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
|
CALID
|
||||||
CALTYPE
|
CALTYPE
|
||||||
CHAR
|
CHAR
|
||||||
CLIPFORMAT
|
|
||||||
COLORREF
|
|
||||||
COORD
|
COORD
|
||||||
DATE
|
DATE
|
||||||
DIGEST_HANDLE
|
DIGEST_HANDLE
|
||||||
|
@ -25,44 +23,25 @@ FLOAT
|
||||||
FOURCC
|
FOURCC
|
||||||
FS_INFORMATION_CLASS
|
FS_INFORMATION_CLASS
|
||||||
GET_FILEEX_INFO_LEVELS
|
GET_FILEEX_INFO_LEVELS
|
||||||
HACCEL
|
|
||||||
HACMDRIVER
|
|
||||||
HACMDRIVERID
|
|
||||||
HACMOBJ
|
|
||||||
HACMSTREAM
|
|
||||||
HANDLE
|
HANDLE
|
||||||
HBITMAP
|
|
||||||
HBRUSH
|
|
||||||
HCALL
|
HCALL
|
||||||
HCOLORSPACE
|
|
||||||
HCONV
|
HCONV
|
||||||
HCONVLIST
|
HCONVLIST
|
||||||
HCURSOR
|
|
||||||
HCRYPTKEY
|
HCRYPTKEY
|
||||||
HDC
|
|
||||||
HDDEDATA
|
HDDEDATA
|
||||||
HDESK
|
|
||||||
HDROP
|
HDROP
|
||||||
HDRVR
|
HDRVR
|
||||||
HDSA
|
HDSA
|
||||||
HDWP
|
HDWP
|
||||||
HENHMETAFILE
|
|
||||||
HFILE
|
HFILE
|
||||||
HFONT
|
|
||||||
HGDIOBJ
|
|
||||||
HGLOBAL
|
HGLOBAL
|
||||||
HHOOK
|
HHOOK
|
||||||
HIC
|
|
||||||
HICON
|
|
||||||
HIMC
|
|
||||||
HINSTANCE
|
HINSTANCE
|
||||||
HKEY
|
HKEY
|
||||||
HKL
|
HKL
|
||||||
HLINE
|
HLINE
|
||||||
HLINEAPP
|
HLINEAPP
|
||||||
HLOCAL
|
HLOCAL
|
||||||
HMENU
|
|
||||||
HMETAFILE
|
|
||||||
HMIDIIN
|
HMIDIIN
|
||||||
HMIDIOUT
|
HMIDIOUT
|
||||||
HMIDISTRM
|
HMIDISTRM
|
||||||
|
@ -70,23 +49,18 @@ HMIXER
|
||||||
HMIXEROBJ
|
HMIXEROBJ
|
||||||
HMMIO
|
HMMIO
|
||||||
HMODULE
|
HMODULE
|
||||||
HMONITOR
|
|
||||||
HOLEMENU
|
HOLEMENU
|
||||||
HPALETTE
|
|
||||||
HPEN
|
|
||||||
HPHONE
|
HPHONE
|
||||||
HPHONEAPP
|
HPHONEAPP
|
||||||
HPROPSHEETPAGE
|
HPROPSHEETPAGE
|
||||||
HPROVIDER
|
HPROVIDER
|
||||||
HRESULT
|
HRESULT
|
||||||
HRGN
|
|
||||||
HRSRC
|
HRSRC
|
||||||
HSZ
|
HSZ
|
||||||
HTASK
|
HTASK
|
||||||
HWAVEIN
|
HWAVEIN
|
||||||
HWAVEOUT
|
HWAVEOUT
|
||||||
HWINSTA
|
HWINSTA
|
||||||
HWND
|
|
||||||
INT
|
INT
|
||||||
KEY_INFORMATION_CLASS
|
KEY_INFORMATION_CLASS
|
||||||
KEY_VALUE_INFORMATION_CLASS
|
KEY_VALUE_INFORMATION_CLASS
|
||||||
|
@ -106,7 +80,6 @@ OLECLIPFORMAT
|
||||||
OLEOPT_RENDER
|
OLEOPT_RENDER
|
||||||
OLESTATUS
|
OLESTATUS
|
||||||
OLE_SERVER_USE
|
OLE_SERVER_USE
|
||||||
OUT
|
|
||||||
PHANDLE
|
PHANDLE
|
||||||
PHPROVIDER
|
PHPROVIDER
|
||||||
PIO_APC_ROUTINE
|
PIO_APC_ROUTINE
|
||||||
|
@ -117,6 +90,7 @@ POBJDIR_INFORMATION
|
||||||
PROCESSINFOCLASS
|
PROCESSINFOCLASS
|
||||||
PTIME_FIELDS
|
PTIME_FIELDS
|
||||||
PTOKEN_PRIVILEGES
|
PTOKEN_PRIVILEGES
|
||||||
|
REGKIND
|
||||||
REGSAM
|
REGSAM
|
||||||
SC_HANDLE
|
SC_HANDLE
|
||||||
SECTION_INHERIT
|
SECTION_INHERIT
|
||||||
|
@ -150,37 +124,21 @@ time_t
|
||||||
|
|
||||||
LARGE_INTEGER
|
LARGE_INTEGER
|
||||||
POINT
|
POINT
|
||||||
|
ULARGE_INTEGER
|
||||||
|
|
||||||
%ptr
|
%ptr
|
||||||
|
|
||||||
ABORTPROC
|
ABORTPROC
|
||||||
ACMDRIVERENUMCB
|
|
||||||
ACMFILTERENUMCBA
|
|
||||||
ACMFILTERENUMCBW
|
|
||||||
ACMFILTERTAGENUMCBA
|
|
||||||
ACMFILTERTAGENUMCBW
|
|
||||||
ACMFORMATENUMCBA
|
|
||||||
ACMFORMATENUMCBW
|
|
||||||
ACMFORMATTAGENUMCBA
|
|
||||||
ACMFORMATTAGENUMCBW
|
|
||||||
AVICOMPRESSOPTIONS *
|
|
||||||
AVISTREAMINFOA *
|
|
||||||
AVISTREAMINFOW *
|
|
||||||
BITMAP *
|
|
||||||
BITMAPINFO *
|
|
||||||
BITMAPINFOHEADER *
|
|
||||||
BOOL *
|
BOOL *
|
||||||
BSTR *
|
BSTR *
|
||||||
BYTE *
|
BYTE *
|
||||||
BY_HANDLE_FILE_INFORMATION *
|
BY_HANDLE_FILE_INFORMATION *
|
||||||
CALINFO_ENUMPROCA
|
CALINFO_ENUMPROCA
|
||||||
CHAR *
|
CHAR *
|
||||||
CLIPFORMAT *
|
|
||||||
CLSID *
|
CLSID *
|
||||||
CODEPAGE_ENUMPROCA
|
CODEPAGE_ENUMPROCA
|
||||||
CODEPAGE_ENUMPROCW
|
CODEPAGE_ENUMPROCW
|
||||||
COLORADJUSTMENT *
|
COLORADJUSTMENT *
|
||||||
COLORREF *
|
|
||||||
CONST
|
CONST
|
||||||
CONTEXT *
|
CONTEXT *
|
||||||
COSERVERINFO *
|
COSERVERINFO *
|
||||||
|
@ -238,6 +196,7 @@ HMENU *
|
||||||
HMIDIIN *
|
HMIDIIN *
|
||||||
HMIDIOUT *
|
HMIDIOUT *
|
||||||
HMIDISTRM *
|
HMIDISTRM *
|
||||||
|
HMODULE *
|
||||||
HMRU
|
HMRU
|
||||||
HOOKPROC
|
HOOKPROC
|
||||||
HPCSTR
|
HPCSTR
|
||||||
|
@ -254,6 +213,8 @@ IDropTarget *
|
||||||
ILockBytes *
|
ILockBytes *
|
||||||
IMAGEINFO *
|
IMAGEINFO *
|
||||||
IMAGELISTDRAWPARAMS *
|
IMAGELISTDRAWPARAMS *
|
||||||
|
IMoniker *
|
||||||
|
IMoniker **
|
||||||
INPUT_RECORD *
|
INPUT_RECORD *
|
||||||
INT *
|
INT *
|
||||||
IPersistStream *
|
IPersistStream *
|
||||||
|
@ -283,8 +244,6 @@ LPACCEL
|
||||||
LPAUTHDLGSTRUCTA
|
LPAUTHDLGSTRUCTA
|
||||||
LPAUXCAPSA
|
LPAUXCAPSA
|
||||||
LPAUXCAPSW
|
LPAUXCAPSW
|
||||||
LPAVIFILEINFOA
|
|
||||||
LPAVIFILEINFOW
|
|
||||||
LPBC *
|
LPBC *
|
||||||
LPBITMAPINFOHEADER
|
LPBITMAPINFOHEADER
|
||||||
LPBOOL
|
LPBOOL
|
||||||
|
@ -327,6 +286,7 @@ LPCWSTR *
|
||||||
LPDATAADVISEHOLDER *
|
LPDATAADVISEHOLDER *
|
||||||
LPDATAOBJECT
|
LPDATAOBJECT
|
||||||
LPDCB
|
LPDCB
|
||||||
|
LPDCB *
|
||||||
LPDDENUMCALLBACKA
|
LPDDENUMCALLBACKA
|
||||||
LPDDENUMCALLBACKEXA
|
LPDDENUMCALLBACKEXA
|
||||||
LPDDENUMCALLBACKEXW
|
LPDDENUMCALLBACKEXW
|
||||||
|
@ -434,8 +394,10 @@ LPMIXERLINECONTROLSW
|
||||||
LPMIXERLINEW
|
LPMIXERLINEW
|
||||||
LPMMCKINFO
|
LPMMCKINFO
|
||||||
LPMMIOPROC
|
LPMMIOPROC
|
||||||
|
LPMMIOPROC16
|
||||||
LPMMTIME
|
LPMMTIME
|
||||||
LPMODULEENTRY
|
LPMODULEENTRY
|
||||||
|
LPMODULEINFO
|
||||||
LPMONIKER
|
LPMONIKER
|
||||||
LPMONIKER *
|
LPMONIKER *
|
||||||
LPMONITORINFO
|
LPMONITORINFO
|
||||||
|
@ -579,31 +541,12 @@ PACE_HEADER
|
||||||
PACE_HEADER *
|
PACE_HEADER *
|
||||||
PACL
|
PACL
|
||||||
PACL *
|
PACL *
|
||||||
PACMDRIVERDETAILSA
|
|
||||||
PACMDRIVERDETAILSW
|
|
||||||
PACMFILTERCHOOSEA
|
|
||||||
PACMFILTERCHOOSEW
|
|
||||||
PACMFILTERDETAILSA
|
|
||||||
PACMFILTERDETAILSW
|
|
||||||
PACMFILTERTAGDETAILSA
|
|
||||||
PACMFILTERTAGDETAILSW
|
|
||||||
PACMFORMATCHOOSEA
|
|
||||||
PACMFORMATCHOOSEW
|
|
||||||
PACMFORMATDETAILSA
|
|
||||||
PACMFORMATDETAILSW
|
|
||||||
PACMFORMATTAGDETAILSA
|
|
||||||
PACMFORMATTAGDETAILSW
|
|
||||||
PACMSTREAMHEADER
|
|
||||||
PAINTSTRUCT *
|
PAINTSTRUCT *
|
||||||
PALETTEENTRY *
|
PALETTEENTRY *
|
||||||
PANSI_STRING
|
PANSI_STRING
|
||||||
PAPCFUNC
|
PAPCFUNC
|
||||||
PAPI_VERSION
|
PAPI_VERSION
|
||||||
PAPPBARDATA
|
PAPPBARDATA
|
||||||
PAVIFILE
|
|
||||||
PAVIFILE *
|
|
||||||
PAVISTREAM
|
|
||||||
PAVISTREAM *
|
|
||||||
PBOOLEAN
|
PBOOLEAN
|
||||||
PBYTE
|
PBYTE
|
||||||
PCHAR
|
PCHAR
|
||||||
|
@ -623,9 +566,6 @@ PFUNCTION_TABLE_ACCESS_ROUTINE
|
||||||
PGENERIC_MAPPING
|
PGENERIC_MAPPING
|
||||||
PGETFRAME
|
PGETFRAME
|
||||||
PGET_MODULE_BASE_ROUTINE
|
PGET_MODULE_BASE_ROUTINE
|
||||||
PHACMDRIVER
|
|
||||||
PHACMDRIVERID
|
|
||||||
PHACMSTREAM
|
|
||||||
PHONECALLBACK
|
PHONECALLBACK
|
||||||
PIMAGEHLP_MODULE
|
PIMAGEHLP_MODULE
|
||||||
PIMAGEHLP_STATUS_ROUTINE
|
PIMAGEHLP_STATUS_ROUTINE
|
||||||
|
@ -646,7 +586,9 @@ POBJECT_ATTRIBUTES
|
||||||
POINT *
|
POINT *
|
||||||
PPOLYTEXTA
|
PPOLYTEXTA
|
||||||
PPOLYTEXTW
|
PPOLYTEXTW
|
||||||
|
PPSAPI_WS_WATCH_INFORMATION
|
||||||
PPRIVILEGE_SET
|
PPRIVILEGE_SET
|
||||||
|
PPROCESS_MEMORY_COUNTERS
|
||||||
PREAD_PROCESS_MEMORY_ROUTINE
|
PREAD_PROCESS_MEMORY_ROUTINE
|
||||||
PRTL_HEAP_DEFINITION
|
PRTL_HEAP_DEFINITION
|
||||||
PROPENUMPROCA
|
PROPENUMPROCA
|
||||||
|
|
|
@ -8,18 +8,48 @@ sub new {
|
||||||
my $self = {};
|
my $self = {};
|
||||||
bless ($self, $class);
|
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_kind = \%{$self->{ALLOWED_KIND}};
|
||||||
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
|
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
|
||||||
my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
|
my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
|
||||||
|
my $allowed_modules_unlimited = \%{$self->{ALLOWED_MODULES_UNLIMITED}};
|
||||||
my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
|
my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
|
||||||
|
|
||||||
$self->{NAME} = shift;
|
|
||||||
my $file = shift;
|
my $file = shift;
|
||||||
|
my $module = shift;
|
||||||
|
|
||||||
my @modules;
|
|
||||||
my $kind;
|
my $kind;
|
||||||
my $forbidden = 0;
|
my $forbidden = 0;
|
||||||
|
|
||||||
|
$$output->progress("$file");
|
||||||
|
|
||||||
open(IN, "< $file") || die "$file: $!\n";
|
open(IN, "< $file") || die "$file: $!\n";
|
||||||
$/ = "\n";
|
$/ = "\n";
|
||||||
while(<IN>) {
|
while(<IN>) {
|
||||||
|
@ -29,34 +59,41 @@ sub new {
|
||||||
|
|
||||||
if(s/^%(\S+)\s*//) {
|
if(s/^%(\S+)\s*//) {
|
||||||
$kind = $1;
|
$kind = $1;
|
||||||
@modules = ();
|
|
||||||
$forbidden = 0;
|
$forbidden = 0;
|
||||||
|
|
||||||
$$allowed_kind{$kind} = 1;
|
$$allowed_kind{$kind} = 1;
|
||||||
if(/^--module=(\S*)/) {
|
if(/^--forbidden/) {
|
||||||
@modules = split(/,/, $1);
|
|
||||||
} elsif(/^--forbidden/) {
|
|
||||||
$forbidden = 1;
|
$forbidden = 1;
|
||||||
}
|
}
|
||||||
} elsif(defined($kind)) {
|
} elsif(defined($kind)) {
|
||||||
my $type = $_;
|
my $type = $_;
|
||||||
if(!$forbidden) {
|
if(!$forbidden) {
|
||||||
for my $module (@modules) {
|
if(defined($module)) {
|
||||||
$$allowed_modules_limited{$type} = 1;
|
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{$type}{$module} = 1;
|
||||||
|
$$allowed_modules_limited{$type} = 1;
|
||||||
|
} else {
|
||||||
|
print "$file: type ($type) already specificed\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$$allowed_modules_unlimited{$type} = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$$allowed_modules_limited{$type} = 1;
|
$$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;
|
$$translate_argument{$type} = $kind;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
print "$file: file must begin with %<type> statement\n";
|
print "$file: file must begin with %<type> statement\n";
|
||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(IN);
|
close(IN);
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_spec_file_type {
|
sub get_spec_file_type {
|
||||||
|
@ -88,7 +125,12 @@ sub read_spec_files {
|
||||||
my $win16api = shift;
|
my $win16api = shift;
|
||||||
my $win32api = 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);
|
my $type = 'winapi'->get_spec_file_type($file);
|
||||||
if($type eq "win16") {
|
if($type eq "win16") {
|
||||||
$win16api->parse_spec_file($file);
|
$win16api->parse_spec_file($file);
|
||||||
|
@ -100,16 +142,22 @@ sub read_spec_files {
|
||||||
|
|
||||||
sub parse_spec_file {
|
sub parse_spec_file {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
|
my $output = \${$self->{OUTPUT}};
|
||||||
my $function_arguments = \%{$self->{FUNCTION_ARGUMENTS}};
|
my $function_arguments = \%{$self->{FUNCTION_ARGUMENTS}};
|
||||||
my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
|
my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
|
||||||
my $function_stub = \%{$self->{FUNCTION_STUB}};
|
my $function_stub = \%{$self->{FUNCTION_STUB}};
|
||||||
my $function_module = \%{$self->{FUNCTION_MODULE}};
|
my $function_module = \%{$self->{FUNCTION_MODULE}};
|
||||||
|
|
||||||
|
|
||||||
my $file = shift;
|
my $file = shift;
|
||||||
|
|
||||||
|
my %ordinals;
|
||||||
my $type;
|
my $type;
|
||||||
my $module;
|
my $module;
|
||||||
|
|
||||||
|
$$output->progress("$file");
|
||||||
|
|
||||||
open(IN, "< $file") || die "$file: $!\n";
|
open(IN, "< $file") || die "$file: $!\n";
|
||||||
$/ = "\n";
|
$/ = "\n";
|
||||||
my $header = 1;
|
my $header = 1;
|
||||||
|
@ -126,18 +174,24 @@ sub parse_spec_file {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(/^\d+\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
|
my $ordinal;
|
||||||
my $calling_convention = $1;
|
if(/^(\d+)\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
|
||||||
my $external_name = $2;
|
my $calling_convention = $2;
|
||||||
my $arguments = $3;
|
my $external_name = $3;
|
||||||
my $internal_name = $4;
|
my $arguments = $4;
|
||||||
|
my $internal_name = $5;
|
||||||
|
|
||||||
|
$ordinal = $1;
|
||||||
|
|
||||||
# FIXME: Internal name existing more than once not handled properly
|
# FIXME: Internal name existing more than once not handled properly
|
||||||
$$function_arguments{$internal_name} = $arguments;
|
$$function_arguments{$internal_name} = $arguments;
|
||||||
$$function_calling_convention{$internal_name} = $calling_convention;
|
$$function_calling_convention{$internal_name} = $calling_convention;
|
||||||
$$function_module{$internal_name} = $module;
|
$$function_module{$internal_name} = "$module";
|
||||||
} elsif(/^\d+\s+stub\s+(\S+)$/) {
|
} elsif(/^(\d+)\s+stub\s+(\S+)$/) {
|
||||||
my $external_name = $1;
|
my $external_name = $2;
|
||||||
|
|
||||||
|
$ordinal = $1;
|
||||||
|
|
||||||
$$function_stub{$external_name} = 1;
|
$$function_stub{$external_name} = 1;
|
||||||
$$function_module{$external_name} = $module;
|
$$function_module{$external_name} = $module;
|
||||||
} elsif(/^\d+\s+(equate|long|word|extern|forward)/) {
|
} elsif(/^\d+\s+(equate|long|word|extern|forward)/) {
|
||||||
|
@ -151,13 +205,22 @@ sub parse_spec_file {
|
||||||
$lookahead = 1;
|
$lookahead = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(defined($ordinal)) {
|
||||||
|
if($ordinals{$ordinal}) {
|
||||||
|
print "$file: ordinal redefined: $_\n";
|
||||||
|
}
|
||||||
|
$ordinals{$ordinal}++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
close(IN);
|
close(IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub name {
|
sub name {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->{NAME};
|
my $name = \${$self->{NAME}};
|
||||||
|
|
||||||
|
return $$name;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub is_allowed_kind {
|
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 {
|
sub allowed_type_in_module {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
|
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
|
||||||
|
@ -183,6 +255,34 @@ sub allowed_type_in_module {
|
||||||
return !$$allowed_modules_limited{$type} || $$allowed_modules{$type}{$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 {
|
sub translate_argument {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
|
my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
|
||||||
|
@ -226,7 +326,7 @@ sub all_functions {
|
||||||
|
|
||||||
sub all_functions_found {
|
sub all_functions_found {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $function_found = \$self->{FUNCTION_FOUND};
|
my $function_found = \%{$self->{FUNCTION_FOUND}};
|
||||||
|
|
||||||
return sort(keys(%$function_found));
|
return sort(keys(%$function_found));
|
||||||
}
|
}
|
||||||
|
@ -282,11 +382,7 @@ sub function_module {
|
||||||
|
|
||||||
my $name = shift;
|
my $name = shift;
|
||||||
|
|
||||||
if($self->is_function($name)) {
|
|
||||||
return $$function_module{$name};
|
return $$function_module{$name};
|
||||||
} else {
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub function_stub {
|
sub function_stub {
|
||||||
|
|
|
@ -20,15 +20,19 @@ BEGIN {
|
||||||
}
|
}
|
||||||
@INC = ($winapi_check_dir);
|
@INC = ($winapi_check_dir);
|
||||||
|
|
||||||
require "winapi.pm";
|
|
||||||
require "nativeapi.pm";
|
require "nativeapi.pm";
|
||||||
|
require "output.pm";
|
||||||
|
require "preprocessor.pm";
|
||||||
|
require "winapi.pm";
|
||||||
require "winapi_local.pm";
|
require "winapi_local.pm";
|
||||||
require "winapi_global.pm";
|
require "winapi_global.pm";
|
||||||
require "winapi_options.pm";
|
require "winapi_options.pm";
|
||||||
require "winapi_parser.pm";
|
require "winapi_parser.pm";
|
||||||
|
|
||||||
import winapi;
|
|
||||||
import nativeapi;
|
import nativeapi;
|
||||||
|
import output;
|
||||||
|
import preprocessor;
|
||||||
|
import winapi;
|
||||||
import winapi_local;
|
import winapi_local;
|
||||||
import winapi_global;
|
import winapi_global;
|
||||||
import winapi_options;
|
import winapi_options;
|
||||||
|
@ -41,11 +45,13 @@ if($options->help) {
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $win16api = 'winapi'->new("win16", "$winapi_check_dir/win16api.dat");
|
my $output = 'output'->new;
|
||||||
my $win32api = 'winapi'->new("win32", "$winapi_check_dir/win32api.dat");
|
|
||||||
|
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);
|
'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) {
|
for my $name ($win32api->all_functions) {
|
||||||
my $module16 = $win16api->function_module($name);
|
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) {
|
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 $found_function = sub {
|
||||||
my $return_type = shift;
|
my $return_type = shift;
|
||||||
my $calling_convention = shift;
|
my $calling_convention = shift;
|
||||||
my $name = shift;
|
my $name = shift;
|
||||||
my $refarguments = shift;
|
my $refarguments = shift;
|
||||||
my @arguments = @$refarguments;
|
my @arguments = @$refarguments;
|
||||||
|
my $statements = shift;
|
||||||
|
|
||||||
if($options->global) {
|
if($options->global) {
|
||||||
$win16api->found_type($return_type) if $options->win16;
|
$win16api->found_type($return_type) if $options->win16;
|
||||||
|
@ -84,15 +134,37 @@ foreach my $file ($options->files) {
|
||||||
if($options->local) {
|
if($options->local) {
|
||||||
my $module16 = $win16api->function_module($name);
|
my $module16 = $win16api->function_module($name);
|
||||||
my $module32 = $win32api->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;
|
my $module = shift;
|
||||||
return sub {
|
return sub {
|
||||||
my $msg = shift;
|
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 $output16 = &$output_module($module16);
|
||||||
my $output32 = &$output($module32);
|
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->argument) {
|
||||||
if($options->win16 && $options->report_module($module16)) {
|
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) {
|
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, $win16api, $nativeapi if $options->win16;
|
||||||
winapi_global::check $options, $win32api, $nativeapi if $options->win32;
|
winapi_global::check $options, $win32api, $nativeapi if $options->win32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,9 @@ sub check {
|
||||||
|
|
||||||
if($options->argument) {
|
if($options->argument) {
|
||||||
foreach my $type ($winapi->all_declared_types) {
|
foreach my $type ($winapi->all_declared_types) {
|
||||||
if(!$winapi->type_found($type) && $type ne "CONTEXT86 *") {
|
if(!$winapi->type_found($type) && !$winapi->is_type_limited($type) && $type ne "CONTEXT86 *") {
|
||||||
print "*.c: $winver: $type: ";
|
print "*.c: $winver: ";
|
||||||
print "type not used\n";
|
print "type ($type) not used\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,19 +21,22 @@ sub check {
|
||||||
if($options->declared) {
|
if($options->declared) {
|
||||||
foreach my $name ($winapi->all_functions) {
|
foreach my $name ($winapi->all_functions) {
|
||||||
if(!$winapi->function_found($name) && !$nativeapi->is_function($name)) {
|
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";
|
print "function declared but not implemented: " . $winapi->function_arguments($name) . "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($options->implemented) {
|
if($options->argument_forbidden) {
|
||||||
foreach my $name ($winapi->all_functions_found) {
|
my $not_used = $winapi->types_not_used;
|
||||||
if($winapi->function_stub($name)) {
|
|
||||||
print "*.c: $winver: $name: ";
|
foreach my $module (sort(keys(%$not_used))) {
|
||||||
print "function implemented but not declared\n";
|
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);
|
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 $forbidden_return_type = 0;
|
||||||
my $implemented_return_kind;
|
my $implemented_return_kind;
|
||||||
|
$winapi->type_used_in_module($return_type,$module);
|
||||||
if(!defined($implemented_return_kind = $winapi->translate_argument($return_type))) {
|
if(!defined($implemented_return_kind = $winapi->translate_argument($return_type))) {
|
||||||
if($return_type ne "") {
|
if($return_type ne "") {
|
||||||
&$output("no translation defined: " . $return_type);
|
&$output("no translation defined: " . $return_type);
|
||||||
|
@ -50,6 +72,8 @@ sub check_arguments {
|
||||||
$implemented_calling_convention = "varargs";
|
$implemented_calling_convention = "varargs";
|
||||||
} elsif($calling_convention =~ /^__stdcall|VFWAPI|WINAPI$/) {
|
} elsif($calling_convention =~ /^__stdcall|VFWAPI|WINAPI$/) {
|
||||||
$implemented_calling_convention = "stdcall";
|
$implemented_calling_convention = "stdcall";
|
||||||
|
} else {
|
||||||
|
$implemented_calling_convention = "<default>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,15 +109,12 @@ sub check_arguments {
|
||||||
|
|
||||||
if($name =~ /^CRTDLL__ftol|CRTDLL__CIpow$/) {
|
if($name =~ /^CRTDLL__ftol|CRTDLL__CIpow$/) {
|
||||||
# ignore
|
# ignore
|
||||||
} elsif($#argument_types != $#declared_argument_kinds) {
|
|
||||||
if($options->argument_count) {
|
|
||||||
&$output("argument count differs: " . ($#argument_types + 1) . " != " . ($#declared_argument_kinds + 1));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
my $n = 0;
|
my $n = 0;
|
||||||
my @argument_kinds = map {
|
my @argument_kinds = map {
|
||||||
my $type = $_;
|
my $type = $_;
|
||||||
my $kind = "unknown";
|
my $kind = "unknown";
|
||||||
|
$winapi->type_used_in_module($type,$module);
|
||||||
if(!defined($kind = $winapi->translate_argument($type))) {
|
if(!defined($kind = $winapi->translate_argument($type))) {
|
||||||
&$output("no translation defined: " . $type);
|
&$output("no translation defined: " . $type);
|
||||||
} elsif(!$winapi->is_allowed_kind($kind) ||
|
} elsif(!$winapi->is_allowed_kind($kind) ||
|
||||||
|
@ -102,8 +123,13 @@ sub check_arguments {
|
||||||
&$output("forbidden argument " . ($n + 1) . " type (" . $type . ")");
|
&$output("forbidden argument " . ($n + 1) . " type (" . $type . ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(defined($kind) && $kind eq "longlong") {
|
||||||
|
$n+=2;
|
||||||
|
("long", "long");
|
||||||
|
} else {
|
||||||
$n++;
|
$n++;
|
||||||
$kind;
|
$kind;
|
||||||
|
}
|
||||||
} @argument_types;
|
} @argument_types;
|
||||||
|
|
||||||
for my $n (0..$#argument_kinds) {
|
for my $n (0..$#argument_kinds) {
|
||||||
|
@ -123,8 +149,13 @@ sub check_arguments {
|
||||||
$argument_types[$n] . " ($argument_kinds[$n]) != " . $declared_argument_kinds[$n]);
|
$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)) {
|
if($segmented && $options->shared_segmented && $winapi->is_shared_function($name)) {
|
||||||
|
|
|
@ -23,12 +23,17 @@ my %options = (
|
||||||
"help" => { default => 0, description => "help mode" },
|
"help" => { default => 0, description => "help mode" },
|
||||||
"verbose" => { default => 0, description => "verbose mode" },
|
"verbose" => { default => 0, description => "verbose mode" },
|
||||||
|
|
||||||
|
"progress" => { default => 1, description => "show progress" },
|
||||||
|
|
||||||
"win16" => { default => 1, description => "Win16 checking" },
|
"win16" => { default => 1, description => "Win16 checking" },
|
||||||
"win32" => { default => 1, description => "Win32 checking" },
|
"win32" => { default => 1, description => "Win32 checking" },
|
||||||
|
|
||||||
"shared" => { default => 0, description => "show shared functions between Win16 and Win32" },
|
"shared" => { default => 0, description => "show shared functions between Win16 and Win32" },
|
||||||
"shared-segmented" => { default => 0, description => "segmented shared functions between Win16 and Win32 checking" },
|
"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" },
|
"local" => { default => 1, description => "local checking" },
|
||||||
"module" => {
|
"module" => {
|
||||||
default => { active => 1, filter => 0, hash => {} },
|
default => { active => 1, filter => 0, hash => {} },
|
||||||
|
@ -40,7 +45,7 @@ my %options = (
|
||||||
"argument" => { default => 1, parent => "local", description => "argument checking" },
|
"argument" => { default => 1, parent => "local", description => "argument checking" },
|
||||||
"argument-count" => { default => 1, parent => "argument", description => "argument count checking" },
|
"argument-count" => { default => 1, parent => "argument", description => "argument count checking" },
|
||||||
"argument-forbidden" => {
|
"argument-forbidden" => {
|
||||||
default => { active => 0, filter => 0, hash => {} },
|
default => { active => 1, filter => 0, hash => {} },
|
||||||
parent => "argument",
|
parent => "argument",
|
||||||
parser => \&parser_comma_list,
|
parser => \&parser_comma_list,
|
||||||
description => "argument forbidden checking"
|
description => "argument forbidden checking"
|
||||||
|
@ -52,12 +57,14 @@ my %options = (
|
||||||
description => "argument kind checking"
|
description => "argument kind checking"
|
||||||
},
|
},
|
||||||
"calling-convention" => { default => 0, parent => "local", description => "calling convention 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" },
|
"global" => { default => 1, description => "global checking" },
|
||||||
"declared" => { default => 1, parent => "global", description => "declared 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 = (
|
my %short_options = (
|
||||||
|
|
|
@ -6,6 +6,27 @@ sub parse_c_file {
|
||||||
my $options = shift;
|
my $options = shift;
|
||||||
my $file = shift;
|
my $file = shift;
|
||||||
my $function_found_callback = 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 $level = 0;
|
||||||
my $again = 0;
|
my $again = 0;
|
||||||
|
@ -44,34 +65,61 @@ sub parse_c_file {
|
||||||
if(/^\s*$/) { next; }
|
if(/^\s*$/) { next; }
|
||||||
|
|
||||||
# remove preprocessor directives
|
# 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)
|
if($level > 0)
|
||||||
{
|
{
|
||||||
s/^[^\{\}]*//s;
|
my $line;
|
||||||
if(/^\{/) {
|
s/^([^\{\}]*)//s;
|
||||||
|
$line = $1;
|
||||||
|
if(/^(\{)/) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
|
$line .= $1;
|
||||||
print "+1: $_\n" if $options->debug >= 2;
|
print "+1: $_\n" if $options->debug >= 2;
|
||||||
$level++;
|
$level++;
|
||||||
} elsif(/^\}/) {
|
} elsif(/^(\})/) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
|
$line .= $1 if $level > 1;
|
||||||
print "-1: $_\n" if $options->debug >= 2;
|
print "-1: $_\n" if $options->debug >= 2;
|
||||||
$level--;
|
$level--;
|
||||||
}
|
}
|
||||||
|
if($line !~ /^\s*$/) {
|
||||||
|
$statements .= "$line\n";
|
||||||
|
}
|
||||||
|
if($function && $level == 0) {
|
||||||
|
&$function_end;
|
||||||
|
}
|
||||||
next;
|
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;
|
$_ = $'; $again = 1;
|
||||||
|
|
||||||
if($9 eq ";") {
|
if($10 eq ";") {
|
||||||
next;
|
next;
|
||||||
} elsif($9 eq "{") {
|
} elsif($10 eq "{") {
|
||||||
$level++;
|
$level++;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $return_type = $1;
|
my $return_type = $1;
|
||||||
my $calling_convention = $5;
|
my $calling_convention = $6;
|
||||||
my $name = $6;
|
my $name = $7;
|
||||||
my $arguments = $8;
|
my $arguments = $9;
|
||||||
|
|
||||||
|
if(!defined($calling_convention)) {
|
||||||
|
$calling_convention = "";
|
||||||
|
}
|
||||||
|
|
||||||
$return_type =~ s/\s*$//;
|
$return_type =~ s/\s*$//;
|
||||||
$return_type =~ s/\s*\*\s*/*/g;
|
$return_type =~ s/\s*\*\s*/*/g;
|
||||||
|
@ -88,7 +136,8 @@ sub parse_c_file {
|
||||||
my $argument = $arguments[$n];
|
my $argument = $arguments[$n];
|
||||||
$argument =~ s/^\s*(.*?)\s*$/$1/;
|
$argument =~ s/^\s*(.*?)\s*$/$1/;
|
||||||
#print " " . ($n + 1) . ": '$argument'\n";
|
#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 =~ /^...$/) {
|
if($argument =~ /^...$/) {
|
||||||
$argument = "...";
|
$argument = "...";
|
||||||
} elsif($argument =~ /^((struct\s+|union\s+|enum\s+)?\w+)\s*((\*\s*?)*)\s*/) {
|
} elsif($argument =~ /^((struct\s+|union\s+|enum\s+)?\w+)\s*((\*\s*?)*)\s*/) {
|
||||||
|
@ -107,52 +156,66 @@ sub parse_c_file {
|
||||||
if($options->debug) {
|
if($options->debug) {
|
||||||
print "$file: $return_type $calling_convention $name(" . join(",", @arguments) . ")\n";
|
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) {
|
} elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
my @arguments = ("HDC16");
|
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) {
|
} elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
my @arguments = ("HDC");
|
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) {
|
} elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
my @arguments16 = ("HDC16", "LP" . $5 . "16");
|
my @arguments16 = ("HDC16", "LP" . $5 . "16");
|
||||||
my @arguments32 = ("HDC", "LP" . $5);
|
my @arguments32 = ("HDC", "LP" . $5);
|
||||||
&$function_found_callback("BOOL16", "WINAPI", $2 . "16", \@arguments16);
|
&$function_begin("BOOL16", "WINAPI", $2 . "16", \@arguments16);
|
||||||
&$function_found_callback("BOOL", "WINAPI", $2, \@arguments32);
|
&$function_end;
|
||||||
|
&$function_begin("BOOL", "WINAPI", $2, \@arguments32);
|
||||||
|
&$function_end;
|
||||||
} elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
} elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
my @arguments16 = ("HDC16", "INT16");
|
my @arguments16 = ("HDC16", "INT16");
|
||||||
my @arguments32 = ("HDC", "INT");
|
my @arguments32 = ("HDC", "INT");
|
||||||
&$function_found_callback("INT16", "WINAPI", $2 . "16", \@arguments16);
|
&$function_begin("INT16", "WINAPI", $2 . "16", \@arguments16);
|
||||||
&$function_found_callback("INT", "WINAPI", $2, \@arguments32);
|
&$function_end;
|
||||||
|
&$function_begin("INT", "WINAPI", $2, \@arguments32);
|
||||||
|
&$function_end;
|
||||||
} elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
} elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
my @arguments16 = ("HWAVEIN16");
|
my @arguments16 = ("HWAVEIN16");
|
||||||
my @arguments32 = ("HWAVEIN");
|
my @arguments32 = ("HWAVEIN");
|
||||||
&$function_found_callback("UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
|
&$function_begin("UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
|
||||||
&$function_found_callback("UINT", "WINAPI", "waveIn" . $1, \@arguments32);
|
&$function_end;
|
||||||
|
&$function_begin("UINT", "WINAPI", "waveIn" . $1, \@arguments32);
|
||||||
|
&$function_end;
|
||||||
} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
my @arguments16 = ("HWAVEOUT16");
|
my @arguments16 = ("HWAVEOUT16");
|
||||||
my @arguments32 = ("HWAVEOUT");
|
my @arguments32 = ("HWAVEOUT");
|
||||||
&$function_found_callback("UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
|
&$function_begin("UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
|
||||||
&$function_found_callback("UINT", "WINAPI", "waveOut" . $1, \@arguments32);
|
&$function_end;
|
||||||
|
&$function_begin("UINT", "WINAPI", "waveOut" . $1, \@arguments32);
|
||||||
|
&$function_end;
|
||||||
} elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
} elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
if($1 eq "1") {
|
if($1 eq "1") {
|
||||||
my @arguments16 = ("HWAVEOUT16", $4);
|
my @arguments16 = ("HWAVEOUT16", $4);
|
||||||
my @arguments32 = ("HWAVEOUT", $4);
|
my @arguments32 = ("HWAVEOUT", $4);
|
||||||
&$function_found_callback("UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
|
&$function_begin("UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
|
||||||
&$function_found_callback("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
|
&$function_end;
|
||||||
|
&$function_begin("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
|
||||||
|
&$function_end;
|
||||||
} elsif($1 eq 2) {
|
} elsif($1 eq 2) {
|
||||||
my @arguments16 = ("UINT16", $4);
|
my @arguments16 = ("UINT16", $4);
|
||||||
my @arguments32 = ("UINT", $4);
|
my @arguments32 = ("UINT", $4);
|
||||||
&$function_found_callback("UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
|
&$function_begin("UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
|
||||||
&$function_found_callback("UINT", "WINAPI", "waveOut" . $2, \@arguments32)
|
&$function_end;
|
||||||
|
&$function_begin("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
|
||||||
|
&$function_end;
|
||||||
}
|
}
|
||||||
} elsif(/;/s) {
|
} elsif(/;/s) {
|
||||||
$_ = $'; $again = 1;
|
$_ = $'; $again = 1;
|
||||||
|
|
Loading…
Reference in New Issue