diff --git a/tools/winapi/config.pm b/tools/winapi/config.pm index 3d950e6c442..26c56f30955 100644 --- a/tools/winapi/config.pm +++ b/tools/winapi/config.pm @@ -93,9 +93,16 @@ sub file_normalize { local $_ = shift; foreach my $dir (split(m%/%, $current_dir)) { - s%^(\.\./)*\.\./$dir/%%; - if(defined($1)) { - $_ = "$1$_"; + if(s%^(\.\./)*\.\./$dir/%%) { + if(defined($1)) { + $_ = "$1$_"; + } + } + } + + while(m%^(.*?)([^/\.]+)/\.\./(.*?)$%) { + if($2 ne "." && $2 ne "..") { + $_ = "$1$3"; } } diff --git a/tools/winapi/make_filter b/tools/winapi/make_filter index 03c6aac34c5..827827087f8 100755 --- a/tools/winapi/make_filter +++ b/tools/winapi/make_filter @@ -7,11 +7,14 @@ BEGIN { require "$1/winapi/setup.pm"; } -use config qw($current_dir $wine_dir); +use config qw( + &file_absolutize &file_normalize + $current_dir $wine_dir +); use output qw($output); use make_filter_options qw($options); -use make_parser; +use make_parser qw($directory $tool $file $line $message); if($options->progress) { $output->enable_progress; @@ -23,7 +26,7 @@ if($options->progress) { # main ######################################################################## -my $command = join(" ", $options->arguments); +my $command = $options->make . " " . join(" ", $options->arguments); open(IN, "($command) 2>&1 |"); while() { @@ -33,35 +36,32 @@ while() { 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($message) { if($file && $line) { - if($directory) { - $output->write("$directory/$file:$line: $message\n"); + if($directory && $directory ne ".") { + $output->write(&file_normalize("$directory/$file") . ":$line: $message\n"); } else { $output->write("$file:$line: $message\n"); } } elsif($file) { - if($directory) { - $output->write("$directory/$file: $message\n"); + if($directory && $directory ne ".") { + $output->write(&file_normalize("$directory/$file") . ": $message\n"); } else { $output->write("$file: $message\n"); } } else { - if($directory) { - $output->write("$directory: " . &make_parser::tool() . ": $message\n"); + if($directory && $directory ne ".") { + $output->write("$directory: $tool: $message\n"); + } elsif($tool) { + $output->write("$tool: $message\n"); } else { - $output->write(".: " . &make_parser::tool() . ": $message\n"); + $output->write("$message\n"); } } + } elsif($tool eq "make") { + if($directory && $directory ne ".") { + $output->progress("$directory: make"); + } } } diff --git a/tools/winapi/make_filter_options.pm b/tools/winapi/make_filter_options.pm index ceecd77bf95..98f3becc66a 100644 --- a/tools/winapi/make_filter_options.pm +++ b/tools/winapi/make_filter_options.pm @@ -10,7 +10,7 @@ require Exporter; @EXPORT = qw(); @EXPORT_OK = qw($options); -use options qw($options &parse_comma_list); +use options qw($options &parse_comma_list &parse_value); my %options_long = ( "debug" => { default => 0, description => "debug mode" }, @@ -19,6 +19,9 @@ my %options_long = ( "progress" => { default => 1, description => "show progress" }, + "make" => { default => "make", + parser => \&parse_value, + description => "use which make" }, "pedantic" => { default => 0, description => "be pedantic" }, ); diff --git a/tools/winapi/make_parser.pm b/tools/winapi/make_parser.pm index 63037d9bef4..124f5397024 100644 --- a/tools/winapi/make_parser.pm +++ b/tools/winapi/make_parser.pm @@ -2,32 +2,39 @@ package make_parser; use strict; +use strict; + +use setup qw($current_dir $wine_dir $winapi_dir $winapi_check_dir); + +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); +require Exporter; + +@ISA = qw(Exporter); +@EXPORT = qw(); +@EXPORT_OK = qw($directory $tool $file $line $message); + +use vars qw($directory $tool $file $line $message); + use output qw($output); +use options qw($options); ######################################################################## # 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"); + if(defined($tool)) { + $output->write("make_filter: $tool: can't parse output: '$current'\n"); + } else { + $output->write("make_filter: <>: can't parse output: '$current'\n"); + } exit 1; } @@ -50,40 +57,52 @@ sub line { $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) + foreach my $file (@{$read_files}) { + $output->lazy_progress("$directory: ld: reading '$file'"); + } + my $file = $$write_files[0]; + $output->progress("$directory: ld: writing '$file'"); + } elsif($tool =~ /^rm$/) { + foreach my $file (@{$remove_files}) { + $output->lazy_progress("$directory: rm: removing '$file'"); + } } else { - $output->progress($progress) + 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}) . "]"; + } + + $output->progress($progress); } - return 0; } if(/^Wine build complete\.$/) { # Nothing - } elsif(s/^make\[(\d+)\]:\s*//) { + } elsif(/^(.*?) is newer than (.*?), please rerun (.*?)\!$/) { + $message = "$_"; + } elsif(/^(.*?) is older than (.*?), please rerun (.*?)$/) { + $message = "$_"; + } elsif(s/^make(?:\[(\d+)\])?:\s*//) { $tool = "make"; make_output($1, $_); + } elsif(!defined($tool)) { + error(); } elsif($tool eq "bison" && /^conflicts:\s+\d+\s+shift\/reduce$/) { # Nothing } elsif($tool eq "gcc" && /^In file included from (.+?):(\d+):$/) { @@ -101,7 +120,7 @@ sub line { } elsif($tool eq "cd" && s/^\/bin\/sh:\s*cd:\s*//) { parse_cd_output($_); } else { - error($_) + error(); } $file =~ s/^\.\///; @@ -123,7 +142,7 @@ sub make_output { if(0) { # Nothing } elsif(/^\*\*\* \[(.*?)\] Error (\d+)$/) { - # Nothing + $message = "$_"; } elsif(/^\*\*\* Warning:\s+/) { # if(/^File \`(.+?)\' has modification time in the future \((.+?) > \(.+?\)\)$/) { # Nothing @@ -150,7 +169,9 @@ sub make_output { } } $directory = join("/", @components); - } elsif(/^Nothing to be done for \`(.*?)\'.$/) { + } elsif(/^(.*?) is older than (.*?), please rerun (.*?)\$/) { + # Nothing + } elsif(/^Nothing to be done for \`(.*?)\'\.$/) { # Nothing } elsif(s/^warning:\s+//) { if(/^Clock skew detected. Your build may be incomplete.$/) { @@ -378,6 +399,8 @@ sub gcc_output { if(0) { # Nothing + } elsif(/^((?:signed |unsigned )?(?:int|long)) format, (different type|\S+) arg \(arg (\d+)\)$/) { + $supress = 0; } elsif(/^\(near initialization for \`(.*?)\'\)$/) { $supress = 0; } elsif(/^\`(.*?)\' defined but not used$/) { @@ -386,10 +409,16 @@ sub gcc_output { $supress = 0; } elsif(/^\`%x\' yields only last 2 digits of year in some locales$/) { $supress = 1; - } elsif(/^(.*?) format, different type arg \(arg (\d+)\)$/) { + } elsif(/^assignment makes integer from pointer without a cast$/) { + $supress = 0; + } elsif(/^assignment makes pointer from integer without a cast$/) { $supress = 0; } elsif(/^assignment from incompatible pointer type$/) { $supress = 0; + } elsif(/^cast from pointer to integer of different size$/) { + $supress = 0; + } elsif(/^comparison between pointer and integer$/) { + $supress = 0; } elsif(/^comparison between signed and unsigned$/) { $supress = 0; } elsif(/^comparison of unsigned expression < 0 is always false$/) { @@ -406,18 +435,28 @@ sub gcc_output { $supress = 0; } elsif(/^initialization from incompatible pointer type$/) { $supress = 0; + } elsif(/^initialization makes pointer from integer without a cast$/) { + $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$/) { + } elsif(/^passing arg (\d+) of (?:pointer to function|\`(\S+)\') from incompatible pointer type$/) { $supress = 0; - } elsif(/^passing arg (\d+) of \`(\S+)\' from incompatible pointer type$/) { + } elsif(/^passing arg (\d+) of (?:pointer to function|\`(\S+)\') makes integer from pointer without a cast$/) { $supress = 0; - } elsif(/^passing arg (\d+) of \`(\S+)\' makes integer from pointer without a cast$/) { + } elsif(/^passing arg (\d+) of (?:pointer to function|\`(\S+)\') makes pointer from integer without a cast$/) { + $supress = 0; + } elsif(/^return makes integer from pointer without a cast$/) { + $supress = 0; + } elsif(/^return makes pointer from integer without a cast$/) { $supress = 0; } elsif(/^type of \`(.*?)\' defaults to \`(.*?)\'$/) { $supress = 0; + } elsif(/^unused variable \`(.*?)\'$/) { + $supress = 0; + } elsif(!$options->pedantic) { + $supress = 0; } else { error(); } @@ -435,11 +474,17 @@ sub gcc_output { $message = "$_"; } elsif(/^\(Each undeclared identifier is reported only once$/) { $message = "$_"; + } elsif(/^conflicting types for \`(.*?)\'$/) { + $message = "$_"; } elsif(/^for each function it appears in.\)$/) { $message = "$_"; + } elsif(/^too many arguments to function$/) { + $message = "$_"; + } elsif(/^previous declaration of \`(.*?)\'$/) { + $message = "$_"; } elsif(/^parse error before `(.*?)'$/) { $message = "$_"; - } elsif(/^$/) { + } elsif(!$options->pedantic) { $message = "$_"; } else { error(); diff --git a/tools/winapi/options.pm b/tools/winapi/options.pm index ac6d0617036..b0fdd4d8b11 100644 --- a/tools/winapi/options.pm +++ b/tools/winapi/options.pm @@ -7,13 +7,16 @@ require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); -@EXPORT_OK = qw($options &parse_comma_list); +@EXPORT_OK = qw($options &parse_comma_list &parse_value); use vars qw($options); +use output qw($output); + sub parse_comma_list { my $prefix = shift; my $value = shift; + if(defined($prefix) && $prefix eq "no") { return { active => 0, filter => 0, hash => {} }; } elsif(defined($value)) { @@ -27,6 +30,13 @@ sub parse_comma_list { } } +sub parse_value { + my $prefix = shift; + my $value = shift; + + return $value; +} + package _options; use strict; diff --git a/tools/winapi/setup.pm b/tools/winapi/setup.pm index 9c0961f3495..e123a7c32ee 100644 --- a/tools/winapi/setup.pm +++ b/tools/winapi/setup.pm @@ -12,24 +12,27 @@ BEGIN { use vars qw($current_dir $wine_dir $winapi_dir $winapi_check_dir); - my $dir; - my $tool; + my $tool = $0; + $tool =~ s%^(?:.*?/)?([^/]+)$%$1%; - if($0 =~ m%^((.*?)/?tools/([^/]+))/([^/]+)$%) + if(defined($current_dir) && defined($wine_dir) && + defined($winapi_dir) && defined($winapi_check_dir)) { - $winapi_dir = $1; - $winapi_check_dir = $1; - $dir = $3; - $tool = $4; - - if(defined($2) && $2 ne "") + # Nothing + } elsif($0 =~ m%^(.*?)/?tools/([^/]+)/[^/]+$%) { + my $dir = $2; + + if(defined($1) && $1 ne "") { - $wine_dir = $2; + $wine_dir = $1; } else { $wine_dir = "."; } - + + require Cwd; + my $cwd = Cwd::cwd(); + if($wine_dir =~ /^\./) { $current_dir = "."; my $pwd; chomp($pwd = `pwd`); @@ -38,19 +41,32 @@ BEGIN { $current_dir = "$1/$current_dir"; } $current_dir =~ s%/\.$%%; + } elsif($wine_dir eq $cwd) { + $wine_dir = "."; + $current_dir = "."; + } elsif($cwd =~ m%^$wine_dir/(.*?)?$%) { + $current_dir = $1; + $wine_dir = "."; + foreach my $dir (split(m%/%, $current_dir)) { + $wine_dir = "../$wine_dir"; + } + $wine_dir =~ s%/\.$%%; + } else { + print STDERR "$tool: You must run this tool in the main Wine directory or a sub directory\n"; + exit 1; } - + + $winapi_dir = "$wine_dir/tools/winapi"; $winapi_dir =~ s%^\./%%; - $winapi_dir =~ s/$dir/winapi/g; - + + $winapi_check_dir = "$wine_dir/tools/winapi_check"; $winapi_check_dir =~ s%^\./%%; - $winapi_check_dir =~ s/$dir/winapi_check/g; + + push @INC, ($winapi_dir, $winapi_check_dir); } else { print STDERR "$tool: You must run this tool in the main Wine directory or a sub directory\n"; exit 1; } - - push @INC, ($winapi_dir, $winapi_check_dir); } 1;