- A few more bug fixes
- Reorganization continues
- New tool (make_filter) for filtering make output added
diff --git a/tools/winapi/config.pm b/tools/winapi/config.pm
index 852ef8b..3d950e6 100644
--- a/tools/winapi/config.pm
+++ b/tools/winapi/config.pm
@@ -10,9 +10,10 @@
@ISA = qw(Exporter);
@EXPORT = qw(
&file_absolutize &file_normalize
+ &file_directory
&file_type &files_filter
- &file_skip &files_skip
- &get_c_files &get_h_files &get_spec_files
+ &file_skip &files_skip
+ &get_api_files &get_c_files &get_h_files &get_spec_files
);
@EXPORT_OK = qw(
$current_dir $wine_dir $winapi_dir $winapi_check_dir
@@ -22,6 +23,8 @@
use output qw($output);
+use File::Find;
+
sub file_type {
local $_ = shift;
@@ -30,7 +33,7 @@
m%^(?:libtest|rc|server|tests|tools)/% && return "";
m%^(?:programs|debugger|miscemu)/% && return "wineapp";
m%^(?:library|tsx11|unicode)/% && return "library";
- m%^windows/x11drv/wineclipsrv.c% && return "application";
+ m%^windows/x11drv/wineclipsrv\.c$% && return "application";
return "winelib";
}
@@ -56,8 +59,9 @@
m%^(?:libtest|programs|rc|server|tests|tools)/% && return 1;
m%^(?:debugger|miscemu|tsx11|server|unicode)/% && return 1;
m%^dlls/wineps/data/% && return 1;
- m%^windows/x11drv/wineclipsrv.c% && return 1;
- m%^dlls/winmm/wineoss/midipatch.c% && return 1;
+ m%^windows/x11drv/wineclipsrv\.c$% && return 1;
+ m%^dlls/winmm/wineoss/midipatch\.c$% && return 1;
+ m%(?:glue|spec)\.c$% && return 1;
return 0;
}
@@ -98,25 +102,57 @@
return $_;
}
+sub file_directory {
+ my $file = shift;
+ $file =~ s%^./%%;
+
+ my $dir = $file;
+ $dir =~ s%/?[^/]*$%%;
+ if(!$dir) {
+ $dir = ".";
+ }
+
+ return $dir;
+}
+
sub _get_files {
my $extension = shift;
my $type = shift;
+ my $dir = shift;
$output->progress("$wine_dir: searching for *.$extension");
- my @files = map {
- s%^\./%%;
- s%^$wine_dir/%%;
- if(file_type($_) eq $type) {
- $_;
- } else {
- ();
+ if(!defined($dir)) {
+ $dir = $wine_dir;
+ }
+
+ my @files;
+
+ my @dirs = ($dir);
+ while(defined(my $dir = shift @dirs)) {
+ opendir(DIR, $dir);
+ my @entries= readdir(DIR);
+ closedir(DIR);
+ foreach (@entries) {
+ $_ = "$dir/$_";
+ if(/\.\.?$/) {
+ # Nothing
+ } elsif(-d $_) {
+ push @dirs, $_;
+ } elsif(/\.$extension$/ && (!defined($type) || file_type($_) eq $type)) {
+ s%^$wine_dir/%%;
+ push @files, $_;
+ }
}
- } split(/\n/, `find $wine_dir -name \\*.$extension`);
+ }
return @files;
}
+sub get_api_files {
+ my $name = shift;
+ return _get_files("api", undef, "$winapi_check_dir/$name");
+}
sub get_c_files { return _get_files("c", @_); }
sub get_h_files { return _get_files("h", @_); }
sub get_spec_files { return _get_files("spec", @_); }
diff --git a/tools/winapi/make_filter b/tools/winapi/make_filter
new file mode 100755
index 0000000..03c6aac
--- /dev/null
+++ b/tools/winapi/make_filter
@@ -0,0 +1,70 @@
+#! /usr/bin/perl -w
+
+use strict;
+
+BEGIN {
+ $0 =~ m%^(.*?/?tools)/winapi/make_filter$%;
+ require "$1/winapi/setup.pm";
+}
+
+use config qw($current_dir $wine_dir);
+use output qw($output);
+use make_filter_options qw($options);
+
+use make_parser;
+
+if($options->progress) {
+ $output->enable_progress;
+} else {
+ $output->disable_progress;
+}
+
+########################################################################
+# main
+########################################################################
+
+my $command = join(" ", $options->arguments);
+open(IN, "($command) 2>&1 |");
+
+while(<IN>) {
+ chomp;
+
+ if(!&make_parser::line($_)) {
+ next;
+ }
+
+ my $directory = &make_parser::directory();
+ my $file = &make_parser::file_name();
+ my $line = &make_parser::file_line();
+ my $message = &make_parser::message();
+
+ if(&make_parser::tool() eq "make") {
+ if($directory && $directory ne ".") {
+ $output->progress("$directory: make");
+ }
+ } elsif($message) {
+ if($file && $line) {
+ if($directory) {
+ $output->write("$directory/$file:$line: $message\n");
+ } else {
+ $output->write("$file:$line: $message\n");
+ }
+ } elsif($file) {
+ if($directory) {
+ $output->write("$directory/$file: $message\n");
+ } else {
+ $output->write("$file: $message\n");
+ }
+ } else {
+ if($directory) {
+ $output->write("$directory: " . &make_parser::tool() . ": $message\n");
+ } else {
+ $output->write(".: " . &make_parser::tool() . ": $message\n");
+ }
+ }
+ }
+}
+
+close(IN);
+
+$output->hide_progress();
diff --git a/tools/winapi/make_filter_options.pm b/tools/winapi/make_filter_options.pm
new file mode 100644
index 0000000..ceecd77
--- /dev/null
+++ b/tools/winapi/make_filter_options.pm
@@ -0,0 +1,35 @@
+package make_filter_options;
+use base qw(options);
+
+use strict;
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw($options);
+
+use options qw($options &parse_comma_list);
+
+my %options_long = (
+ "debug" => { default => 0, description => "debug mode" },
+ "help" => { default => 0, description => "help mode" },
+ "verbose" => { default => 0, description => "verbose mode" },
+
+ "progress" => { default => 1, description => "show progress" },
+
+ "pedantic" => { default => 0, description => "be pedantic" },
+);
+
+my %options_short = (
+ "d" => "debug",
+ "?" => "help",
+ "v" => "verbose"
+);
+
+my $options_usage = "usage: make_filter [--help]\n";
+
+$options = '_options'->new(\%options_long, \%options_short, $options_usage);
+
+1;
diff --git a/tools/winapi/make_parser.pm b/tools/winapi/make_parser.pm
new file mode 100644
index 0000000..63037d9
--- /dev/null
+++ b/tools/winapi/make_parser.pm
@@ -0,0 +1,664 @@
+package make_parser;
+
+use strict;
+
+use output qw($output);
+
+########################################################################
+# global
+########################################################################
+
+my $current;
+my $tool;
+my $directory;
+my $file;
+my $line;
+my $function;
+my $message;
+
+sub directory { return $directory; }
+sub tool { return $tool; }
+sub file_name { return $file; }
+sub file_line { return $line; }
+sub message { return $message; }
+
+########################################################################
+# error
+########################################################################
+
+sub error {
+ $output->write("make_filter: $tool: can't parse output: '$current'\n");
+ exit 1;
+}
+
+########################################################################
+# line
+########################################################################
+
+sub line {
+ local $_ = shift;
+
+ $file = "";
+ $line = "";
+ $message = "";
+
+ $current = $_;
+
+ my ($new_tool, $read_files, $write_files, $remove_files) = command($_);
+ if(defined($new_tool)) {
+ $tool = $new_tool;
+
+ $function = "";
+
+ my $progress = "$directory: $tool: ";
+ if($#$read_files >= 0) {
+ $progress .= "read[" . join(" ", @{$read_files}) . "]";
+ }
+ if($#$write_files >= 0) {
+ if($#$read_files >= 0) {
+ $progress .= ", ";
+ }
+ $progress .= "write[" . join(" ", @{$write_files}) . "]";
+ }
+ if($#$remove_files >= 0) {
+ if($#$read_files >= 0 || $#$write_files >= 0) {
+ $progress .= ", ";
+ }
+ $progress .= "remove[" . join(" ", @{$remove_files}) . "]";
+ }
+
+ if($tool =~ /^cd|make$/) {
+ # Nothing
+ } elsif($tool =~ /^ld$/) {
+ $progress =~ s/read\[.*?\]/read[*.o]/; # FIXME: Kludge
+ $output->progress($progress)
+ } else {
+ $output->progress($progress)
+ }
+
+ return 0;
+ }
+
+ if(/^Wine build complete\.$/) {
+ # Nothing
+ } elsif(s/^make\[(\d+)\]:\s*//) {
+ $tool = "make";
+ make_output($1, $_);
+ } elsif($tool eq "bison" && /^conflicts:\s+\d+\s+shift\/reduce$/) {
+ # Nothing
+ } elsif($tool eq "gcc" && /^In file included from (.+?):(\d+):$/) {
+ # Nothing
+ } elsif($tool =~ /^gcc|ld$/ && s/^(.+?\.o(?:\(.*?\))?):\s*//) {
+ ld_output($1, $_)
+ } elsif($tool eq "gcc" && s/^(.+?\.[chly]):\s*//) {
+ gcc_output($1, $_);
+ } elsif($tool eq "winebuild" && s/^(.+?\.spec):\s*//) {
+ winebuild_output($1, $_);
+ } elsif($tool eq "wmc" && s/^(.+?\.mc):\s*//) {
+ wmc_output($1, $_);
+ } elsif($tool eq "wrc" && s/^(.+?\.rc):\s*//) {
+ wrc_output($1, $_);
+ } elsif($tool eq "cd" && s/^\/bin\/sh:\s*cd:\s*//) {
+ parse_cd_output($_);
+ } else {
+ error($_)
+ }
+
+ $file =~ s/^\.\///;
+
+ return 1;
+}
+
+########################################################################
+# make_output
+########################################################################
+
+sub make_output {
+ my $level = shift;
+ local $_ = shift;
+
+ $file = "";
+ $message = "";
+
+ if(0) {
+ # Nothing
+ } elsif(/^\*\*\* \[(.*?)\] Error (\d+)$/) {
+ # Nothing
+ } elsif(/^\*\*\* Warning:\s+/) { #
+ if(/^File \`(.+?)\' has modification time in the future \((.+?) > \(.+?\)\)$/) {
+ # Nothing
+ } else {
+ error();
+ }
+ } elsif(/^\`(.*?)\' is up to date.$/) {
+ # Nothing
+ } elsif(/^\[(.*?)\] Error (\d+) \(ignored\)$/) {
+ # Nothing
+ } elsif(/^(Entering|Leaving) directory \`(.*?)\'$/) {
+ if($1 eq "Entering") {
+ $directory = $2;
+ } else {
+ $directory = "";
+ }
+
+ my @components;
+ foreach my $component (split(/\//, $directory)) {
+ if($component eq "wine") {
+ @components = ();
+ } else {
+ push @components, $component;
+ }
+ }
+ $directory = join("/", @components);
+ } elsif(/^Nothing to be done for \`(.*?)\'.$/) {
+ # Nothing
+ } elsif(s/^warning:\s+//) {
+ if(/^Clock skew detected. Your build may be incomplete.$/) {
+ # Nothing
+ } else {
+ error();
+ }
+ } else {
+ error();
+ }
+
+}
+
+########################################################################
+# command
+########################################################################
+
+sub command {
+ local $_ = shift;
+
+ my $tool;
+ my $file;
+ my $read_files = ["<???>"];
+ my $write_files = ["<???>"];
+ my $remove_files = [];
+
+ s/^\s*(.*?)\s*$/$1/;
+
+ if(s/^\[\s+-d\s+(.*?)\s+\]\s+\|\|\s+//) {
+ # Nothing
+ }
+
+ if(s/^ar\s*//) {
+ $tool = "ar";
+ ($read_files, $write_files) = ar_command($_);
+ } elsif(s/^as\s*//) {
+ $tool = "as";
+ ($read_files, $write_files) = as_command($_);
+ } elsif(s/^bison\s*//) {
+ $tool = "bison";
+ ($read_files, $write_files) = bison_command($_);
+ } elsif(s/^cd\s*//) {
+ $tool = "cd";
+ ($read_files, $write_files) = cd_command($_);
+ } elsif(s/^flex\s*//) {
+ $tool = "flex";
+ ($read_files, $write_files) = flex_command($_);
+ } elsif(s/^for\s*//) {
+ $tool = "for";
+ ($read_files, $write_files) = for_command($_);
+ } elsif(s/^\/usr\/bin\/install\s*//) {
+ $tool = "install";
+ ($read_files, $write_files) = install_command($_);
+ } elsif(s/^ld\s*//) {
+ $tool = "ld";
+ ($read_files, $write_files) = ld_command($_);
+ } elsif(s/^\/sbin\/ldconfig\s*//) {
+ $tool = "ldconfig";
+ ($read_files, $write_files) = ldconfig_command();
+ } elsif(s/^gcc\s*//) {
+ $tool = "gcc";
+ ($read_files, $write_files) = gcc_command($_);
+ } elsif(s/^(?:(?:\.\.\/)+|\.\/)tools\/makedep\s*//) {
+ $tool = "makedep";
+ ($read_files, $write_files) = makedep_command($_);
+ } elsif(s/^mkdir\s*//) {
+ $tool = "mkdir";
+ ($read_files, $write_files) = mkdir_command($_);
+ } elsif(s/^ranlib\s*//) {
+ $tool = "ranlib";
+ ($read_files, $write_files) = ranlib_command($_);
+ } elsif(s/^rm\s*//) {
+ $tool = "rm";
+ ($read_files, $write_files, $remove_files) = rm_command($_);
+ } elsif(s/^sed\s*//) {
+ $tool = "sed";
+ ($read_files, $write_files) = sed_command($_);
+ } elsif(s/^strip\s*//) {
+ $tool = "sed";
+ ($read_files, $write_files) = strip_command($_);
+ } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/winebuild\/winebuild\s*//) {
+ $tool = "winebuild";
+ ($read_files, $write_files) = winebuild_command($_);
+ } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/wmc\/wmc\s*//) {
+ $tool = "wmc";
+ ($read_files, $write_files) = wmc_command($_);
+ } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/wrc\/wrc\s*//) {
+ $tool = "wrc";
+ ($read_files, $write_files) = wrc_command($_);
+ }
+
+ return ($tool, $read_files, $write_files, $remove_files);
+}
+
+########################################################################
+# ar_command
+########################################################################
+
+sub ar_command {
+ local $_ = shift;
+
+ my $read_files;
+ my $write_files;
+
+ if(/rc\s+(\S+)(\s+\S+)+$/) {
+ $write_files = [$1];
+ $read_files = $2;
+ $read_files =~ s/^\s*//;
+ $read_files = [split(/\s+/, $read_files)];
+ } else {
+ error();
+ }
+
+ return ($read_files, $write_files);
+}
+
+########################################################################
+# as_command
+########################################################################
+
+sub as_command {
+ local $_ = shift;
+
+ my $read_files;
+ my $write_files;
+
+ if(/-o\s+(\S+)\s+(\S+)$/) {
+ $write_files = [$1];
+ $read_files = [$2];
+ } else {
+ error();
+ }
+
+ return ($read_files, $write_files);
+}
+
+########################################################################
+# bision_command
+########################################################################
+
+sub bison_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# cd_command
+########################################################################
+
+sub cd_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# cd_output
+########################################################################
+
+sub cd_output {
+ local $_ = shift;
+
+ if(/^(.*?): No such file or directory/) {
+ $message = "directory '$1' doesn't exist";
+ }
+}
+
+########################################################################
+# flex_command
+########################################################################
+
+sub flex_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# for_command
+########################################################################
+
+sub for_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# gcc_command
+########################################################################
+
+sub gcc_command {
+ my $read_files;
+ my $write_files;
+
+ if(/-o\s+(\S+)\s+(\S+)$/) {
+ $write_files = [$1];
+ $read_files = [$2];
+ } elsif(/-o\s+(\S+)/) {
+ $write_files = [$1];
+ $read_files = ["<???>"];
+ } elsif(/^-shared.*?-o\s+(\S+)/) {
+ $write_files = [$1];
+ $read_files = ["<???>"];
+ } else {
+ error();
+ }
+
+ return ($read_files, $write_files);
+}
+
+########################################################################
+# gcc_output
+########################################################################
+
+sub gcc_output {
+ $file = shift;
+ local $_ = shift;
+
+ if(s/^(\d+):\s+//) {
+ $line = $1;
+ if(s/^warning:\s+//) {
+ my $supress = 0;
+
+ if(0) {
+ # Nothing
+ } elsif(/^\(near initialization for \`(.*?)\'\)$/) {
+ $supress = 0;
+ } elsif(/^\`(.*?)\' defined but not used$/) {
+ $supress = 0;
+ } elsif(/^\`(.*?)\' is not at beginning of declaration$/) {
+ $supress = 0;
+ } elsif(/^\`%x\' yields only last 2 digits of year in some locales$/) {
+ $supress = 1;
+ } elsif(/^(.*?) format, different type arg \(arg (\d+)\)$/) {
+ $supress = 0;
+ } elsif(/^assignment from incompatible pointer type$/) {
+ $supress = 0;
+ } elsif(/^comparison between signed and unsigned$/) {
+ $supress = 0;
+ } elsif(/^comparison of unsigned expression < 0 is always false$/) {
+ $supress = 0;
+ } elsif(/^comparison of unsigned expression >= 0 is always true$/) {
+ $supress = 0;
+ } elsif(/^conflicting types for built-in function \`(.*?)\'$/) {
+ $supress = 0;
+ } elsif(/^empty body in an if-statement$/) {
+ $supress = 0;
+ } elsif(/^empty body in an else-statement$/) {
+ $supress = 0;
+ } elsif(/^implicit declaration of function \`(.*?)\'$/) {
+ $supress = 0;
+ } elsif(/^initialization from incompatible pointer type$/) {
+ $supress = 0;
+ } elsif(/^missing initializer$/) {
+ $supress = 0;
+ } elsif(/^ordered comparison of pointer with integer zero$/) {
+ $supress = 0;
+ } elsif(/^passing arg (\d+) of pointer to function from incompatible pointer type$/) {
+ $supress = 0;
+ } elsif(/^passing arg (\d+) of \`(\S+)\' from incompatible pointer type$/) {
+ $supress = 0;
+ } elsif(/^passing arg (\d+) of \`(\S+)\' makes integer from pointer without a cast$/) {
+ $supress = 0;
+ } elsif(/^type of \`(.*?)\' defaults to \`(.*?)\'$/) {
+ $supress = 0;
+ } else {
+ error();
+ }
+
+ if(!$supress) {
+ if($function) {
+ $message = "function $function: $_";
+ } else {
+ $message = "$_";
+ }
+ } else {
+ $message = "";
+ }
+ } elsif(/^\`(.*?)\' undeclared \(first use in this function\)$/) {
+ $message = "$_";
+ } elsif(/^\(Each undeclared identifier is reported only once$/) {
+ $message = "$_";
+ } elsif(/^for each function it appears in.\)$/) {
+ $message = "$_";
+ } elsif(/^parse error before `(.*?)'$/) {
+ $message = "$_";
+ } elsif(/^$/) {
+ $message = "$_";
+ } else {
+ error();
+ }
+ } elsif(/^In function \`(.*?)\':$/) {
+ $function = $1;
+ } elsif(/^At top level:$/) {
+ $function = "";
+ } else {
+ error();
+ }
+}
+
+########################################################################
+# install_command
+########################################################################
+
+sub install_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# ld_command
+########################################################################
+
+sub ld_command {
+ local $_ = shift;
+
+ my $read_files;
+ my $write_files;
+
+ if(/-r\s+(.*?)\s+-o\s+(\S+)$/) {
+ $write_files = [$2];
+ $read_files = [split(/\s+/, $1)];
+ } else {
+ error();
+ }
+
+ return ($read_files, $write_files);
+}
+
+########################################################################
+# ld_output
+########################################################################
+
+sub ld_output {
+ $file = shift;
+ local $_ = shift;
+
+ if(/^the use of \`(.+?)\' is dangerous, better use \`(.+?)\'$/) {
+ # nothing
+ }
+}
+
+########################################################################
+# ldconfig_command
+########################################################################
+
+sub ldconfig_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# makedep_command
+########################################################################
+
+sub makedep_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# mkdir_command
+########################################################################
+
+sub mkdir_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# ranlib_command
+########################################################################
+
+sub ranlib_command {
+ local $_ = shift;
+
+ my $read_files;
+ my $write_files;
+
+ $read_files = [split(/\s+/)];
+ $write_files = [];
+
+ return ($read_files, $write_files);
+}
+
+########################################################################
+# rm_command
+########################################################################
+
+sub rm_command {
+ local $_ = shift;
+ s/^-f\s*//;
+ return ([], [], [split(/\s+/, $_)]);
+}
+
+########################################################################
+# sed_command
+########################################################################
+
+sub sed_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# strip_command
+########################################################################
+
+sub strip_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# winebuild_command
+########################################################################
+
+sub winebuild_command {
+ local $_ = shift;
+
+ return ([], []);
+}
+
+########################################################################
+# winebuild_output
+########################################################################
+
+sub winebuild_output {
+ $file = shift;
+ local $_ = shift;
+
+ $message = $_;
+}
+
+########################################################################
+# wmc_command
+########################################################################
+
+sub wmc_command {
+ local $_ = shift;
+
+ my $read_files;
+ my $write_files;
+
+ if(/\s+(\S+)$/) {
+ my $mc_file = $1;
+
+ my $rc_file = $mc_file;
+ $rc_file =~ s/\.mc$/.rc/;
+
+ $write_files = [$rc_file];
+ $read_files = [$mc_file];
+ } else {
+ error();
+ }
+
+ return ($read_files, $write_files);
+}
+
+########################################################################
+# wmc_output
+########################################################################
+
+sub wmc_output {
+ $file = shift;
+ local $_ = shift;
+}
+
+########################################################################
+# wrc_command
+########################################################################
+
+sub wrc_command {
+ local $_ = shift;
+
+ my $read_files;
+ my $write_files;
+
+ if(/\s+(\S+)$/) {
+ my $rc_file = $1;
+
+ my $o_file = $rc_file;
+ $o_file =~ s/\.rc$/.o/;
+
+ $write_files = [$o_file];
+ $read_files = [$rc_file];
+ } else {
+ error();
+ }
+
+ return ($read_files, $write_files);
+}
+
+########################################################################
+# wrc_output
+########################################################################
+
+sub wrc_output {
+ $file = shift;
+ local $_ = shift;
+}
+
+1;
diff --git a/tools/winapi/options.pm b/tools/winapi/options.pm
index 6ff005f..ac6d061 100644
--- a/tools/winapi/options.pm
+++ b/tools/winapi/options.pm
@@ -40,9 +40,9 @@
my $self = {};
bless ($self, $class);
- my $options_long = \%{$self->{OPTIONS_LONG}};
- my $options_short = \%{$self->{OPTIONS_SHORT}};
- my $options_usage = \${$self->{OPTIONS_USAGE}};
+ my $options_long = \%{$self->{_OPTIONS_LONG}};
+ my $options_short = \%{$self->{_OPTIONS_SHORT}};
+ my $options_usage = \${$self->{_OPTIONS_USAGE}};
my $refoptions_long = shift;
my $refoptions_short = shift;
@@ -53,12 +53,16 @@
$self->options_set("default");
- my $c_files = \@{$self->{C_FILES}};
- my $h_files = \@{$self->{H_FILES}};
- my @files;
+ my $arguments = \@{$self->{_ARGUMENTS}};
+ my $end_of_options = 0;
while(defined($_ = shift @ARGV)) {
- if(/^--(all|none)$/) {
+ if(/^--$/) {
+ $end_of_options = 1;
+ next;
+ } elsif($end_of_options) {
+ # Nothing
+ } elsif(/^--(all|none)$/) {
$self->options_set("$1");
next;
} elsif(/^-([^=]*)(=(.*))?$/) {
@@ -143,17 +147,12 @@
}
}
- if(/^-(.*)$/) {
+ if(!$end_of_options && /^-(.*)$/) {
$output->write("unknown option: $_\n");
$output->write($$options_usage);
exit 1;
} else {
- if(!-e $_) {
- $output->write("$_: no such file or directory\n");
- exit 1;
- }
-
- push @files, $_;
+ push @$arguments, $_;
}
}
@@ -163,6 +162,33 @@
exit 0;
}
+ return $self;
+}
+
+sub DESTROY {
+}
+
+sub parse_files {
+ my $self = shift;
+
+ my $arguments = \@{$self->{_ARGUMENTS}};
+ my $c_files = \@{$self->{_C_FILES}};
+ my $h_files = \@{$self->{_H_FILES}};
+
+ my $error = 0;
+ my @files = ();
+ foreach (@$arguments) {
+ if(!-e $_) {
+ $output->write("$_: no such file or directory\n");
+ $error = 1;
+ } else {
+ push @files, $_;
+ }
+ }
+ if($error) {
+ exit 1;
+ }
+
my @paths = ();
my @c_files = ();
my @h_files = ();
@@ -186,7 +212,7 @@
my %found;
@$c_files = sort(map {
s/^\.\/(.*)$/$1/;
- if(defined($found{$_}) || /glue\.c|spec\.c$/) {
+ if(defined($found{$_})) {
();
} else {
$found{$_}++;
@@ -209,18 +235,13 @@
}
} split(/\n/, `$h_command`));
}
-
- return $self;
-}
-
-sub DESTROY {
}
sub options_set {
my $self = shift;
- my $options_long = \%{$self->{OPTIONS_LONG}};
- my $options_short = \%{$self->{OPTIONS_SHORT}};
+ my $options_long = \%{$self->{_OPTIONS_LONG}};
+ my $options_short = \%{$self->{_OPTIONS_SHORT}};
local $_ = shift;
for my $name (sort(keys(%$options_long))) {
@@ -255,8 +276,8 @@
sub show_help {
my $self = shift;
- my $options_long = \%{$self->{OPTIONS_LONG}};
- my $options_short = \%{$self->{OPTIONS_SHORT}};
+ my $options_long = \%{$self->{_OPTIONS_LONG}};
+ my $options_short = \%{$self->{_OPTIONS_SHORT}};
my $maxname = 0;
for my $name (sort(keys(%$options_long))) {
@@ -329,8 +350,36 @@
}
}
-sub c_files { my $self = shift; return @{$self->{C_FILES}}; }
+sub arguments {
+ my $self = shift;
-sub h_files { my $self = shift; return @{$self->{H_FILES}}; }
+ my $arguments = \@{$self->{_ARGUMENTS}};
+
+ return @$arguments;
+}
+
+sub c_files {
+ my $self = shift;
+
+ my $c_files = \@{$self->{_C_FILES}};
+
+ if(!defined(@$c_files)) {
+ $self->parse_files;
+ }
+
+ return @$c_files;
+}
+
+sub h_files {
+ my $self = shift;
+
+ my $h_files = \@{$self->{_H_FILES}};
+
+ if(!defined(@$h_files)) {
+ $self->parse_files;
+ }
+
+ return @$h_files;
+}
1;
diff --git a/tools/winapi/output.pm b/tools/winapi/output.pm
index 7c9bf0d..018d63f 100644
--- a/tools/winapi/output.pm
+++ b/tools/winapi/output.pm
@@ -26,6 +26,7 @@
my $self = {};
bless ($self, $class);
+ my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
my $last_time = \${$self->{LAST_TIME}};
@@ -33,6 +34,7 @@
my $prefix = \${$self->{PREFIX}};
my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
+ $$progress_enabled = 1;
$$progress = "";
$$last_progress = "";
$$last_time = 0;
@@ -43,62 +45,91 @@
return $self;
}
+sub DESTROY {
+ my $self = shift;
+
+ $self->hide_progress;
+}
+
+sub enable_progress {
+ my $self = shift;
+ my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
+
+ $$progress_enabled = 1;
+}
+
+sub disable_progress {
+ my $self = shift;
+ my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
+
+ $$progress_enabled = 0;
+}
+
sub show_progress {
my $self = shift;
+ my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
my $progress_count = \${$self->{PROGRESS_COUNT}};
$$progress_count++;
- if($$progress_count > 0 && $$progress && $stderr_isatty) {
- print STDERR $$progress;
- $$last_progress = $$progress;
+ if($$progress_enabled) {
+ if($$progress_count > 0 && $$progress && $stderr_isatty) {
+ print STDERR $$progress;
+ $$last_progress = $$progress;
+ }
}
}
sub hide_progress {
my $self = shift;
+ my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
my $progress_count = \${$self->{PROGRESS_COUNT}};
$$progress_count--;
- if($$last_progress && $stderr_isatty) {
- my $message;
- for (1..length($$last_progress)) {
- $message .= " ";
+ if($$progress_enabled) {
+ if($$last_progress && $stderr_isatty) {
+ my $message;
+ for (1..length($$last_progress)) {
+ $message .= " ";
+ }
+ print STDERR $message;
+ undef $$last_progress;
}
- print STDERR $message;
- undef $$last_progress;
}
}
sub update_progress {
my $self = shift;
+ my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
my $progress = \${$self->{PROGRESS}};
my $last_progress = \${$self->{LAST_PROGRESS}};
- my $prefix = "";
- my $suffix = "";
- if($$last_progress) {
- for (1..length($$last_progress)) {
- $prefix .= "";
- }
-
- my $diff = length($$last_progress)-length($$progress);
- if($diff > 0) {
- for (1..$diff) {
- $suffix .= " ";
+ if($$progress_enabled) {
+ my $prefix = "";
+ my $suffix = "";
+ if($$last_progress) {
+ for (1..length($$last_progress)) {
+ $prefix .= "";
}
- for (1..$diff) {
- $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;
}
- print STDERR $prefix . $$progress . $suffix;
- $$last_progress = $$progress;
}
sub progress {
diff --git a/tools/winapi/type.pm b/tools/winapi/type.pm
new file mode 100644
index 0000000..3608355
--- /dev/null
+++ b/tools/winapi/type.pm
@@ -0,0 +1,14 @@
+package type;
+
+use strict;
+
+sub new {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $self = {};
+ bless ($self, $class);
+
+ return $self;
+}
+
+1;
diff --git a/tools/winapi/winapi_check_options.pm b/tools/winapi/winapi_check_options.pm
index 22d5e8a..88dab8c 100644
--- a/tools/winapi/winapi_check_options.pm
+++ b/tools/winapi/winapi_check_options.pm
@@ -127,16 +127,10 @@
"v" => "verbose"
);
-my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
+my $options_usage = "usage: winapi_check [--help] [<files>]\n";
$options = '_winapi_check_options'->new(\%options_long, \%options_short, $options_usage);
-my $global = \${$options->{GLOBAL}};
-
-if($wine_dir ne ".") {
- $$global = 0;
-}
-
package _winapi_check_options;
use base qw(_options);
diff --git a/tools/winapi/winapi_extract b/tools/winapi/winapi_extract
index c93c1e2..8423836 100755
--- a/tools/winapi/winapi_extract
+++ b/tools/winapi/winapi_extract
@@ -13,18 +13,18 @@
&file_type &files_skip &files_filter &get_spec_files
$current_dir $wine_dir $winapi_dir $winapi_check_dir
);
-use modules;
-use nativeapi;
use output qw($output);
-use options;
-use winapi;
+use winapi_extract_options qw($options);
+
+use function;
+use type;
use winapi_function;
use winapi_parser;
-use winapi_extract_options qw($options);
+use winapi qw(@winapis);
my %module2spec_file;
my %module2type;
-{
+if($options->spec_files) {
local $_;
foreach my $spec_file (get_spec_files("winelib")) {
@@ -49,22 +49,6 @@
}
}
-my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat");
-
-my $win16api = 'winapi'->new($options, $output, "win16", "$winapi_check_dir/win16");
-my $win32api = 'winapi'->new($options, $output, "win32", "$winapi_check_dir/win32");
-my @winapis = ($win16api, $win32api);
-
-if($wine_dir eq ".") {
- 'winapi'->read_all_spec_files($modules, $wine_dir, $current_dir, \&file_type, $win16api, $win32api);
-} else {
- my @spec_files = $modules->allowed_spec_files($wine_dir, $current_dir);
- 'winapi'->read_spec_files($modules, $wine_dir, $current_dir, \@spec_files, $win16api, $win32api);
-}
-
-my $nativeapi = 'nativeapi'->new($options, $output, "$winapi_check_dir/nativeapi.dat",
- "$wine_dir/configure.in", "$wine_dir/include/config.h.in");
-
my %specifications;
sub documentation_specifications {
@@ -164,6 +148,14 @@
$output->progress("$file: file $progress_current of $progress_max");
}
+ my $create_function = sub {
+ if($options->stub_statistics) {
+ return 'winapi_function'->new;
+ } else {
+ return 'function'->new;
+ }
+ };
+
my $found_function = sub {
my $function = shift;
@@ -191,12 +183,20 @@
$output->prefix("");
};
+ my $create_type = sub {
+ return 'type'->new;
+ };
+
+ my $found_type = sub {
+ my $type = shift;
+ };
+
my $found_preprocessor = sub {
my $directive = shift;
my $argument = shift;
};
- &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
+ &winapi_parser::parse_c_file($file, $create_function, $found_function, $create_type, $found_type, $found_preprocessor);
my @internal_names = keys(%functions);
if($#internal_names < 0) {
@@ -342,7 +342,7 @@
foreach my $internal_name ($winapi->all_internal_functions,$winapi->all_functions_stub) {
foreach my $module (split(/ \& /, $winapi->function_internal_module($internal_name))) {
- if($winapi->function_stub($internal_name)) {
+ if($winapi->is_function_stub_in_module($module, $internal_name)) {
$module_stub_count{$module}++;
}
$module_total_count{$module}++;
@@ -372,4 +372,3 @@
}
}
-$output->hide_progress;
diff --git a/tools/winapi/winapi_extract_options.pm b/tools/winapi/winapi_extract_options.pm
index 0e4e978..3d29621 100644
--- a/tools/winapi/winapi_extract_options.pm
+++ b/tools/winapi/winapi_extract_options.pm
@@ -26,7 +26,7 @@
"global" => { default => 1, description => "global extraction" },
"spec-files" => { default => 1, parent => "global", description => "spec files extraction" },
- "stub-statistics" => { default => 0, parent => "global", description => "stub statistics" },
+ "stub-statistics" => { default => 1, parent => "global", description => "stub statistics" },
);
my %options_short = (
diff --git a/tools/winapi/winapi_fixup b/tools/winapi/winapi_fixup
index 4a87ba2..f043138 100755
--- a/tools/winapi/winapi_fixup
+++ b/tools/winapi/winapi_fixup
@@ -17,24 +17,14 @@
$current_dir $wine_dir $winapi_dir $winapi_check_dir
);
use output qw($output);
-use modules;
-use util;
-use winapi;
-use winapi_parser;
use winapi_fixup_options qw($options);
+use modules qw($modules);
+use winapi qw($win16api $win32api @winapis);
-my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat");
-
-my $win16api = 'winapi'->new($options, $output, "win16", "$winapi_check_dir/win16");
-my $win32api = 'winapi'->new($options, $output, "win32", "$winapi_check_dir/win32");
-my @winapis = ($win16api, $win32api);
-
-if($wine_dir eq ".") {
- 'winapi'->read_all_spec_files($modules, $wine_dir, $current_dir, \&file_type, $win16api, $win32api);
-} else {
- my @spec_files = $modules->allowed_spec_files($wine_dir, $current_dir);
- 'winapi'->read_spec_files($modules, $wine_dir, $current_dir, \@spec_files, $win16api, $win32api);
-}
+use type;
+use util;
+use winapi_function;
+use winapi_parser;
my @c_files = $options->c_files;
@c_files = files_skip(@c_files);
@@ -58,6 +48,10 @@
my %documentation_line_used;
+ my $create_function = sub {
+ return 'winapi_function'->new;
+ };
+
my $found_function = sub {
my $function = shift;
@@ -434,12 +428,21 @@
$output->prefix("");
};
+
+ my $create_type = sub {
+ return 'type'->new;
+ };
+
+ my $found_type = sub {
+ my $type = shift;
+ };
+
my $found_preprocessor = sub {
my $directive = shift;
my $argument = shift;
};
- &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
+ &winapi_parser::parse_c_file($file, $create_function, $found_function, $create_type, $found_type, $found_preprocessor);
my $editor = sub {
local *IN = shift;
@@ -598,4 +601,3 @@
}
}
-$output->hide_progress;