- A few more bug fixes
- Reorganization continues - New tool (make_filter) for filtering make output added
This commit is contained in:
parent
9a57ef4de1
commit
67f0a70c33
|
@ -10,9 +10,10 @@ require Exporter;
|
|||
@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 vars qw($current_dir $wine_dir $winapi_dir $winapi_check_dir);
|
|||
|
||||
use output qw($output);
|
||||
|
||||
use File::Find;
|
||||
|
||||
sub file_type {
|
||||
local $_ = shift;
|
||||
|
||||
|
@ -30,7 +33,7 @@ sub file_type {
|
|||
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 @@ sub file_skip {
|
|||
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 @@ sub file_normalize {
|
|||
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", @_); }
|
||||
|
|
|
@ -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();
|
|
@ -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;
|
|
@ -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;
|
|
@ -40,9 +40,9 @@ sub new {
|
|||
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 @@ sub new {
|
|||
|
||||
$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 @@ sub new {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ sub new {
|
|||
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 @@ sub new {
|
|||
my %found;
|
||||
@$c_files = sort(map {
|
||||
s/^\.\/(.*)$/$1/;
|
||||
if(defined($found{$_}) || /glue\.c|spec\.c$/) {
|
||||
if(defined($found{$_})) {
|
||||
();
|
||||
} else {
|
||||
$found{$_}++;
|
||||
|
@ -209,18 +235,13 @@ sub new {
|
|||
}
|
||||
} 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 options_set {
|
|||
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 AUTOLOAD {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -26,6 +26,7 @@ sub new {
|
|||
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 @@ sub new {
|
|||
my $prefix = \${$self->{PREFIX}};
|
||||
my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
|
||||
|
||||
$$progress_enabled = 1;
|
||||
$$progress = "";
|
||||
$$last_progress = "";
|
||||
$$last_time = 0;
|
||||
|
@ -43,62 +45,91 @@ sub new {
|
|||
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 {
|
||||
|
|
|
@ -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;
|
|
@ -127,16 +127,10 @@ my %options_short = (
|
|||
"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);
|
||||
|
||||
|
|
|
@ -13,18 +13,18 @@ use config qw(
|
|||
&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 %module2type;
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ foreach my $file (@c_files) {
|
|||
$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 @@ foreach my $file (@c_files) {
|
|||
$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 @@ if($options->stub_statistics) {
|
|||
|
||||
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 @@ if($options->stub_statistics) {
|
|||
}
|
||||
}
|
||||
|
||||
$output->hide_progress;
|
||||
|
|
|
@ -26,7 +26,7 @@ my %options_long = (
|
|||
"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 = (
|
||||
|
|
|
@ -17,24 +17,14 @@ use config qw(
|
|||
$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 @@ foreach my $file (@c_files) {
|
|||
|
||||
my %documentation_line_used;
|
||||
|
||||
my $create_function = sub {
|
||||
return 'winapi_function'->new;
|
||||
};
|
||||
|
||||
my $found_function = sub {
|
||||
my $function = shift;
|
||||
|
||||
|
@ -434,12 +428,21 @@ foreach my $file (@c_files) {
|
|||
$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 @@ foreach my $file (@c_files) {
|
|||
}
|
||||
}
|
||||
|
||||
$output->hide_progress;
|
||||
|
|
|
@ -344,7 +344,6 @@ dlls/user
|
|||
% dlls/user/user.spec
|
||||
|
||||
controls
|
||||
dlls/kernel
|
||||
dlls/user
|
||||
misc
|
||||
windows
|
||||
|
|
|
@ -11,30 +11,33 @@ require Exporter;
|
|||
|
||||
use vars qw($modules);
|
||||
|
||||
use config qw(
|
||||
&file_type &files_skip
|
||||
&file_directory
|
||||
&get_c_files
|
||||
$current_dir $wine_dir
|
||||
$winapi_check_dir
|
||||
);
|
||||
use options qw($options);
|
||||
use output qw($output);
|
||||
|
||||
$modules = 'modules'->new;
|
||||
|
||||
sub new {
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
my $self = {};
|
||||
bless ($self, $class);
|
||||
|
||||
my $options = \${$self->{OPTIONS}};
|
||||
my $output = \${$self->{OUTPUT}};
|
||||
my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
|
||||
my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
|
||||
my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
|
||||
|
||||
$$options = shift;
|
||||
$$output = shift;
|
||||
my $wine_dir = shift;
|
||||
my $current_dir = shift;
|
||||
my $file_type = shift;
|
||||
my $module_file = shift;
|
||||
|
||||
$module_file =~ s/^\.\///;
|
||||
my $module_file = "$winapi_check_dir/modules.dat";
|
||||
|
||||
my @all_spec_files = map {
|
||||
s/^.\/(.*)$/$1/;
|
||||
if(&$file_type($_) eq "winelib") {
|
||||
if(file_type($_) eq "winelib") {
|
||||
$_;
|
||||
} else {
|
||||
();
|
||||
|
@ -46,8 +49,8 @@ sub new {
|
|||
$all_spec_files{$file}++ ;
|
||||
}
|
||||
|
||||
if($$options->progress) {
|
||||
$$output->progress("modules.dat");
|
||||
if($options->progress) {
|
||||
$output->progress("modules.dat");
|
||||
}
|
||||
|
||||
my $allowed_dir;
|
||||
|
@ -64,7 +67,7 @@ sub new {
|
|||
$spec_file = $1;
|
||||
|
||||
if(!-f "$wine_dir/$spec_file") {
|
||||
$$output->write("modules.dat: $spec_file: file ($spec_file) doesn't exist or is no file\n");
|
||||
$output->write("modules.dat: $spec_file: file ($spec_file) doesn't exist or is no file\n");
|
||||
}
|
||||
|
||||
if($wine_dir eq ".") {
|
||||
|
@ -81,14 +84,14 @@ sub new {
|
|||
$$dir2spec_file{$allowed_dir}{$spec_file}++;
|
||||
|
||||
if(!-d "$wine_dir/$allowed_dir") {
|
||||
$$output->write("modules.dat: $spec_file: directory ($allowed_dir) doesn't exist or is no directory\n");
|
||||
$output->write("modules.dat: $spec_file: directory ($allowed_dir) doesn't exist or is no directory\n");
|
||||
}
|
||||
}
|
||||
close(IN);
|
||||
|
||||
foreach my $spec_file (sort(keys(%all_spec_files))) {
|
||||
if($all_spec_files{$spec_file} > 0) {
|
||||
$$output->write("modules.dat: $spec_file: exists but is not specified\n");
|
||||
$output->write("modules.dat: $spec_file: exists but is not specified\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,6 +108,44 @@ sub all_modules {
|
|||
return sort(keys(%$module2spec_file));
|
||||
}
|
||||
|
||||
sub complete_modules {
|
||||
my $self = shift;
|
||||
|
||||
my $c_files = shift;
|
||||
|
||||
my %dirs;
|
||||
|
||||
foreach my $file (@$c_files) {
|
||||
my $dir = file_directory("$current_dir/$file");
|
||||
$dirs{$dir}++;
|
||||
}
|
||||
|
||||
my @c_files = get_c_files("winelib");
|
||||
@c_files = files_skip(@c_files);
|
||||
foreach my $file (@c_files) {
|
||||
my $dir = file_directory($file);
|
||||
if(exists($dirs{$dir})) {
|
||||
$dirs{$dir}--;
|
||||
}
|
||||
}
|
||||
|
||||
my @complete_modules = ();
|
||||
foreach my $module ($self->all_modules) {
|
||||
my $index = -1;
|
||||
my @dirs = $self->allowed_dirs_for_module($module);
|
||||
foreach my $dir (@dirs) {
|
||||
if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
if($index == $#dirs) {
|
||||
push @complete_modules, $module;
|
||||
}
|
||||
}
|
||||
|
||||
return @complete_modules;
|
||||
}
|
||||
|
||||
sub spec_file_module {
|
||||
my $self = shift;
|
||||
|
||||
|
@ -183,13 +224,8 @@ sub allowed_dirs_for_module {
|
|||
sub allowed_spec_files {
|
||||
my $self = shift;
|
||||
|
||||
my $options = \${$self->{OPTIONS}};
|
||||
my $output = \${$self->{OUTPUT}};
|
||||
my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
|
||||
|
||||
my $wine_dir = shift;
|
||||
my $current_dir = shift;
|
||||
|
||||
my @dirs = map {
|
||||
s/^\.\/(.*)$/$1/;
|
||||
if(/^\.$/) {
|
||||
|
@ -227,7 +263,6 @@ sub found_module_in_dir {
|
|||
sub global_report {
|
||||
my $self = shift;
|
||||
|
||||
my $output = \${$self->{OUTPUT}};
|
||||
my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
|
||||
my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
|
||||
my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
|
||||
|
@ -244,7 +279,7 @@ sub global_report {
|
|||
}
|
||||
|
||||
foreach my $message (sort(@messages)) {
|
||||
$$output->write($message);
|
||||
$output->write($message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,31 +11,33 @@ require Exporter;
|
|||
|
||||
use vars qw($nativeapi);
|
||||
|
||||
use config qw(&file_type $current_dir $wine_dir $winapi_check_dir);
|
||||
use options qw($options);
|
||||
use output qw($output);
|
||||
|
||||
$nativeapi = 'nativeapi'->new;
|
||||
|
||||
sub new {
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
my $self = {};
|
||||
bless ($self, $class);
|
||||
|
||||
my $options = \${$self->{OPTIONS}};
|
||||
my $output = \${$self->{OUTPUT}};
|
||||
my $functions = \%{$self->{FUNCTIONS}};
|
||||
my $conditionals = \%{$self->{CONDITIONALS}};
|
||||
my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
|
||||
my $conditional_functions = \%{$self->{CONDITIONAL_FUNCTIONS}};
|
||||
|
||||
$$options = shift;
|
||||
$$output = shift;
|
||||
my $api_file = shift;
|
||||
my $configure_in_file = shift;
|
||||
my $config_h_in_file = shift;
|
||||
my $api_file = "$winapi_check_dir/nativeapi.dat";
|
||||
my $configure_in_file = "$wine_dir/configure.in";
|
||||
my $config_h_in_file = "$wine_dir/include/config.h.in";
|
||||
|
||||
$api_file =~ s/^\.\///;
|
||||
$configure_in_file =~ s/^\.\///;
|
||||
$config_h_in_file =~ s/^\.\///;
|
||||
|
||||
if($$options->progress) {
|
||||
$$output->progress("$api_file");
|
||||
if($options->progress) {
|
||||
$output->progress("$api_file");
|
||||
}
|
||||
|
||||
open(IN, "< $api_file");
|
||||
|
@ -49,8 +51,8 @@ sub new {
|
|||
}
|
||||
close(IN);
|
||||
|
||||
if($$options->progress) {
|
||||
$$output->progress("$configure_in_file");
|
||||
if($options->progress) {
|
||||
$output->progress("$configure_in_file");
|
||||
}
|
||||
|
||||
my $again = 0;
|
||||
|
@ -100,8 +102,8 @@ sub new {
|
|||
}
|
||||
close(IN);
|
||||
|
||||
if($$options->progress) {
|
||||
$$output->progress("$config_h_in_file");
|
||||
if($options->progress) {
|
||||
$output->progress("$config_h_in_file");
|
||||
}
|
||||
|
||||
open(IN, "< $config_h_in_file");
|
||||
|
@ -186,7 +188,7 @@ sub global_report {
|
|||
}
|
||||
|
||||
foreach my $message (sort(@messages)) {
|
||||
$$output->write($message);
|
||||
$output->write($message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,49 +11,53 @@ require Exporter;
|
|||
|
||||
use vars qw($win16api $win32api @winapis);
|
||||
|
||||
use config qw(
|
||||
&file_type
|
||||
&get_api_files &get_spec_files
|
||||
$current_dir $wine_dir
|
||||
);
|
||||
use modules qw($modules);
|
||||
use options qw($options);
|
||||
use output qw($output);
|
||||
|
||||
$win16api = 'winapi'->new("win16");
|
||||
$win32api = 'winapi'->new("win32");
|
||||
@winapis = ($win16api, $win32api);
|
||||
|
||||
my @spec_files = get_spec_files("winelib");
|
||||
foreach my $file (@spec_files) {
|
||||
(my $type, my $module) = 'winapi'->get_spec_file_type("$wine_dir/$file");
|
||||
$modules->spec_file_module($file, $module);
|
||||
}
|
||||
|
||||
if($wine_dir eq ".") {
|
||||
'winapi'->read_spec_files(\@spec_files);
|
||||
} else {
|
||||
@spec_files = $modules->allowed_spec_files;
|
||||
'winapi'->read_spec_files(\@spec_files);
|
||||
}
|
||||
|
||||
sub new {
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
my $self = {};
|
||||
bless ($self, $class);
|
||||
|
||||
my $options = \${$self->{OPTIONS}};
|
||||
my $output = \${$self->{OUTPUT}};
|
||||
my $name = \${$self->{NAME}};
|
||||
|
||||
$$options = shift;
|
||||
$$output = shift;
|
||||
$$name = shift;
|
||||
my $path = shift;
|
||||
|
||||
if($$options->progress) {
|
||||
$$output->progress("$path: searching for *.api");
|
||||
}
|
||||
|
||||
my @files = map {
|
||||
s%^\./%%;
|
||||
$_;
|
||||
} split(/\n/, `find $path -name \\*.api`);
|
||||
|
||||
foreach my $file (@files) {
|
||||
foreach my $file (get_api_files($$name)) {
|
||||
my $module = $file;
|
||||
|
||||
if($$options->progress) {
|
||||
$$output->lazy_progress("$file");
|
||||
if($options->progress) {
|
||||
$output->lazy_progress("$file");
|
||||
}
|
||||
|
||||
$module =~ s/.*?\/([^\/]*?)\.api$/$1/;
|
||||
$self->parse_api_file($file,$module);
|
||||
}
|
||||
|
||||
if($$name eq "win16") {
|
||||
$win16api = $self;
|
||||
} elsif($$name eq "win32") {
|
||||
$win32api = $self;
|
||||
}
|
||||
|
||||
push @winapis, $self;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
@ -68,8 +72,6 @@ sub win32api {
|
|||
sub parse_api_file {
|
||||
my $self = shift;
|
||||
|
||||
my $options = \${$self->{OPTIONS}};
|
||||
my $output = \${$self->{OUTPUT}};
|
||||
my $allowed_kind = \%{$self->{ALLOWED_KIND}};
|
||||
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
|
||||
my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
|
||||
|
@ -85,11 +87,11 @@ sub parse_api_file {
|
|||
my $extension = 0;
|
||||
my $forbidden = 0;
|
||||
|
||||
if($$options->progress) {
|
||||
$$output->progress("$file");
|
||||
if($options->progress) {
|
||||
$output->progress("$file");
|
||||
}
|
||||
|
||||
open(IN, "< $file") || die "$file: $!\n";
|
||||
open(IN, "< $wine_dir/$file") || die "$wine_dir/$file: $!\n";
|
||||
$/ = "\n";
|
||||
while(<IN>) {
|
||||
s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
|
||||
|
@ -143,12 +145,12 @@ sub parse_api_file {
|
|||
if(!$forbidden) {
|
||||
if(defined($module)) {
|
||||
if($$allowed_modules_unlimited{$type}) {
|
||||
$$output->write("$file: type ($type) already specificed as an unlimited type\n");
|
||||
$output->write("$file: type ($type) already specificed as an unlimited type\n");
|
||||
} elsif(!$$allowed_modules{$type}{$module}) {
|
||||
$$allowed_modules{$type}{$module} = 1;
|
||||
$$allowed_modules_limited{$type} = 1;
|
||||
} else {
|
||||
$$output->write("$file: type ($type) already specificed\n");
|
||||
$output->write("$file: type ($type) already specificed\n");
|
||||
}
|
||||
} else {
|
||||
$$allowed_modules_unlimited{$type} = 1;
|
||||
|
@ -157,14 +159,14 @@ sub parse_api_file {
|
|||
$$allowed_modules_limited{$type} = 1;
|
||||
}
|
||||
if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
|
||||
$$output->write("$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n");
|
||||
$output->write("$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n");
|
||||
} else {
|
||||
$$translate_argument{$type} = $kind;
|
||||
}
|
||||
|
||||
$$type_format{$module}{$type} = $format;
|
||||
} else {
|
||||
$$output->write("$file: file must begin with %<type> statement\n");
|
||||
$output->write("$file: file must begin with %<type> statement\n");
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
@ -201,16 +203,10 @@ sub read_spec_files {
|
|||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
|
||||
my $modules = shift;
|
||||
my $wine_dir = shift;
|
||||
my $current_dir = shift;
|
||||
my $files = shift;
|
||||
my $win16api = shift;
|
||||
my $win32api = shift;
|
||||
|
||||
foreach my $file (@$files) {
|
||||
(my $type, my $module) = 'winapi'->get_spec_file_type("$wine_dir/$file");
|
||||
$modules->spec_file_module($file, $module);
|
||||
if($type eq "win16") {
|
||||
$win16api->parse_spec_file("$wine_dir/$file");
|
||||
} elsif($type eq "win32") {
|
||||
|
@ -246,34 +242,9 @@ sub read_spec_files {
|
|||
}
|
||||
}
|
||||
|
||||
sub read_all_spec_files {
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
|
||||
my $modules = shift;
|
||||
my $wine_dir = shift;
|
||||
my $current_dir = shift;
|
||||
my $file_type = shift;
|
||||
my $win16api = shift;
|
||||
my $win32api = shift;
|
||||
|
||||
my @files = map {
|
||||
s%^$wine_dir/%%;
|
||||
if(&$file_type($_) eq "winelib") {
|
||||
$_;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
} split(/\n/, `find $wine_dir -name \\*.spec`);
|
||||
|
||||
'winapi'->read_spec_files($modules, $wine_dir, $current_dir, \@files, $win16api, $win32api);
|
||||
}
|
||||
|
||||
sub parse_spec_file {
|
||||
my $self = shift;
|
||||
|
||||
my $options = \${$self->{OPTIONS}};
|
||||
my $output = \${$self->{OUTPUT}};
|
||||
my $function_internal_arguments = \%{$self->{FUNCTION_INTERNAL_ARGUMENTS}};
|
||||
my $function_external_arguments = \%{$self->{FUNCTION_EXTERNAL_ARGUMENTS}};
|
||||
my $function_internal_ordinal = \%{$self->{FUNCTION_INTERNAL_ORDINAL}};
|
||||
|
@ -297,8 +268,8 @@ sub parse_spec_file {
|
|||
my $module;
|
||||
my $module_file;
|
||||
|
||||
if($$options->progress) {
|
||||
$$output->lazy_progress("$file");
|
||||
if($options->progress) {
|
||||
$output->lazy_progress("$file");
|
||||
}
|
||||
|
||||
open(IN, "< $file") || die "$file: $!\n";
|
||||
|
@ -366,10 +337,10 @@ sub parse_spec_file {
|
|||
$$function_external_module{$external_name} .= " & $module";
|
||||
}
|
||||
|
||||
if(0 && $$options->spec_mismatch) {
|
||||
if(0 && $options->spec_mismatch) {
|
||||
if($external_name eq "@") {
|
||||
if($internal_name !~ /^\U$module\E_$ordinal$/) {
|
||||
$$output->write("$file: $external_name: the internal name ($internal_name) mismatch\n");
|
||||
$output->write("$file: $external_name: the internal name ($internal_name) mismatch\n");
|
||||
}
|
||||
} else {
|
||||
my $name = $external_name;
|
||||
|
@ -393,7 +364,7 @@ sub parse_spec_file {
|
|||
if(uc($internal_name) ne uc($external_name) &&
|
||||
$internal_name !~ /(\Q$name\E|\Q$name1\E|\Q$name2\E|\Q$name3\E|\Q$name4\E|\Q$name5\E)/)
|
||||
{
|
||||
$$output->write("$file: $external_name: internal name ($internal_name) mismatch\n");
|
||||
$output->write("$file: $external_name: internal name ($internal_name) mismatch\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -466,7 +437,7 @@ sub parse_spec_file {
|
|||
|
||||
if(defined($ordinal)) {
|
||||
if($ordinal ne "@" && $ordinals{$ordinal}) {
|
||||
$$output->write("$file: ordinal redefined: $_\n");
|
||||
$output->write("$file: ordinal redefined: $_\n");
|
||||
}
|
||||
$ordinals{$ordinal}++;
|
||||
}
|
||||
|
@ -556,7 +527,6 @@ sub types_not_used {
|
|||
sub types_unlimited_used_in_modules {
|
||||
my $self = shift;
|
||||
|
||||
my $output = \${$self->{OUTPUT}};
|
||||
my $used_modules = \%{$self->{USED_MODULES}};
|
||||
my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
|
||||
my $allowed_modules_unlimited = \%{$self->{ALLOWED_MODULES_UNLIMITED}};
|
||||
|
|
|
@ -20,38 +20,25 @@ BEGIN {
|
|||
}
|
||||
|
||||
use config qw(
|
||||
&file_type &files_filter &files_skip
|
||||
&get_h_files
|
||||
$current_dir $wine_dir $winapi_dir $winapi_check_dir
|
||||
&files_filter &files_skip
|
||||
&get_h_files
|
||||
$current_dir $wine_dir
|
||||
);
|
||||
use modules;
|
||||
use nativeapi;
|
||||
use output qw($output);
|
||||
use winapi_check_options qw($options);
|
||||
use modules qw($modules);
|
||||
use nativeapi qw($nativeapi);
|
||||
use winapi qw($win16api $win32api @winapis);
|
||||
|
||||
use preprocessor;
|
||||
use type;
|
||||
use util qw(&is_subset);
|
||||
use winapi;
|
||||
use winapi_documentation;
|
||||
use winapi_function;
|
||||
use winapi_local;
|
||||
use winapi_global;
|
||||
use winapi_check_options qw($options);
|
||||
use winapi_parser;
|
||||
|
||||
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($options->global) {
|
||||
'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 %declared_functions;
|
||||
|
||||
my %include2info;
|
||||
|
@ -125,6 +112,10 @@ if($options->headers) {
|
|||
$output->progress("$file: file $progress_current of $progress_max");
|
||||
}
|
||||
|
||||
my $create_function = sub {
|
||||
return 'winapi_function'->new;
|
||||
};
|
||||
|
||||
my $found_function = sub {
|
||||
my $function = shift;
|
||||
|
||||
|
@ -156,6 +147,15 @@ if($options->headers) {
|
|||
$output->write("duplicate declaration (first declaration at $file:$function_line)\n");
|
||||
}
|
||||
}
|
||||
$output->prefix("");
|
||||
};
|
||||
|
||||
my $create_type = sub {
|
||||
return 'type'->new;
|
||||
};
|
||||
|
||||
my $found_type = sub {
|
||||
my $type = shift;
|
||||
};
|
||||
|
||||
my $found_preprocessor = sub {
|
||||
|
@ -163,7 +163,7 @@ if($options->headers) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,6 +188,10 @@ foreach my $file (@c_files) {
|
|||
if(!($file_dir =~ s/(.*?)\/[^\/]*$/$1/)) {
|
||||
$file_dir = ".";
|
||||
}
|
||||
|
||||
my $create_function = sub {
|
||||
return 'winapi_function'->new;
|
||||
};
|
||||
|
||||
my $found_function = sub {
|
||||
my $function = shift;
|
||||
|
@ -273,19 +277,19 @@ foreach my $file (@c_files) {
|
|||
}
|
||||
}
|
||||
|
||||
if($options->local && $options->argument) {
|
||||
if($options->local && $options->argument && defined($statements)) {
|
||||
&winapi_local::check_function($function);
|
||||
}
|
||||
|
||||
if($options->local && $options->statements) {
|
||||
if($options->local && $options->statements && defined($statements)) {
|
||||
&winapi_local::check_statements(\%functions, $function);
|
||||
}
|
||||
|
||||
if($options->local && $options->documentation &&
|
||||
(defined($module16) || defined($module32)) &&
|
||||
$linkage ne "static" && ($linkage ne "" || defined($statements)))
|
||||
$linkage eq "" && defined($statements))
|
||||
{
|
||||
&winapi_documentation::check_documentation($function);
|
||||
# &winapi_documentation::check_documentation($function);
|
||||
}
|
||||
|
||||
if(1) {
|
||||
|
@ -386,6 +390,15 @@ foreach my $file (@c_files) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
my $create_type = sub {
|
||||
return 'type'->new;
|
||||
};
|
||||
|
||||
my $found_type = sub {
|
||||
my $type = shift;
|
||||
};
|
||||
|
||||
my $preprocessor = 'preprocessor'->new($found_include, $found_conditional);
|
||||
my $found_preprocessor = sub {
|
||||
my $directive = shift;
|
||||
|
@ -511,7 +524,7 @@ foreach my $file (@c_files) {
|
|||
}
|
||||
};
|
||||
|
||||
&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);
|
||||
|
||||
if($options->config_unnessary) {
|
||||
if($config && $conditional == 0) {
|
||||
|
@ -522,74 +535,69 @@ foreach my $file (@c_files) {
|
|||
&winapi_local::check_file($file, \%functions);
|
||||
}
|
||||
|
||||
$output->hide_progress;
|
||||
if($options->global) {
|
||||
my @complete_modules = $modules->complete_modules(\@c_files);
|
||||
my %complete_module;
|
||||
|
||||
if($options->declared) {
|
||||
my %dirs;
|
||||
foreach my $file (@c_files) {
|
||||
my $dir = $file;
|
||||
$dir =~ s%/?[^/]*$%%;
|
||||
if($dir) {
|
||||
if($current_dir ne ".") {
|
||||
$dir = "$current_dir/$dir";
|
||||
}
|
||||
} else {
|
||||
$dir = "$current_dir";
|
||||
}
|
||||
$dirs{$dir}++;
|
||||
foreach my $module (@complete_modules) {
|
||||
$complete_module{$module}++;
|
||||
}
|
||||
|
||||
foreach my $module ($modules->all_modules) {
|
||||
my $incomplete = 0;
|
||||
foreach my $module_dir ($modules->allowed_dirs_for_module($module)) {
|
||||
my $found = 0;
|
||||
foreach my $dir (sort(keys(%dirs))) {
|
||||
if($module_dir eq $dir) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if(!$found) {
|
||||
$incomplete = 1;
|
||||
}
|
||||
}
|
||||
if(!$incomplete) {
|
||||
if($options->declared) {
|
||||
foreach my $winapi (@winapis) {
|
||||
if(!$winapi->is_module($module)) { next; }
|
||||
my $functions = $module2functions{$module};
|
||||
foreach my $internal_name ($winapi->all_internal_functions_in_module($module)) {
|
||||
my $function = $functions->{$internal_name};
|
||||
if(!defined($function) && !$nativeapi->is_function($internal_name) &&
|
||||
!($module eq "user" && $internal_name =~
|
||||
/^(?:GlobalAddAtomA|GlobalDeleteAtom|GlobalFindAtomA|
|
||||
GlobalGetAtomNameA|lstrcmpiA)$/x))
|
||||
{
|
||||
$output->write("*.c: $module: $internal_name: " .
|
||||
"function declared but not implemented or declared external\n");
|
||||
}
|
||||
if($options->declared) {
|
||||
foreach my $module (@complete_modules) {
|
||||
foreach my $winapi (@winapis) {
|
||||
if(!$winapi->is_module($module)) { next; }
|
||||
my $functions = $module2functions{$module};
|
||||
foreach my $internal_name ($winapi->all_internal_functions_in_module($module)) {
|
||||
my $function = $functions->{$internal_name};
|
||||
if(!defined($function) && !$nativeapi->is_function($internal_name) &&
|
||||
!($module eq "user" && $internal_name =~
|
||||
/^(?:GlobalAddAtomA|GlobalDeleteAtom|GlobalFindAtomA|
|
||||
GlobalGetAtomNameA|lstrcmpiA)$/x))
|
||||
{
|
||||
$output->write("*.c: $module: $internal_name: " .
|
||||
"function declared but not implemented or declared external\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($options->global) {
|
||||
&winapi_documentation::report_documentation;
|
||||
|
||||
if($options->headers_unused) {
|
||||
foreach my $name (sort(keys(%include2info))) {
|
||||
if(!$include2info{$name}{used}) {
|
||||
if($options->include) {
|
||||
$output->write("*.c: $name: include file is never used\n");
|
||||
if($options->argument && $options->argument_forbidden) {
|
||||
foreach my $winapi (@winapis) {
|
||||
my $types_not_used = $winapi->types_not_used;
|
||||
foreach my $module (sort(keys(%$types_not_used))) {
|
||||
if(!$complete_module{$module}) { next; }
|
||||
foreach my $type (sort(keys(%{$$types_not_used{$module}}))) {
|
||||
$output->write("*.c: $module: type ($type) not used\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&winapi_global::check(\%type_found);
|
||||
my $all_modules = 1;
|
||||
foreach my $module ($modules->all_modules) {
|
||||
if(!$complete_module{$module}) {
|
||||
$all_modules = 0;
|
||||
}
|
||||
}
|
||||
if($all_modules) {
|
||||
&winapi_documentation::report_documentation;
|
||||
|
||||
if($options->headers_unused) {
|
||||
foreach my $name (sort(keys(%include2info))) {
|
||||
if(!$include2info{$name}{used}) {
|
||||
if($options->include) {
|
||||
$output->write("*.c: $name: include file is never used\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&winapi_global::check(\%type_found);
|
||||
|
||||
$modules->global_report;
|
||||
$nativeapi->global_report;
|
||||
$modules->global_report;
|
||||
$nativeapi->global_report;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,14 +35,6 @@ sub _check {
|
|||
}
|
||||
|
||||
if($options->argument && $options->argument_forbidden) {
|
||||
my $not_used = $winapi->types_not_used;
|
||||
|
||||
foreach my $module (sort(keys(%$not_used))) {
|
||||
foreach my $type (sort(keys(%{$$not_used{$module}}))) {
|
||||
$output->write("*.c: $module: type ($type) not used\n");
|
||||
}
|
||||
}
|
||||
|
||||
my $types_used = $winapi->types_unlimited_used_in_modules;
|
||||
|
||||
foreach my $type (sort(keys(%$types_used))) {
|
||||
|
|
|
@ -3,93 +3,131 @@ package winapi_parser;
|
|||
use strict;
|
||||
|
||||
use output qw($output);
|
||||
use winapi_function;
|
||||
use options qw($options);
|
||||
|
||||
sub parse_c_file {
|
||||
my $options = shift;
|
||||
my $file = shift;
|
||||
my $function_create_callback = shift;
|
||||
my $function_found_callback = shift;
|
||||
my $type_create_callback = shift;
|
||||
my $type_found_callback = shift;
|
||||
my $preprocessor_found_callback = shift;
|
||||
|
||||
# global
|
||||
my $debug_channels = [];
|
||||
|
||||
# local
|
||||
my $documentation_line;
|
||||
my $documentation;
|
||||
my $function_line;
|
||||
my $linkage;
|
||||
my $return_type;
|
||||
my $calling_convention;
|
||||
my $internal_name = "";
|
||||
my $argument_types;
|
||||
my $argument_names;
|
||||
my $argument_documentations;
|
||||
my $statements;
|
||||
|
||||
my $function_begin = sub {
|
||||
$documentation_line = shift;
|
||||
$documentation = shift;
|
||||
$function_line = shift;
|
||||
$linkage = shift;
|
||||
$return_type= shift;
|
||||
$calling_convention = shift;
|
||||
$internal_name = shift;
|
||||
$argument_types = shift;
|
||||
$argument_names = shift;
|
||||
$argument_documentations = shift;
|
||||
|
||||
if(defined($argument_names) && defined($argument_types) &&
|
||||
$#$argument_names == -1)
|
||||
{
|
||||
foreach my $n (0..$#$argument_types) {
|
||||
push @$argument_names, "";
|
||||
my $in_function = 0;
|
||||
my $function_begin;
|
||||
my $function_end;
|
||||
{
|
||||
my $documentation_line;
|
||||
my $documentation;
|
||||
my $function_line;
|
||||
my $linkage;
|
||||
my $return_type;
|
||||
my $calling_convention;
|
||||
my $internal_name = "";
|
||||
my $argument_types;
|
||||
my $argument_names;
|
||||
my $argument_documentations;
|
||||
my $statements;
|
||||
|
||||
$function_begin = sub {
|
||||
$documentation_line = shift;
|
||||
$documentation = shift;
|
||||
$function_line = shift;
|
||||
$linkage = shift;
|
||||
$return_type= shift;
|
||||
$calling_convention = shift;
|
||||
$internal_name = shift;
|
||||
$argument_types = shift;
|
||||
$argument_names = shift;
|
||||
$argument_documentations = shift;
|
||||
|
||||
if(defined($argument_names) && defined($argument_types) &&
|
||||
$#$argument_names == -1)
|
||||
{
|
||||
foreach my $n (0..$#$argument_types) {
|
||||
push @$argument_names, "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(defined($argument_documentations) &&
|
||||
$#$argument_documentations == -1)
|
||||
{
|
||||
foreach my $n (0..$#$argument_documentations) {
|
||||
push @$argument_documentations, "";
|
||||
|
||||
if(defined($argument_documentations) &&
|
||||
$#$argument_documentations == -1)
|
||||
{
|
||||
foreach my $n (0..$#$argument_documentations) {
|
||||
push @$argument_documentations, "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$in_function = 1;
|
||||
};
|
||||
|
||||
$statements = undef;
|
||||
};
|
||||
my $function_end = sub {
|
||||
my $function = 'winapi_function'->new;
|
||||
$function_end = sub {
|
||||
$statements = shift;
|
||||
|
||||
if(!defined($documentation_line)) {
|
||||
$documentation_line = 0;
|
||||
}
|
||||
my $function = &$function_create_callback();
|
||||
|
||||
if(!defined($documentation_line)) {
|
||||
$documentation_line = 0;
|
||||
}
|
||||
|
||||
$function->file($file);
|
||||
$function->debug_channels([@$debug_channels]);
|
||||
$function->documentation_line($documentation_line);
|
||||
$function->documentation($documentation);
|
||||
$function->function_line($function_line);
|
||||
$function->linkage($linkage);
|
||||
$function->return_type($return_type);
|
||||
$function->calling_convention($calling_convention);
|
||||
$function->internal_name($internal_name);
|
||||
if(defined($argument_types)) {
|
||||
$function->argument_types([@$argument_types]);
|
||||
}
|
||||
if(defined($argument_names)) {
|
||||
$function->argument_names([@$argument_names]);
|
||||
}
|
||||
if(defined($argument_documentations)) {
|
||||
$function->argument_documentations([@$argument_documentations]);
|
||||
}
|
||||
$function->statements($statements);
|
||||
|
||||
&$function_found_callback($function);
|
||||
|
||||
$function->file($file);
|
||||
$function->debug_channels([@$debug_channels]);
|
||||
$function->documentation_line($documentation_line);
|
||||
$function->documentation($documentation);
|
||||
$function->function_line($function_line);
|
||||
$function->linkage($linkage);
|
||||
$function->return_type($return_type);
|
||||
$function->calling_convention($calling_convention);
|
||||
$function->internal_name($internal_name);
|
||||
if(defined($argument_types)) {
|
||||
$function->argument_types([@$argument_types]);
|
||||
}
|
||||
if(defined($argument_names)) {
|
||||
$function->argument_names([@$argument_names]);
|
||||
}
|
||||
if(defined($argument_documentations)) {
|
||||
$function->argument_documentations([@$argument_documentations]);
|
||||
}
|
||||
$function->statements($statements);
|
||||
$in_function = 0;
|
||||
};
|
||||
}
|
||||
|
||||
my $in_type = 0;
|
||||
my $type_begin;
|
||||
my $type_end;
|
||||
{
|
||||
my $type;
|
||||
|
||||
$type_begin = sub {
|
||||
$type = shift;
|
||||
$in_type = 1;
|
||||
};
|
||||
|
||||
$type_end = sub {
|
||||
my $names = shift;
|
||||
|
||||
foreach my $name (@$names) {
|
||||
if($type =~ /^(?:struct|enum)/) {
|
||||
# $output->write("typedef $type {\n");
|
||||
# $output->write("} $name;\n");
|
||||
} else {
|
||||
# $output->write("typedef $type $name;\n");
|
||||
}
|
||||
}
|
||||
$in_type = 0;
|
||||
};
|
||||
}
|
||||
|
||||
&$function_found_callback($function);
|
||||
$internal_name = "";
|
||||
};
|
||||
my %regs_entrypoints;
|
||||
my @comment_lines = ();
|
||||
my @comments = ();
|
||||
my $statements;
|
||||
my $level = 0;
|
||||
my $extern_c = 0;
|
||||
my $again = 0;
|
||||
|
@ -263,8 +301,20 @@ sub parse_c_file {
|
|||
$statements .= "$line\n";
|
||||
}
|
||||
|
||||
if($internal_name && $level == 0) {
|
||||
&$function_end;
|
||||
if($level == 0) {
|
||||
if($in_function) {
|
||||
&$function_end($statements);
|
||||
$statements = undef;
|
||||
} elsif($in_type) {
|
||||
if(/^\s*(?:WINE_PACKED\s+)?((?:\*\s*)?\w+\s*(?:\s*,\s*(?:\*+\s*)?\w+)*\s*);/s) {
|
||||
my @parts = split(/\s*,\s*/, $1);
|
||||
&$type_end([@parts]);
|
||||
} elsif(/;/s) {
|
||||
die "$file: $.: syntax error: '$_'\n";
|
||||
} else {
|
||||
$lookahead = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
next;
|
||||
} elsif(/(extern\s+|static\s+)?((struct\s+|union\s+|enum\s+|signed\s+|unsigned\s+)?\w+((\s*\*)+\s*|\s+))
|
||||
|
@ -358,7 +408,8 @@ sub parse_c_file {
|
|||
$function_line, $linkage, $return_type, $calling_convention, $name,
|
||||
\@argument_types,\@argument_names,\@argument_documentations);
|
||||
if($level == 0) {
|
||||
&$function_end;
|
||||
&$function_end($statements);
|
||||
$statements = undef;
|
||||
}
|
||||
} elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
|
@ -368,95 +419,20 @@ sub parse_c_file {
|
|||
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "void", "__asm", $1);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
} elsif(/DC_(GET_X_Y_16|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s){
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
||||
$_ = $'; $again = 1;
|
||||
|
||||
my $return16 = $2 . "16";
|
||||
my $name16 = $3 . "16";
|
||||
|
||||
$return16 =~ s/^(COLORREF|DWORD)16$/$1/;
|
||||
|
||||
my @arguments = ("HDC16");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", $return16, "WINAPI", $name16, \@arguments);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
} elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
||||
$_ = $'; $again = 1;
|
||||
|
||||
my $return32 = $2;
|
||||
my $name32 = $3;
|
||||
my @arguments32 = ("HDC");
|
||||
|
||||
&$function_end;
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", $return32, "WINAPI", $name32, \@arguments32);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
} elsif(/DC_(GET_VAL_EX_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
||||
$_ = $'; $again = 1;
|
||||
|
||||
my @arguments16 = ("HDC16", "LP" . $5 . "16");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "BOOL16", "WINAPI", $2 . "16", \@arguments16);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
} elsif(/DC_(GET_VAL_EX_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
||||
$_ = $'; $again = 1;
|
||||
|
||||
my @arguments32 = ("HDC", "LP" . $5);
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "BOOL", "WINAPI", $2, \@arguments32);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
} elsif(/DC_(SET_MODE_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
||||
$_ = $'; $again = 1;
|
||||
|
||||
my @arguments16 = ("HDC16", "INT16");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "INT16", "WINAPI", $2 . "16", \@arguments16);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
} elsif(/DC_(SET_MODE_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
||||
$_ = $'; $again = 1;
|
||||
|
||||
my @arguments32 = ("HDC", "INT");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "INT", "WINAPI", $2, \@arguments32);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
} elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
||||
$_ = $'; $again = 1;
|
||||
my @arguments16 = ("HWAVEIN16");
|
||||
my @arguments32 = ("HWAVEIN");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "UINT", "WINAPI", "waveIn" . $1, \@arguments32);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
@ -467,11 +443,10 @@ sub parse_c_file {
|
|||
my @arguments32 = ("HWAVEOUT");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "UINT", "WINAPI", "waveOut" . $1, \@arguments32);
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
} elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
|
||||
my @lines = split(/\n/, $&);
|
||||
my $function_line = $. - scalar(@lines) + 1;
|
||||
|
@ -483,21 +458,19 @@ sub parse_c_file {
|
|||
my @arguments32 = ("HWAVEOUT", $4);
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
} elsif($1 eq 2) {
|
||||
my @arguments16 = ("UINT16", $4);
|
||||
my @arguments32 = ("UINT", $4);
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
|
||||
$statements = "";
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
&$function_begin($documentation_line, $documentation,
|
||||
$function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
|
||||
&$function_end;
|
||||
&$function_end("");
|
||||
}
|
||||
} elsif(/DEFINE_REGS_ENTRYPOINT_\d+\(\s*(\S*)\s*,\s*([^\s,\)]*).*?\)/s) {
|
||||
$_ = $'; $again = 1;
|
||||
|
@ -508,6 +481,74 @@ sub parse_c_file {
|
|||
} elsif(/(DEFAULT|DECLARE)_DEBUG_CHANNEL\s*\((\S+)\)/s) {
|
||||
$_ = $'; $again = 1;
|
||||
push @$debug_channels, $1;
|
||||
} elsif(/typedef\s+(enum|struct|union)(?:\s+(\w+))?\s*\{/s) {
|
||||
$_ = $'; $again = 1;
|
||||
$level++;
|
||||
my $type = $1;
|
||||
if(defined($2)) {
|
||||
$type .= " $2";
|
||||
}
|
||||
&$type_begin($type);
|
||||
} elsif(/typedef\s+
|
||||
((?:const\s+|enum\s+|long\s+|signed\s+|short\s+|struct\s+|union\s+|unsigned\s+)*?)
|
||||
(\w+)
|
||||
(?:\s+const)?
|
||||
((?:\s*\*+\s*|\s+)\w+\s*(?:\[[^\]]*\])?
|
||||
(?:\s*,\s*(?:\s*\*+\s*|\s+)\w+\s*(?:\[[^\]]*\])?)*)
|
||||
\s*;/sx)
|
||||
{
|
||||
$_ = $'; $again = 1;
|
||||
|
||||
my $type = "$1 $2";
|
||||
|
||||
my @names;
|
||||
my @parts = split(/\s*,\s*/, $2);
|
||||
foreach my $part (@parts) {
|
||||
if($part =~ /(?:\s*(\*+)\s*|\s+)(\w+)\s*(\[[^\]]*\])?/) {
|
||||
my $name = $2;
|
||||
if(defined($1)) {
|
||||
$name = "$1$2";
|
||||
}
|
||||
if(defined($3)) {
|
||||
$name .= $3;
|
||||
}
|
||||
push @names, $name;
|
||||
}
|
||||
}
|
||||
&$type_begin($type);
|
||||
&$type_end([@names]);
|
||||
} elsif(/typedef\s+
|
||||
(?:(?:const\s+|enum\s+|long\s+|signed\s+|short\s+|struct\s+|union\s+|unsigned\s+)*?)
|
||||
(\w+)\s+
|
||||
(?:(\w+)\s*)?
|
||||
\((?:(\w+)\s+)?\s*\*\s*(\w+)\s*\)\s*
|
||||
(?:\(([^\)]*)\)|\[([^\]]*)\])\s*;/sx)
|
||||
{
|
||||
$_ = $'; $again = 1;
|
||||
my $type;
|
||||
if(defined($2) || defined($3)) {
|
||||
my $cc = $2 || $3;
|
||||
if(defined($5)) {
|
||||
$type = "$1 ($cc *)($5)";
|
||||
} else {
|
||||
$type = "$1 ($cc *)[$6]";
|
||||
}
|
||||
} else {
|
||||
if(defined($5)) {
|
||||
$type = "$1 (*)($5)";
|
||||
} else {
|
||||
$type = "$1 (*)[$6]";
|
||||
}
|
||||
}
|
||||
my $name = $4;
|
||||
&$type_begin($type);
|
||||
&$type_end([$name]);
|
||||
} elsif(/typedef[^\{;]*;/s) {
|
||||
$_ = $'; $again = 1;
|
||||
$output->write("$file: $.: can't parse: '$&'\n");
|
||||
} elsif(/typedef[^\{]*\{[^\}]*\}[^;];/s) {
|
||||
$_ = $'; $again = 1;
|
||||
$output->write("$file: $.: can't parse: '$&'\n");
|
||||
} elsif(/\'[^\']*\'/s) {
|
||||
$_ = $'; $again = 1;
|
||||
} elsif(/\"[^\"]*\"/s) {
|
||||
|
|
Loading…
Reference in New Issue