Several bug fixes and additions.
diff --git a/tools/winapi/config.pm b/tools/winapi/config.pm
index dc30a2c..6bf25f9 100644
--- a/tools/winapi/config.pm
+++ b/tools/winapi/config.pm
@@ -119,7 +119,7 @@
if(/^__cdecl$/) {
return "cdecl";
} elsif(/^VFWAPIV|WINAPIV$/) {
- return "varargs";
+ return "pascal"; # FIXME: Is this correct?
} elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
return "pascal";
} elsif(/^__asm$/) {
diff --git a/tools/winapi/winapi_extract b/tools/winapi/winapi_extract
index e6e6b31..dfe3894 100755
--- a/tools/winapi/winapi_extract
+++ b/tools/winapi/winapi_extract
@@ -118,23 +118,54 @@
local $_;
foreach (split(/\n/, $documentation)) {
- if(/^\s*\*\s*(\w+|\@)\s*[\(\[]\s*(\w+)\s*\.\s*(\@|\d+)\s*[\)\]]/) {
+ if(/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+)\s*\.\s*(\S+)\s*[\)\]]/) {
my $external_name = $1;
my $module = lc($2);
my $ordinal = $3;
if($ordinal eq "@") {
- $specifications{$module}{unfixed}{$external_name}{debug_channels} = [@debug_channels];
- $specifications{$module}{unfixed}{$external_name}{internal_name} = $internal_name;
- $specifications{$module}{unfixed}{$external_name}{external_name} = $external_name;
- $specifications{$module}{unfixed}{$external_name}{ordinal} = $ordinal;
- $specifications{$module}{unfixed}{$external_name}{arguments} = [@argument_types];
+ if(1 || !exists($specifications{$module}{unfixed}{$external_name})) {
+ $specifications{$module}{unfixed}{$external_name}{debug_channels} = [@debug_channels];
+ $specifications{$module}{unfixed}{$external_name}{internal_name} = $internal_name;
+ $specifications{$module}{unfixed}{$external_name}{external_name} = $external_name;
+ $specifications{$module}{unfixed}{$external_name}{ordinal} = $ordinal;
+ $specifications{$module}{unfixed}{$external_name}{return_type} = $return_type;
+ $specifications{$module}{unfixed}{$external_name}{argument_types} = [@argument_types];
+ } else {
+ output->write("$file: $external_name ($module.$ordinal) already exists\n");
+ }
+ } elsif($ordinal =~ /^\d+$/) {
+ if(1 || !exists($specifications{$module}{fixed}{$ordinal})) {
+ $specifications{$module}{fixed}{$ordinal}{debug_channels} = [@debug_channels];
+ $specifications{$module}{fixed}{$ordinal}{ordinal} = $ordinal;
+ $specifications{$module}{fixed}{$ordinal}{internal_name} = $internal_name;
+ $specifications{$module}{fixed}{$ordinal}{external_name} = $external_name;
+ $specifications{$module}{fixed}{$ordinal}{return_type} = $return_type;
+ $specifications{$module}{fixed}{$ordinal}{argument_types} = [@argument_types];
+ } else {
+ output->write("$file: $external_name ($module.$ordinal) already exists\n");
+ }
+ } elsif($ordinal eq "init") {
+ if(!exists($specifications{$module}{init})) {
+ $specifications{$module}{init}{debug_channels} = [@debug_channels];
+ $specifications{$module}{init}{external_name} = $external_name;
+ $specifications{$module}{init}{internal_name} = $internal_name;
+ $specifications{$module}{init}{return_type} = $return_type;
+ $specifications{$module}{init}{argument_types} = [@argument_types];
+ } else {
+ output->write("$file: $external_name ($module.$ordinal) already exists\n");
+ }
} else {
- $specifications{$module}{fixed}{$ordinal}{debug_channels} = [@debug_channels];
- $specifications{$module}{fixed}{$ordinal}{ordinal} = $ordinal;
- $specifications{$module}{fixed}{$ordinal}{internal_name} = $internal_name;
- $specifications{$module}{fixed}{$ordinal}{external_name} = $external_name;
- $specifications{$module}{fixed}{$ordinal}{arguments} = [@argument_types];
+ if(!exists($specifications{$module}{unknown}{$external_name})) {
+ $specifications{$module}{unknown}{$external_name}{debug_channels} = [@debug_channels];
+ $specifications{$module}{unknown}{$external_name}{internal_name} = $internal_name;
+ $specifications{$module}{unknown}{$external_name}{external_name} = $external_name;
+ $specifications{$module}{unknown}{$external_name}{ordinal} = $ordinal;
+ $specifications{$module}{unknown}{$external_name}{return_type} = $return_type;
+ $specifications{$module}{unknown}{$external_name}{argument_types} = [@argument_types];
+ } else {
+ output->write("$file: $external_name ($module.$ordinal) already exists\n");
+ }
}
if($options->debug) {
@@ -165,32 +196,52 @@
my $internal_name = $function->{internal_name};
my $external_name = $function->{external_name};
my $ordinal = $function->{ordinal};
- my @arguments = @{$function->{arguments}};
-
- my @arguments2;
- foreach my $argument (@arguments) {
- my $argument2;
- if($type eq "win16") {
- $argument2 = $win16api->translate_argument($argument);
- } else {
- $argument2 = $win32api->translate_argument($argument);
- }
- if(!defined($argument2)) {
- $argument2 = "undef";
- }
+ my $return_type = $function->{return_type};
+ my @argument_types = @{$function->{argument_types}};
- if($argument2 eq "longlong") {
- push @arguments2, ("long", "long");
- } else {
- push @arguments2, $argument2;
- }
- }
-
+ my $return_kind;
if($type eq "win16") {
- print OUT "$ordinal pascal $external_name(@arguments2) $internal_name\n";
+ $return_kind = $win16api->translate_argument($return_type);
} else {
- print OUT "$ordinal stdcall $external_name(@arguments2) $internal_name\n";
+ $return_kind = $win32api->translate_argument($return_type);
}
+ if(!defined($return_kind)) {
+ $return_kind = "undef";
+ }
+
+ my @argument_kinds;
+ foreach my $argument_kind (@argument_kinds) {
+ my $argument_kind;
+ if($type eq "win16") {
+ $argument_kind = $win16api->translate_argument($argument_kind);
+ } else {
+ $argument_kind = $win32api->translate_argument($argument_kind);
+ }
+ if(!defined($argument_kind)) {
+ $argument_kind = "undef";
+ }
+
+ if($argument_kind eq "longlong") {
+ push @argument_kinds, ("long", "long");
+ } else {
+ push @argument_kinds, $argument_kind;
+ }
+ }
+
+ my $calling_convention;
+ if($type eq "win16") {
+ if($return_kind =~ /^(?:void|s_word|word)$/) {
+ $calling_convention = "pascal16";
+ } elsif($return_kind =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) {
+ $calling_convention = "pascal";
+ } else {
+ $calling_convention = "undef";
+ }
+ } else {
+ $calling_convention = "stdcall";
+ }
+
+ print OUT "$ordinal $calling_convention $external_name(@argument_kinds) $internal_name\n";
}
if($options->spec_files) {
@@ -210,9 +261,19 @@
print OUT "name $module\n";
print OUT "type $type\n";
+ if(exists($specifications{$module}{init})) {
+ my $init = $specifications{$module}{init}{internal_name};
+ print OUT "init $init\n";
+ }
print OUT "\n";
my %debug_channels;
+ if(exists($specifications{$module}{init})) {
+ my $function = $specifications{$module}{init};
+ foreach my $debug_channel (@{$function->{debug_channels}}) {
+ $debug_channels{$debug_channel}++;
+ }
+ }
foreach my $ordinal (sort {$a <=> $b} keys(%{$specifications{$module}{fixed}})) {
my $function = $specifications{$module}{fixed}{$ordinal};
foreach my $debug_channel (@{$function->{debug_channels}}) {
@@ -225,6 +286,12 @@
$debug_channels{$debug_channel}++;
}
}
+ foreach my $name (sort(keys(%{$specifications{$module}{unknown}}))) {
+ my $function = $specifications{$module}{unknown}{$name};
+ foreach my $debug_channel (@{$function->{debug_channels}}) {
+ $debug_channels{$debug_channel}++;
+ }
+ }
my @debug_channels = sort(keys(%debug_channels));
if($#debug_channels >= 0) {
@@ -233,20 +300,38 @@
}
my $empty = 1;
- foreach my $ordinal (sort {$a <=> $b} keys(%{$specifications{$module}{fixed}})) {
+
+ if(!$empty) {
+ print OUT "\n";
+ $empty = 1;
+ }
+ foreach my $name (sort(keys(%{$specifications{$module}{unknown}}))) {
+ my $function = $specifications{$module}{unknown}{$name};
+ print OUT "# ";
+ output_function(\*OUT, $type, $function);
+ $empty = 0;
+ }
+
+ if(!$empty) {
+ print OUT "\n";
+ $empty = 1;
+ }
+ foreach my $ordinal (sort {$a <=> $b} keys(%{$specifications{$module}{fixed}})) {
my $function = $specifications{$module}{fixed}{$ordinal};
output_function(\*OUT, $type, $function);
$empty = 0;
}
+ if(!$empty) {
+ print OUT "\n";
+ $empty = 1;
+ }
foreach my $name (sort(keys(%{$specifications{$module}{unfixed}}))) {
- if(!$empty) {
- print OUT "\n";
- $empty = 1;
- }
my $function = $specifications{$module}{unfixed}{$name};
output_function(\*OUT, $type, $function);
+ $empty = 0;
}
+
close(OUT);
}
}
diff --git a/tools/winapi/winapi_fixup b/tools/winapi/winapi_fixup
index 3eb4c43..246b878 100755
--- a/tools/winapi/winapi_fixup
+++ b/tools/winapi/winapi_fixup
@@ -38,9 +38,10 @@
"local" => { default => 1, description => "local fixup" },
"documentation" => { default => 1, parent => "local", description => "documentation fixup" },
- "documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" },
- "documentation-missing" => { default => 0, parent => "documentation", description => "documentation missing fixup" },
+ "documentation-missing" => { default => 1, parent => "documentation", description => "documentation missing fixup" },
"documentation-name" => { default => 1, parent => "documentation", description => "documentation name fixup" },
+ "documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" },
+ "documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" },
"stub" => { default => 0, parent => "local", description => "stub fixup" },
"global" => { default => 1, description => "global fixup" },
@@ -71,82 +72,6 @@
winapi->read_spec_files($modules, $wine_dir, $current_dir, \@spec_files, $win16api, $win32api);
}
-sub get_all_module_internal_ordinal {
- my $internal_name = shift;
-
- my @entries = ();
- foreach my $winapi (@winapis) {
- my @name = (); {
- my $name = $winapi->function_external_name($internal_name);
- if(defined($name)) {
- @name = split(/ & /, $name);
- }
- }
- my @module = (); {
- my $module = $winapi->function_internal_module($internal_name);
- if(defined($module)) {
- @module = split(/ & /, $module);
- }
- }
- my @ordinal = (); {
- my $ordinal = $winapi->function_internal_ordinal($internal_name);
- if(defined($ordinal)) {
- @ordinal = split(/ & /, $ordinal);
- }
- }
-
- my $name;
- my $module;
- my $ordinal;
- while(defined($name = shift @name) &&
- defined($module = shift @module) &&
- defined($ordinal = shift @ordinal))
- {
- push @entries, [$name, $module, $ordinal];
- }
- }
-
- return @entries;
-}
-
-sub get_all_module_external_ordinal {
- my $external_name = shift;
-
- my @entries = ();
- foreach my $winapi (@winapis) {
- my @name = (); {
- my $name = $winapi->function_internal_name($external_name);
- if(defined($name)) {
- @name = split(/ & /, $name);
- }
- }
- my @module = (); {
- my $module = $winapi->function_external_module($external_name);
- if(defined($module)) {
- @module = split(/ & /, $module);
- }
- }
- my @ordinal = (); {
- my $ordinal = $winapi->function_external_ordinal($external_name);
- if(defined($ordinal)) {
- @ordinal = split(/ & /, $ordinal);
- }
- }
-
- my $name;
- my $module;
- my $ordinal;
- while(defined($name = shift @name) &&
- defined($module = shift @module) &&
- defined($ordinal = shift @ordinal))
- {
- push @entries, [$name, $module, $ordinal];
- }
- }
-
- return @entries;
-}
-
sub normalize_set {
local $_ = shift;
@@ -171,8 +96,9 @@
my $progress_max = scalar(@c_files);
foreach my $file (@c_files) {
- my %substitute_line;
my %insert_line;
+ my %substitute_line;
+ my %delete_line;
my %spec_file;
@@ -236,19 +162,109 @@
my $calling_convention16 = translate_calling_convention16($calling_convention);
my $calling_convention32 = translate_calling_convention32($calling_convention);
- my $documention_modified = 0;
+ my $spec_modified = 0;
- if(($documentation && !$documention_modified) &&
- (options->documentation_name || options->documentation_ordinal))
+ if(options->stub && $documentation) {
+ foreach my $winapi (@winapis) {
+ my @entries = ();
+ if($winapi->function_stub($internal_name)) {
+ my $module = $winapi->function_internal_module($internal_name);
+ my $ordinal = $winapi->function_internal_ordinal($internal_name);
+
+ my $external_name = $internal_name;
+ if($winapi->name eq "win16") {
+ $external_name =~ s/(?:_)?16([AW]?)$//;
+ if(defined($1)) {
+ $external_name .= $1;
+ }
+ }
+ push @entries, [$external_name, $module, $ordinal];
+ }
+
+ foreach (split(/\n/, $documentation)) {
+ if(/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+)\s*\.\s*([^\s\)\]]*)\s*[\)\]].*?$/) {
+ my $external_name = $1;
+ my $module = lc($2);
+ my $ordinal = $3;
+
+ if($external_name ne "@" &&
+ $winapi->is_module($module) &&
+ $winapi->function_stub($external_name) &&
+ $internal_name !~ /^\U$module\E_\Q$external_name\E$/)
+ {
+ push @entries, [$external_name, $module, $ordinal];
+ }
+ }
+ }
+
+ foreach my $entry (@entries) {
+ (my $external_name, my $module, my $ordinal) = @$entry;
+
+ my $abort = 0;
+ my $n;
+ my @argument_kinds = map {
+ my $type = $_;
+ my $kind;
+ if($type ne "..." && !defined($kind = $winapi->translate_argument($type))) {
+ output->write("no translation defined: " . $type . "\n");
+ }
+
+ # FIXME: Kludge
+ if(defined($kind) && $kind eq "longlong") {
+ $n += 2;
+ ("long", "long");
+ } elsif(defined($kind)) {
+ $n++;
+ $kind;
+ } elsif($type eq "...") {
+ if($winapi->name eq "win16") {
+ $calling_convention16 = "pascal"; # FIXME: Is this correct?
+ } else {
+ $calling_convention32 = "varargs";
+ }
+ ();
+ } else {
+ $abort = 1;
+ $n++;
+ "undef";
+ }
+ } @argument_types;
+
+ my $substitute = {};
+ $substitute->{search} = "^\\s*$ordinal\\s+stub\\s+$external_name\\s*(?:#.*?)?\$";
+
+ if($winapi->name eq "win16") {
+ $substitute->{replace} = "$ordinal $calling_convention16 $external_name(@argument_kinds) $internal_name";
+ } else {
+ $substitute->{replace} = "$ordinal $calling_convention32 $external_name(@argument_kinds) $internal_name";
+ }
+
+ if(!defined($spec_file{$module})) {
+ $spec_file{$module} = [];
+ }
+
+ if(!$abort) {
+ $spec_modified = 1;
+ push @{$spec_file{$module}}, $substitute;
+ }
+ }
+ }
+ }
+
+ my %found_external_names;
+ foreach my $external_name (@external_names) {
+ $found_external_names{$external_name} = {};
+ }
+
+ my $documentation_modified = 0;
+
+ if(!$spec_modified &&
+ ($documentation && !$documentation_modified) &&
+ (options->documentation_name || options->documentation_ordinal ||
+ options->documentation_missing))
{
local $_;
- my %found_external_names;
-
- foreach my $external_name (@external_names) {
- $found_external_names{$external_name} = 0;
- }
-
my $line3;
my $search;
my $replace;
@@ -257,7 +273,7 @@
my $line2 = $line - 1;
foreach (split(/\n/, $documentation)) {
$line2++;
- if(/^(\s*\*\s*(\w+|\@)\s*)((?:\s*[\(\[]\s*\w+(?:\s*\.\s*[^\s\)\]]*\s*)?[\)\]])+)(.*?)$/) {
+ if(/^(\s*\*\s*(\S+)\s*)((?:\s*[\(\[]\s*\w+(?:\s*\.\s*[^\s\)\]]*\s*)?[\)\]])+)(.*?)$/) {
my $part1 = $1;
my $external_name = $2;
my $part3 = $3;
@@ -273,7 +289,10 @@
my $found = 0;
foreach my $external_name2 (@external_names) {
if($external_name eq $external_name2) {
- $found_external_names{$external_name2} = 1;
+ foreach my $entry (@entries) {
+ (undef, my $module, undef) = @$entry;
+ $found_external_names{$external_name2}{$module} = 1;
+ }
$found = 1;
last;
}
@@ -285,7 +304,7 @@
my $part12 = $part1;
(my $part32, my $module, my $ordinal) = @$entry;
- foreach my $entry2 (get_all_module_internal_ordinal($internal_name)) {
+ foreach my $entry2 (winapi::get_all_module_internal_ordinal($internal_name)) {
(my $external_name2, my $module2, my $ordinal2) = @$entry2;
if(options->documentation_name && lc($module) eq $module2 &&
@@ -324,19 +343,20 @@
$replace = $replace2;
}
$count++;
- } elsif(/^(\s*\*\s*)(\w+|\@)\s*$/) {
+ } elsif(/^(\s*\*\s*)([^\s\(]+)(?:\(\))?\s*$/) {
my $part1 = $1;
my $external_name = $2;
- if($internal_name eq $external_name) {
- foreach my $entry (get_all_module_internal_ordinal($internal_name)) {
+
+ if($internal_name =~ /^(?:\S+_)?\Q$external_name\E(?:16)?$/) {
+ foreach my $entry (winapi::get_all_module_internal_ordinal($internal_name)) {
(my $external_name2, my $module, my $ordinal) = @$entry;
$line3 = $line2;
$search = "^\Q$_\E\$";
$replace = "$part1$external_name2 (\U$module\E.$ordinal)";
}
+ $count++;
}
- $count++;
}
}
@@ -344,22 +364,101 @@
if($count > 1 || $#external_names >= 1) {
output->write("multiple entries (fixup not supported)\n");
# output->write("s/$search/$replace/\n");
+ # output->write("@external_names\n");
} else {
+ $documentation_modified = 1;
$substitute_line{$line3}{search} = $search;
$substitute_line{$line3}{replace} = $replace;
+
}
}
-
- if(options->documentation_missing) {
- foreach my $external_name (keys(%found_external_names)) {
- if(!$found_external_names{$external_name}) {
- output->write("$external_name missing (fixup not supported)\n");
- }
- }
- }
}
- if(0 && !$documentation) {
+ if(!$spec_modified && !$documentation_modified &&
+ options->documentation_missing && $documentation)
+ {
+ my $part1;
+ my $part2;
+ my $part3;
+ my $part4;
+ my $line3 = 0;
+
+ my $line2 = $line - 1;
+ foreach (split(/\n/, $documentation)) {
+ $line2++;
+ if(/^(\s*\*\s*)(\S+\s*)([\(\[])\s*\w+\s*\.\s*[^\s\)\]]*\s*([\)\]]).*?$/) {
+ $part1 = $1;
+ $part2 = $2;
+ $part3 = $3;
+ $part4 = $4;
+
+ $part2 =~ s/\S/ /g;
+
+ $line3 = $line2 + 1;
+ }
+ }
+
+ foreach my $entry2 (winapi::get_all_module_internal_ordinal($internal_name)) {
+ (my $external_name2, my $module2, my $ordinal2) = @$entry2;
+
+ my $found = 0;
+ foreach my $external_name (keys(%found_external_names)) {
+ foreach my $module3 (keys(%{$found_external_names{$external_name}})) {
+ if($external_name eq $external_name2 && uc($module2) eq $module3) {
+ $found = 1;
+ }
+ }
+ }
+ # FIXME: Not 100% correct
+ if(!$found &&
+ !$win16api->function_stub($internal_name) &&
+ !$win32api->function_stub($internal_name))
+ {
+ if($line3 > 0) {
+ $part2 = $external_name2 . " " x (length($part2) - length($external_name2));
+ $insert_line{$line3} = "$part1$part2$part3\U$module2\E.$ordinal2$part4\n";
+ } else {
+ output->write("$external_name2 (\U$module2\E.$ordinal2) missing (fixup not supported)\n");
+ }
+ }
+ }
+ }
+
+ if(!$documentation_modified &&
+ options->documentation_wrong)
+ {
+ my $line2 = $line - 1;
+ foreach (split(/\n/, $documentation)) {
+ $line2++;
+ if(/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+)\s*\.\s*([^\s\)\]]*)\s*[\)\]].*?$/) {
+ my $external_name = $1;
+ my $module = $2;
+ my $ordinal = $3;
+
+ my $found = 0;
+ foreach my $entry2 (winapi::get_all_module_internal_ordinal($internal_name)) {
+ (my $external_name2, my $module2, my $ordinal2) = @$entry2;
+
+ if($external_name eq $external_name2 &&
+ lc($module) eq $module2 &&
+ $ordinal eq $ordinal2)
+ {
+ $found = 1;
+ }
+ }
+ if(!$found) {
+ if(1) {
+ $delete_line{$line2} = "^\Q$_\E\$";
+ } else {
+ output->write("$external_name (\U$module\E.$ordinal) wrong (fixup not supported)\n");
+ };
+ }
+ }
+ }
+ }
+
+ if(0) # !$spec_modified && !$documentation
+ {
# FIXME: Not correct
my $external_name;
@@ -380,64 +479,6 @@
}
}
- if(options->stub) {
- # FIXME: Not correct
- foreach my $winapi (@winapis) {
- if($winapi->function_stub($internal_name)) {
- my $module = $winapi->function_internal_module($internal_name);
- my $ordinal = $winapi->function_internal_ordinal($internal_name);
-
- my $external_name = $internal_name;
- if($winapi->name eq "win16") {
- $external_name =~ s/(?:_)?16([AW]?)$//;
- if(defined($1)) {
- $external_name .= $1;
- }
- }
-
- my $abort = 0;
- my $n;
- my @argument_kinds = map {
- my $type = $_;
- my $kind = "unknown";
- $winapi->type_used_in_module($type, $module);
- if(!defined($kind = $winapi->translate_argument($type))) {
- output->write("no translation defined: " . $type . "\n");
- }
-
- # FIXME: Kludge
- if(defined($kind) && $kind eq "longlong") {
- $n += 2;
- ("long", "long");
- } elsif(defined($kind)) {
- $n++;
- $kind;
- } else {
- $abort = 1;
- $n++;
- "undef";
- }
- } @argument_types;
-
- my $substitute = {};
- $substitute->{search} = "^\\s*$ordinal\\s+stub\\s+$external_name\\s*(?:#.*?)?\$";
-
- if($winapi->name eq "win16") {
- $substitute->{replace} = "$ordinal $calling_convention16 $external_name(@argument_kinds) $internal_name";
- } else {
- $substitute->{replace} = "$ordinal $calling_convention32 $external_name(@argument_kinds) $internal_name";
- }
-
- if(!defined($spec_file{$module})) {
- $spec_file{$module} = [];
- }
-
- if(!$abort) {
- push @{$spec_file{$module}}, $substitute;
- }
- }
- }
- }
$output->prefix("");
};
@@ -456,13 +497,24 @@
while(<IN>) {
chomp;
- my $line = $insert_line{$.};
+ my $line;
+
+ $line = $insert_line{$.};
if(defined($line)) {
if(options->modify) {
$_ = "$line$_";
$modified = 1;
} else {
- output->write("$file: $.: insert : '$line'\n");
+ my $line2 = $line; chomp($line2);
+ my @line2 = split(/\n/, $line2);
+ if($#line2 > 0) {
+ output->write("$file: $.: insert: \\\n");
+ foreach my $line2 (@line2) {
+ output->write("'$line2'\n");
+ }
+ } else {
+ output->write("$file: $.: insert: '$line2'\n");
+ }
}
}
@@ -501,13 +553,31 @@
}
}
}
+
+ $line = $delete_line{$.};
+ if(defined($line)) {
+ if(/$line/) {
+ if(options->modify) {
+ $modified = 1;
+ next;
+ } else {
+ output->write("$file: $.: delete: '$line'\n");
+ }
+ } else {
+ output->write("$file: $.: unmatched delete: '$line'\n");
+ }
+ }
+
print OUT "$_\n";
}
return $modified;
};
- my $n = 0; while(defined(each %substitute_line)) { $n++; }
+ my $n = 0;
+ while(defined(each %insert_line)) { $n++; }
+ while(defined(each %substitute_line)) { $n++; }
+ while(defined(each %delete_line)) { $n++; }
if($n > 0) {
edit_file($file, $editor);
}
diff --git a/tools/winapi_check/modules.dat b/tools/winapi_check/modules.dat
index 9dfce9f..d440e8f 100644
--- a/tools/winapi_check/modules.dat
+++ b/tools/winapi_check/modules.dat
@@ -98,6 +98,8 @@
% dlls/kernel/kernel.spec
dlls/kernel
+dlls/shell32
+dlls/win32s
files
loader/ne
loader
@@ -130,6 +132,7 @@
% dlls/kernel/system.spec
+memory
misc
% dlls/kernel/toolhelp.spec
@@ -138,7 +141,6 @@
loader/ne
loader
memory
-windows
% dlls/kernel/wprocs.spec
@@ -185,6 +187,7 @@
% dlls/ntdll/ntdll.spec
dlls/ntdll
+memory
misc
scheduler
@@ -262,6 +265,10 @@
dlls/psapi
+% dlls/quartz/quartz.spec
+
+dlls/quartz
+
% dlls/rasapi32/rasapi16.spec
% dlls/rasapi32/rasapi32.spec
@@ -291,10 +298,12 @@
% dlls/shell32/shell.spec
dlls/shell32
+misc
% dlls/shell32/shell32.spec
dlls/shell32
+memory
% dlls/shdocvw/shdocvw.spec
@@ -342,6 +351,7 @@
dlls/kernel
dlls/user
memory
+misc
windows
% dlls/user/user32.spec
@@ -350,6 +360,7 @@
dlls/user
dlls/user/dde
loader
+objects
windows
% dlls/version/ver.spec
@@ -366,14 +377,12 @@
% dlls/win32s/w32sys.spec
+dlls/kernel
dlls/win32s
% dlls/win32s/win32s16.spec
-dlls/kernel
dlls/win32s
-memory
-scheduler
% dlls/winaspi/winaspi.spec
diff --git a/tools/winapi_check/win16/gdi.api b/tools/winapi_check/win16/gdi.api
index 8a052f7..52f7d56 100644
--- a/tools/winapi_check/win16/gdi.api
+++ b/tools/winapi_check/win16/gdi.api
@@ -12,9 +12,9 @@
int
%ptr
-
BITMAP16 *
BITMAPINFO *
+BITMAPINFOHEADER *
DEVMODEA *
DOCINFO16 *
FARPROC16 *
diff --git a/tools/winapi_check/win32/oledlg.api b/tools/winapi_check/win32/oledlg.api
index 34f8bf1..894222e 100644
--- a/tools/winapi_check/win32/oledlg.api
+++ b/tools/winapi_check/win32/oledlg.api
@@ -24,6 +24,7 @@
LPOLEUIINSERTOBJECTA
LPOLEUIINSERTOBJECTW
LPOLEUILINKCONTAINERA
+LPOLEUILINKCONTAINERW
LPOLEUIOBJECTPROPSA
LPOLEUIOBJECTPROPSW
LPOLEUIPASTESPECIALA
@@ -38,3 +39,4 @@
%wstr
LPCWSTR
+LPWSTR
\ No newline at end of file
diff --git a/tools/winapi_check/win32/quartz.api b/tools/winapi_check/win32/quartz.api
new file mode 100644
index 0000000..b4d5096
--- /dev/null
+++ b/tools/winapi_check/win32/quartz.api
@@ -0,0 +1,10 @@
+%long
+
+DWORD
+HRESULT
+
+%ptr
+
+CLSID *
+IID *
+void **
diff --git a/tools/winapi_check/win32/winmm.api b/tools/winapi_check/win32/winmm.api
index 57bfc18..eab7f98 100644
--- a/tools/winapi_check/win32/winmm.api
+++ b/tools/winapi_check/win32/winmm.api
@@ -79,7 +79,7 @@
WORD *
YIELDPROC
-%ptr --forbidden
+%ptr # --forbidden
LPMMIOPROC16
diff --git a/tools/winapi_check/win32/wsock32.api b/tools/winapi_check/win32/wsock32.api
index bb43794..2b83839 100644
--- a/tools/winapi_check/win32/wsock32.api
+++ b/tools/winapi_check/win32/wsock32.api
@@ -3,10 +3,7 @@
DWORD
INT
SOCKET
-
-%long # --forbidden
-
-long
+UINT
%ptr
diff --git a/tools/winapi_check/winapi.pm b/tools/winapi_check/winapi.pm
index f94fdda..a4b769d 100644
--- a/tools/winapi_check/winapi.pm
+++ b/tools/winapi_check/winapi.pm
@@ -2,6 +2,8 @@
use strict;
+my @winapis;
+
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
@@ -28,6 +30,8 @@
$self->parse_api_file($file,$module);
}
+ push @winapis, $self;
+
return $self;
}
@@ -285,7 +289,6 @@
$ordinal = $1;
- # FIXME: Internal name existing more than once not handled properly
if(!$$function_internal_name{$external_name}) {
$$function_internal_name{$external_name} = $internal_name;
} else {
@@ -358,7 +361,7 @@
$ordinal = $1;
my $internal_name;
- if($type eq "win16") {
+ if(0 && $type eq "win16") {
if($external_name =~ /\d$/) {
$internal_name = $external_name . "_16";
} else {
@@ -368,8 +371,17 @@
$internal_name = $external_name;
}
- # FIXME: Internal name existing more than once not handled properly
- $$function_stub{$internal_name} = 1;
+ $$function_stub{$external_name} = 1;
+ if(!$$function_internal_name{$external_name}) {
+ $$function_internal_name{$external_name} = $internal_name;
+ } else {
+ $$function_internal_name{$external_name} .= " & $internal_name";
+ }
+ if(!$$function_external_name{$internal_name}) {
+ $$function_external_name{$internal_name} = $external_name;
+ } else {
+ $$function_external_name{$internal_name} .= " & $external_name";
+ }
if(!$$function_internal_ordinal{$internal_name}) {
$$function_internal_ordinal{$internal_name} = $ordinal;
} else {
@@ -802,4 +814,84 @@
return $$function_found{$name};
}
+########################################################################
+# class methods
+#
+
+sub get_all_module_internal_ordinal {
+ my $internal_name = shift;
+
+ my @entries = ();
+ foreach my $winapi (@winapis) {
+ my @name = (); {
+ my $name = $winapi->function_external_name($internal_name);
+ if(defined($name)) {
+ @name = split(/ & /, $name);
+ }
+ }
+ my @module = (); {
+ my $module = $winapi->function_internal_module($internal_name);
+ if(defined($module)) {
+ @module = split(/ & /, $module);
+ }
+ }
+ my @ordinal = (); {
+ my $ordinal = $winapi->function_internal_ordinal($internal_name);
+ if(defined($ordinal)) {
+ @ordinal = split(/ & /, $ordinal);
+ }
+ }
+
+ my $name;
+ my $module;
+ my $ordinal;
+ while(defined($name = shift @name) &&
+ defined($module = shift @module) &&
+ defined($ordinal = shift @ordinal))
+ {
+ push @entries, [$name, $module, $ordinal];
+ }
+ }
+
+ return @entries;
+}
+
+sub get_all_module_external_ordinal {
+ my $external_name = shift;
+
+ my @entries = ();
+ foreach my $winapi (@winapis) {
+ my @name = (); {
+ my $name = $winapi->function_internal_name($external_name);
+ if(defined($name)) {
+ @name = split(/ & /, $name);
+ }
+ }
+ my @module = (); {
+ my $module = $winapi->function_external_module($external_name);
+ if(defined($module)) {
+ @module = split(/ & /, $module);
+ }
+ }
+ my @ordinal = (); {
+ my $ordinal = $winapi->function_external_ordinal($external_name);
+ if(defined($ordinal)) {
+ @ordinal = split(/ & /, $ordinal);
+ }
+ }
+
+ my $name;
+ my $module;
+ my $ordinal;
+ while(defined($name = shift @name) &&
+ defined($module = shift @module) &&
+ defined($ordinal = shift @ordinal))
+ {
+ push @entries, [$name, $module, $ordinal];
+ }
+ }
+
+ return @entries;
+}
+
1;
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index 1222819..c67233c 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -352,6 +352,8 @@
my @argument_documentations = @$refargument_documentations;
my $statements = shift;
+ my $documentation_line = $line;
+
my $external_name16 = $win16api->function_external_name($internal_name);
my $external_name32 = $win32api->function_external_name($internal_name);
@@ -372,10 +374,14 @@
my $module32 = $win32api->function_internal_module($internal_name);
if(defined($module16)) {
- $modules->found_module_in_dir($module16, $file_dir);
+ foreach my $module (split(/ & /, $module16)) {
+ $modules->found_module_in_dir($module, $file_dir);
+ }
}
if(defined($module32)) {
- $modules->found_module_in_dir($module32, $file_dir);
+ foreach my $module (split(/ & /, $module32)) {
+ $modules->found_module_in_dir($module, $file_dir);
+ }
}
my $previous_function;
@@ -387,6 +393,7 @@
$functions{$internal_name} = $function;
$function->documentation($documentation);
+ $function->documentation_line($documentation_line);
$function->linkage($linkage);
$function->file($file);
$function->return_type($return_type);
@@ -428,33 +435,46 @@
}
if($options->local && $options->misplaced &&
- $linkage ne "extern" && $statements)
+ $linkage ne "extern" && defined($statements))
{
if($options->win16 && $options->report_module($module16)) {
- my $match = 0;
foreach my $module (split(/ & /, $module16)) {
+ my $match = 0;
foreach my $file_module (split(/ & /, $file_module16)) {
if($module eq $file_module) {
- $match++;
+ $match = 1;
}
}
- }
- if(!$match && $file ne "library/port.c" && !$nativeapi->is_function($internal_name)) {
- $output->write("is misplaced\n");
+ if(!$match) {
+ if($file ne "library/port.c" &&
+ !$nativeapi->is_function($internal_name) &&
+ !$win16api->function_stub($internal_name))
+ {
+ $output->write("is misplaced ($module)\n");
+ }
+ last;
+ }
+
}
}
if($options->win32 && $options->report_module($module32)) {
- my $match = 0;
foreach my $module (split(/ & /, $module32)) {
+ my $match = 0;
foreach my $file_module (split(/ & /, $file_module32)) {
if($module eq $file_module) {
- $match++;
+ $match = 1;
}
}
- }
- if(!$match && $file ne "library/port.c" && !$nativeapi->is_function($internal_name)) {
- $output->write("is misplaced\n");
+ if(!$match) {
+ if($file ne "library/port.c" &&
+ !$nativeapi->is_function($internal_name) &&
+ !$win32api->function_stub($internal_name))
+ {
+ $output->write("is misplaced ($module)\n");
+ }
+ last;
+ }
}
}
}
@@ -527,7 +547,7 @@
if($options->local && $options->documentation &&
!defined($previous_function) &&
(defined($module16) || defined($module32)) &&
- $linkage ne "extern" && $statements)
+ $linkage ne "extern" && defined($statements))
{
winapi_documentation::check_documentation $options, $output, $win16api, $win32api, $function;
}
diff --git a/tools/winapi_check/winapi_documentation.pm b/tools/winapi_check/winapi_documentation.pm
index eadcaa9..682c4a6 100644
--- a/tools/winapi_check/winapi_documentation.pm
+++ b/tools/winapi_check/winapi_documentation.pm
@@ -7,6 +7,8 @@
my %comment_spacing;
sub check_documentation {
+ local $_;
+
my $options = shift;
my $output = shift;
my $win16api = shift;
@@ -19,126 +21,92 @@
my $external_name32 = $function->external_name32;
my $internal_name = $function->internal_name;
my $documentation = $function->documentation;
+ my $documentation_line = $function->documentation_line;
my @argument_documentations = @{$function->argument_documentations};
- # FIXME: Not correct
- if(defined($external_name16)) {
- $external_name16 = (split(/\s*&\s*/, $external_name16))[0];
- }
-
- # FIXME: Not correct
- if(defined($external_name32)) {
- $external_name32 = (split(/\s*&\s*/, $external_name32))[0];
- }
-
- my $external_name;
- my $name1;
- my $name2;
-
- if(defined($module16) && !defined($module32)) {
- my @uc_modules16 = split(/\s*\&\s*/, uc($module16));
- push @uc_modules16, "WIN16";
-
- $name1 = $internal_name;
- foreach my $uc_module16 (@uc_modules16) {
- if($name1 =~ s/^$uc_module16\_//) { last; }
- }
-
- $name2 = $name1;
- $name2 =~ s/(?:_)?16$//;
- $name2 =~ s/16_fn/16_/;
-
- $external_name = $external_name16;
- } elsif(!defined($module16) && defined($module32)) {
- my @uc_modules32 = split(/\s*\&\s*/, uc($module32));
- push @uc_modules32, "wine";
-
- foreach my $uc_module32 (@uc_modules32) {
- if($uc_module32 =~ /^WS2_32$/) {
- push @uc_modules32, "WSOCK32";
- }
- }
-
- $name1 = $internal_name;
- foreach my $uc_module32 (@uc_modules32) {
- if($name1 =~ s/^$uc_module32\_//) { last; }
- }
-
- $name2 = $name1;
- $name2 =~ s/AW$//;
-
- $external_name = $external_name32;
- } else {
- my @uc_modules = split(/\s*\&\s*/, uc($module16));
- push @uc_modules, split(/\s*\&\s*/, uc($module32));
-
- $name1 = $internal_name;
- foreach my $uc_module (@uc_modules) {
- if($name1 =~ s/^$uc_module\_//) { last; }
- }
-
- $name2 = $name1;
- $external_name = $external_name32;
- }
-
- if(!defined($external_name)) {
- $external_name = $internal_name;
- }
-
- if($options->documentation_name) {
- my $n = 0;
- if((++$n && defined($module16) && defined($external_name16) &&
- $external_name16 ne "@" && $documentation !~ /\b\Q$external_name16\E\b/) ||
- (++$n && defined($module16) && defined($external_name16) &&
- $external_name16 eq "@" && $documentation !~ /\@/) ||
- (++$n && defined($module32) && defined($external_name32) &&
- $external_name32 ne "@" && $documentation !~ /\b\Q$external_name32\E\b/) ||
- (++$n && defined($module32) && defined($external_name32) &&
- $external_name32 eq "@" && $documentation !~ /\@/))
+ if($options->documentation_name ||
+ $options->documentation_ordinal ||
+ $options->documentation_pedantic)
+ {
+ my @winapis = ($win16api, $win32api);
+ my @modules = ($module16, $module32);
+ my @external_names = ($external_name16, $external_name32);
+ while(
+ defined(my $winapi = shift @winapis) &&
+ defined(my $external_name = shift @external_names) &&
+ defined(my $module = shift @modules))
{
- my $external_name = ($external_name16, $external_name32)[($n-1)/2];
- if($options->documentation_pedantic || $documentation !~ /\b(?:$internal_name|$name1|$name2)\b/) {
- $output->write("documentation: wrong or missing name ($external_name) \\\n$documentation\n");
+ if($winapi->function_stub($internal_name)) { next; }
+
+ my @external_name = split(/\s*\&\s*/, $external_name);
+ my @modules = split(/\s*\&\s*/, $module);
+ my @ordinals = split(/\s*\&\s*/, $winapi->function_internal_ordinal($internal_name));
+
+ my $pedantic_failed = 0;
+ while(defined(my $external_name = shift @external_name) &&
+ defined(my $module = shift @modules) &&
+ defined(my $ordinal = shift @ordinals))
+ {
+ my $found_name = 0;
+ my $found_ordinal = 0;
+ foreach (split(/\n/, $documentation)) {
+ if(/^(\s*)\*(\s*)(\@|\S+)(\s*)([\(\[])(\w+)\.(\@|\d+)([\)\]])/) {
+ my $external_name2 = $3;
+ my $module2 = $6;
+ my $ordinal2 = $7;
+
+ if(length($1) != 1 || length($2) < 1 ||
+ length($4) < 1 || $5 ne "(" || $8 ne ")")
+ {
+ $pedantic_failed = 1;
+ }
+
+ if($external_name eq $external_name2) {
+ $found_name = 1;
+ if("\U$module\E" eq $module2 &&
+ $ordinal eq $ordinal2)
+ {
+ $found_ordinal = 1;
+ }
+ }
+ }
+ }
+ if(($options->documentation_name && !$found_name) ||
+ ($options->documentation_ordinal && !$found_ordinal))
+ {
+ $output->write("documentation: expected $external_name (\U$module\E.$ordinal): \\\n$documentation\n");
+ }
+
+ }
+ if($options->documentation_pedantic && $pedantic_failed) {
+ $output->write("documentation: pedantic failed: \\\n$documentation\n");
}
}
}
- if($options->documentation_ordinal) {
- if(defined($module16)) {
- my @modules16 = split(/\s*\&\s*/, $module16);
- my @ordinals16 = split(/\s*\&\s*/, $win16api->function_internal_ordinal($internal_name));
+ if($options->documentation_wrong) {
+ foreach (split(/\n/, $documentation)) {
+ if(/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+)\s*\.\s*([^\s\)\]]*)\s*[\)\]].*?$/) {
+ my $external_name = $1;
+ my $module = $2;
+ my $ordinal = $3;
- my $module16;
- my $ordinal16;
- while(defined($module16 = shift @modules16) && defined($ordinal16 = shift @ordinals16)) {
- if($documentation !~ /\b\U$module16\E\.\Q$ordinal16\E/) {
- $output->write("documentation: wrong or missing ordinal " .
- "expected (\U$module16\E.$ordinal16) \\\n$documentation\n");
+ my $found = 0;
+ foreach my $entry2 (winapi::get_all_module_internal_ordinal($internal_name)) {
+ (my $external_name2, my $module2, my $ordinal2) = @$entry2;
+
+ if($external_name eq $external_name2 &&
+ lc($module) eq $module2 &&
+ $ordinal eq $ordinal2)
+ {
+ $found = 1;
+ }
+ }
+ if(!$found) {
+ $output->write("documentation: $external_name (\U$module\E.$ordinal) wrong\n");
}
}
}
-
- if(defined($module32)) {
- my @modules32 = split(/\s*\&\s*/, $module32);
- my @ordinals32 = split(/\s*\&\s*/, $win32api->function_internal_ordinal($internal_name));
-
- my $module32;
- my $ordinal32;
- while(defined($module32 = shift @modules32) && defined($ordinal32 = shift @ordinals32)) {
- if($documentation !~ /\b\U$module32\E\.\Q$ordinal32\E/) {
- $output->write("documentation: wrong or missing ordinal " .
- "expected (\U$module32\E.$ordinal32) \\\n$documentation\n");
- }
- }
- }
- }
-
- # FIXME: Not correct
- if($options->documentation_pedantic) {
- my $ordinal = (split(/\s*\&\s*/, $win16api->function_internal_ordinal($internal_name)))[0];
- if(defined($ordinal) && $documentation !~ /^ \*\s+(?:\@|\w+)(?:\s+[\(\[]\w+\.(?:\@|\d+)[\)\]])+/m) {
- $output->write("documentation: pedantic check failed \\\n$documentation\n");
- }
}
if($options->documentation_comment_indent) {
diff --git a/tools/winapi_check/winapi_function.pm b/tools/winapi_check/winapi_function.pm
index e6b1879..85f1761 100644
--- a/tools/winapi_check/winapi_function.pm
+++ b/tools/winapi_check/winapi_function.pm
@@ -33,6 +33,17 @@
return $$documentation;
}
+sub documentation_line {
+ my $self = shift;
+ my $documentation_line = \${$self->{DOCUMENTATION_LINE}};
+
+ local $_ = shift;
+
+ if(defined($_)) { $$documentation_line = $_; }
+
+ return $$documentation_line;
+}
+
sub linkage {
my $self = shift;
my $linkage = \${$self->{LINKAGE}};
diff --git a/tools/winapi_check/winapi_local.pm b/tools/winapi_check/winapi_local.pm
index ff58b23..c4f7972 100644
--- a/tools/winapi_check/winapi_local.pm
+++ b/tools/winapi_check/winapi_local.pm
@@ -122,7 +122,7 @@
$output->write("function not implemented as vararg\n");
}
} elsif($#argument_types != -1 && $argument_types[$#argument_types] eq "...") {
- if($#argument_types == 0) {
+ if($#argument_types == 0 || $winapi->name eq "win16") {
pop @argument_types;
} else {
$output->write("function not declared as vararg\n");
diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm
index 25030f2..60df0d5 100644
--- a/tools/winapi_check/winapi_options.pm
+++ b/tools/winapi_check/winapi_options.pm
@@ -102,10 +102,15 @@
description => "check for documentation name inconsistances\n"
},
"documentation-ordinal" => {
- default => 0,
+ default => 1,
parent => "documentation",
description => "check for documentation ordinal inconsistances\n"
},
+ "documentation-wrong" => {
+ default => 1,
+ parent => "documentation",
+ description => "check for wrong documentation\n"
+ },
"prototype" => {default => 0, parent => ["local", "headers"], description => "prototype checking" },
"global" => { default => 1, description => "global checking" },