From 1c61b3babcdd4a18c1a1eb861fa582cb01e2ea9b Mon Sep 17 00:00:00 2001 From: Patrik Stridvall Date: Mon, 23 Jul 2001 23:20:56 +0000 Subject: [PATCH] Yet another major reorganization and a few new features. --- tools/winapi/config.pm | 2 +- tools/winapi/options.pm | 30 +--- tools/winapi/output.pm | 46 ++++-- tools/winapi/winapi_check_options.pm | 177 +++++++++++++++++++++ tools/winapi/winapi_extract | 53 ++---- tools/winapi/winapi_extract_options.pm | 42 +++++ tools/winapi/winapi_fixup | 106 +++++------- tools/winapi/winapi_fixup_options.pm | 48 ++++++ tools/winapi_check/winapi_check | 126 ++++++++------- tools/winapi_check/winapi_documentation.pm | 29 ++-- tools/winapi_check/winapi_function.pm | 34 +++- tools/winapi_check/winapi_global.pm | 22 ++- tools/winapi_check/winapi_local.pm | 61 ++++++- tools/winapi_check/winapi_options.pm | 29 ++-- tools/winapi_check/winapi_parser.pm | 113 +++++++++---- 15 files changed, 649 insertions(+), 269 deletions(-) create mode 100644 tools/winapi/winapi_check_options.pm create mode 100644 tools/winapi/winapi_extract_options.pm create mode 100644 tools/winapi/winapi_fixup_options.pm diff --git a/tools/winapi/config.pm b/tools/winapi/config.pm index 6e7aa8e1498..852ef8b8214 100644 --- a/tools/winapi/config.pm +++ b/tools/winapi/config.pm @@ -20,7 +20,7 @@ require Exporter; use vars qw($current_dir $wine_dir $winapi_dir $winapi_check_dir); -my $output = "output"; +use output qw($output); sub file_type { local $_ = shift; diff --git a/tools/winapi/options.pm b/tools/winapi/options.pm index 95eb23566fe..6ff005fd90d 100644 --- a/tools/winapi/options.pm +++ b/tools/winapi/options.pm @@ -6,10 +6,10 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); require Exporter; @ISA = qw(Exporter); -@EXPORT = qw(&parse_comma_list); -@EXPORT_OK = qw(); +@EXPORT = qw(); +@EXPORT_OK = qw($options &parse_comma_list); -my $output = "output"; +use vars qw($options); sub parse_comma_list { my $prefix = shift; @@ -27,27 +27,13 @@ sub parse_comma_list { } } -my $_options; - -sub new { - my $self = shift; - $_options = _options->new(@_); - return $_options; -} - -sub AUTOLOAD { - my $self = shift; - - my $name = $options::AUTOLOAD; - $name =~ s/^.*::(.[^:]*)$/$1/; - - return $_options->$name(@_); -} - package _options; use strict; +use config qw($current_dir $wine_dir); +use output qw($output); + sub new { my $proto = shift; my $class = ref($proto) || $proto; @@ -209,8 +195,8 @@ sub new { } split(/\n/, `$c_command`)); } - if($#h_files != -1) { - my $h_command = "find " . join(" ", @h_files) . " -name \\*.h"; + if($#paths != -1 || $#h_files != -1) { + my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h"; my %found; @$h_files = sort(map { diff --git a/tools/winapi/output.pm b/tools/winapi/output.pm index 1b461728d4f..7c9bf0d427c 100644 --- a/tools/winapi/output.pm +++ b/tools/winapi/output.pm @@ -2,22 +2,16 @@ package output; use strict; -my $_output; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); +require Exporter; -sub new { - my $self = shift; - $_output = _output->new(@_); - return $_output; -} +@ISA = qw(Exporter); +@EXPORT = qw(); +@EXPORT_OK = qw($output); -sub AUTOLOAD { - my $self = shift; +use vars qw($output); - my $name = $output::AUTOLOAD; - $name =~ s/^.*::(.[^:]*)$/$1/; - - return $_output->$name(@_); -} +$output = '_output'->new; package _output; @@ -37,17 +31,18 @@ sub new { my $last_time = \${$self->{LAST_TIME}}; my $progress_count = \${$self->{PROGRESS_COUNT}}; my $prefix = \${$self->{PREFIX}}; + my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; $$progress = ""; $$last_progress = ""; $$last_time = 0; $$progress_count = 0; - $$prefix = ""; + $$prefix = undef; + $$prefix_callback = undef; return $self; } - sub show_progress { my $self = shift; my $progress = \${$self->{PROGRESS}}; @@ -134,8 +129,20 @@ sub lazy_progress { sub prefix { my $self = shift; my $prefix = \${$self->{PREFIX}}; + my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; $$prefix = shift; + $$prefix_callback = undef; +} + +sub prefix_callback { + my $self = shift; + + my $prefix = \${$self->{PREFIX}}; + my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; + + $$prefix = undef; + $$prefix_callback = shift; } sub write { @@ -144,9 +151,16 @@ sub write { my $message = shift; my $prefix = \${$self->{PREFIX}}; + my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; $self->hide_progress if $stdout_isatty; - print $$prefix . $message; + if(defined($$prefix)) { + print $$prefix . $message; + } elsif(defined($$prefix_callback)) { + print &{$$prefix_callback}() . $message; + } else { + print $message; + } $self->show_progress if $stdout_isatty; } diff --git a/tools/winapi/winapi_check_options.pm b/tools/winapi/winapi_check_options.pm new file mode 100644 index 00000000000..22d5e8a466f --- /dev/null +++ b/tools/winapi/winapi_check_options.pm @@ -0,0 +1,177 @@ +package winapi_check_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 config qw($current_dir $wine_dir); +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" }, + + "win16" => { default => 1, description => "Win16 checking" }, + "win32" => { default => 1, description => "Win32 checking" }, + + "shared" => { default => 0, description => "show shared functions between Win16 and Win32" }, + "shared-segmented" => { default => 0, description => "segmented shared functions between Win16 and Win32 checking" }, + + "config" => { default => 1, parent => "local", description => "check configuration include consistancy" }, + "config-unnessary" => { default => 0, parent => "config", description => "check for unnessary #include \"config.h\"" }, + + "spec-mismatch" => { default => 0, description => "spec file mismatch checking" }, + + "local" => { default => 1, description => "local checking" }, + "module" => { + default => { active => 1, filter => 0, hash => {} }, + parent => "local", + parser => \&parser_comma_list, + description => "module filter" + }, + + "argument" => { default => 1, parent => "local", description => "argument checking" }, + "argument-count" => { default => 1, parent => "argument", description => "argument count checking" }, + "argument-forbidden" => { + default => { active => 1, filter => 0, hash => {} }, + parent => "argument", + parser => \&parser_comma_list, + description => "argument forbidden checking" + }, + "argument-kind" => { + default => { active => 1, filter => 1, hash => { double => 1 } }, + parent => "argument", + parser => \&parser_comma_list, + description => "argument kind checking" + }, + "calling-convention" => { default => 1, parent => "local", description => "calling convention checking" }, + "calling-convention-win16" => { default => 0, parent => "calling-convention", description => "calling convention checking (Win16)" }, + "calling-convention-win32" => { default => 1, parent => "calling-convention", description => "calling convention checking (Win32)" }, + "misplaced" => { default => 1, parent => "local", description => "check for misplaced functions" }, + "statements" => { default => 0, parent => "local", description => "check for statements inconsistances" }, + "cross-call" => { default => 0, parent => "statements", description => "check for cross calling functions" }, + "cross-call-win32-win16" => { + default => 0, parent => "cross-call", description => "check for cross calls between win32 and win16" + }, + "cross-call-unicode-ascii" => { + default => 0, parent => "cross-call", description => "check for cross calls between Unicode and ASCII" + }, + "debug-messages" => { default => 0, parent => "statements", description => "check for debug messages inconsistances" }, + + "documentation" => { + default => 1, + parent => "local", + description => "check for documentation inconsistances" + }, + "documentation-pedantic" => { + default => 0, + parent => "documentation", + description => "be pendantic when checking for documentation inconsistances" + }, + + "documentation-arguments" => { + default => 1, + parent => "documentation", + description => "check for arguments documentation inconsistances\n" + }, + "documentation-comment-indent" => { + default => 0, + parent => "documentation", description => "check for documentation comment indent inconsistances" + }, + "documentation-comment-width" => { + default => 0, + parent => "documentation", description => "check for documentation comment width inconsistances" + }, + "documentation-name" => { + default => 1, + parent => "documentation", + description => "check for documentation name inconsistances\n" + }, + "documentation-ordinal" => { + default => 1, + parent => "documentation", + description => "check for documentation ordinal inconsistances\n" + }, + "documentation-wrong" => { + default => 1, + parent => "documentation", + description => "check for wrong documentation\n" + }, + + "prototype" => {default => 0, parent => ["local", "headers"], description => "prototype checking" }, + "global" => { default => 1, description => "global checking" }, + "declared" => { default => 1, parent => "global", description => "declared checking" }, + "implemented" => { default => 0, parent => "local", description => "implemented checking" }, + "implemented-win32" => { default => 0, parent => "implemented", description => "implemented as win32 checking" }, + "include" => { default => 1, parent => "global", description => "include checking" }, + + "headers" => { default => 0, description => "headers checking" }, + "headers-duplicated" => { default => 0, parent => "headers", description => "duplicated function declarations checking" }, + "headers-misplaced" => { default => 0, parent => "headers", description => "misplaced function declarations checking" }, + "headers-needed" => { default => 1, parent => "headers", description => "headers needed checking" }, + "headers-unused" => { default => 0, parent => "headers", description => "headers unused checking" }, +); + +my %options_short = ( + "d" => "debug", + "?" => "help", + "v" => "verbose" +); + +my $options_usage = "usage: winapi_fixup [--help] []\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); + +use strict; + +sub report_module { + my $self = shift; + my $refvalue = $self->{MODULE}; + + my $name = shift; + + if(defined($name)) { + return $$refvalue->{active} && (!$$refvalue->{filter} || $$refvalue->{hash}->{$name}); + } else { + return 0; + } +} + +sub report_argument_forbidden { + my $self = shift; + my $refargument_forbidden = $self->{ARGUMENT_FORBIDDEN}; + + my $type = shift; + + return $$refargument_forbidden->{active} && (!$$refargument_forbidden->{filter} || $$refargument_forbidden->{hash}->{$type}); +} + +sub report_argument_kind { + my $self = shift; + my $refargument_kind = $self->{ARGUMENT_KIND}; + + my $kind = shift; + + return $$refargument_kind->{active} && (!$$refargument_kind->{filter} || $$refargument_kind->{hash}->{$kind}); + +} + +1; diff --git a/tools/winapi/winapi_extract b/tools/winapi/winapi_extract index de72ae0dff0..c93c1e29e20 100755 --- a/tools/winapi/winapi_extract +++ b/tools/winapi/winapi_extract @@ -15,40 +15,12 @@ use config qw( ); use modules; use nativeapi; -use output; +use output qw($output); use options; use winapi; use winapi_function; use winapi_parser; - -my $output = 'output'->new; - -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" }, - - "win16" => { default => 1, description => "Win16 extraction" }, - "win32" => { default => 1, description => "Win32 extraction" }, - - "local" => { default => 1, description => "local extraction" }, - "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" }, -); - -my %options_short = ( - "d" => "debug", - "?" => "help", - "v" => "verbose" -); - -my $options_usage = "usage: winapi_extract [--help] []\n"; - -my $options = 'options'->new(\%options_long, \%options_short, $options_usage); +use winapi_extract_options qw($options); my %module2spec_file; my %module2type; @@ -104,7 +76,6 @@ sub documentation_specifications { my $return_type = $function->return_type; my $linkage = $function->linkage; my $internal_name = $function->internal_name; - my @argument_types = @{$function->argument_types}; if($linkage eq "static") { return; @@ -203,14 +174,11 @@ foreach my $file (@c_files) { my $return_type = $function->return_type; my $calling_convention = $function->calling_convention; my $internal_name = $function->internal_name; - my @argument_types = @{$function->argument_types}; - my @argument_names = @{$function->argument_names}; - my @argument_documentations = @{$function->argument_documentations}; my $statements = $function->statements; $functions{$internal_name} = $function; - $output->prefix("$file: " . $function->prefix); + $output->prefix_callback(sub { return $function->prefix; }); if($options->spec_files) { documentation_specifications($function); @@ -228,7 +196,7 @@ foreach my $file (@c_files) { my $argument = shift; }; - winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor; + &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor); my @internal_names = keys(%functions); if($#internal_names < 0) { @@ -247,18 +215,23 @@ sub output_function { my $return_kind; my $calling_convention; - my @argument_kinds; + my $refargument_kinds; if($type eq "win16") { $return_kind = $function->return_kind16 || "undef"; $calling_convention = $function->calling_convention16 || "undef"; - @argument_kinds = map { $_ || "undef"; } @{$function->argument_kinds16}; + $refargument_kinds = $function->argument_kinds16; } elsif($type eq "win32") { $return_kind = $function->return_kind32 || "undef"; $calling_convention = $function->calling_convention32 || "undef"; - @argument_kinds = map { $_ || "undef"; } @{$function->argument_kinds32}; + $refargument_kinds = $function->argument_kinds32; } - print OUT "$ordinal $calling_convention $external_name(@argument_kinds) $internal_name\n"; + if(defined($refargument_kinds)) { + my @argument_kinds = map { $_ || "undef"; } @$refargument_kinds; + print OUT "$ordinal $calling_convention $external_name(@argument_kinds) $internal_name\n"; + } else { + print OUT "$ordinal $calling_convention $external_name() $internal_name # FIXME: arguments undefined\n"; + } } if($options->spec_files) { diff --git a/tools/winapi/winapi_extract_options.pm b/tools/winapi/winapi_extract_options.pm new file mode 100644 index 00000000000..0e4e9782000 --- /dev/null +++ b/tools/winapi/winapi_extract_options.pm @@ -0,0 +1,42 @@ +package winapi_extract_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" }, + + "win16" => { default => 1, description => "Win16 extraction" }, + "win32" => { default => 1, description => "Win32 extraction" }, + + "local" => { default => 1, description => "local extraction" }, + "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" }, +); + +my %options_short = ( + "d" => "debug", + "?" => "help", + "v" => "verbose" +); + +my $options_usage = "usage: winapi_extract [--help] []\n"; + +$options = '_options'->new(\%options_long, \%options_short, $options_usage); + +1; diff --git a/tools/winapi/winapi_fixup b/tools/winapi/winapi_fixup index a10dc4c9f34..4a87ba22265 100755 --- a/tools/winapi/winapi_fixup +++ b/tools/winapi/winapi_fixup @@ -16,47 +16,12 @@ use config qw( &get_spec_files $current_dir $wine_dir $winapi_dir $winapi_check_dir ); -use output; -use options; +use output qw($output); use modules; use util; use winapi; use winapi_parser; - -my $output = 'output'->new; - -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" }, - - "win16" => { default => 1, description => "Win16 fixup" }, - "win32" => { default => 1, description => "Win32 fixup" }, - - "local" => { default => 1, description => "local fixup" }, - "documentation" => { default => 1, parent => "local", description => "documentation fixup" }, - "documentation-missing" => { default => 1, parent => "documentation", description => "documentation missing fixup" }, - "documentation-name" => { default => 1, parent => "documentation", description => "documentation name fixup" }, - "documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" }, - "documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" }, - "stub" => { default => 0, parent => "local", description => "stub fixup" }, - - "global" => { default => 1, description => "global fixup" }, - - "modify" => { default => 0, description => "actually perform the fixups" }, -); - -my %options_short = ( - "d" => "debug", - "?" => "help", - "v" => "verbose" -); - -my $options_usage = "usage: winapi_fixup [--help] []\n"; - -my $options = 'options'->new(\%options_long, \%options_short, $options_usage); +use winapi_fixup_options qw($options); my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat"); @@ -91,6 +56,8 @@ foreach my $file (@c_files) { $output->progress("$file: file $progress_current of $progress_max"); } + my %documentation_line_used; + my $found_function = sub { my $function = shift; @@ -101,12 +68,12 @@ foreach my $file (@c_files) { my $return_type = $function->return_type; my $calling_convention = $function->calling_convention; my $internal_name = $function->internal_name; - my @argument_types = @{$function->argument_types}; - my @argument_names = @{$function->argument_names}; - my @argument_documentations = @{$function->argument_documentations}; my $statements = $function->statements; - if($linkage eq "static" || ($linkage eq "" && !defined($statements))) { + if($linkage eq "static" || + ($linkage eq "extern" && !defined($statements)) || + ($linkage eq "" && !defined($statements))) + { return; } @@ -115,7 +82,12 @@ foreach my $file (@c_files) { return; } - $output->prefix("$file: " . $function->prefix); + if($documentation_line_used{$documentation_line}) { + $documentation = undef; + } + $documentation_line_used{$documentation_line}++; + + $output->prefix_callback(sub { return $function->prefix; }); my @module_ordinal_entries = (); foreach my $entry2 ($function->get_all_module_ordinal) { @@ -131,7 +103,7 @@ foreach my $file (@c_files) { my $spec_modified = 0; - if($options->stub && $documentation) { + if($options->stub && defined($documentation)) { my $calling_convention16 = $function->calling_convention16; my $calling_convention32 = $function->calling_convention32; @@ -170,6 +142,12 @@ foreach my $file (@c_files) { foreach my $entry (@entries) { (my $external_name, my $module, my $ordinal) = @$entry; + my $refargument_types = $function->argument_types; + + if(!defined($refargument_types)) { + next; + } + my $abort = 0; my $n; my @argument_kinds = map { @@ -198,7 +176,7 @@ foreach my $file (@c_files) { $n++; "undef"; } - } @argument_types; + } @$refargument_types; my $substitute = {}; $substitute->{search} = "^\\s*$ordinal\\s+stub\\s+$external_name\\s*(?:#.*?)?\$"; @@ -229,9 +207,9 @@ foreach my $file (@c_files) { my $documentation_modified = 0; if(!$spec_modified && - ($documentation && !$documentation_modified) && + (defined($documentation) && !$documentation_modified) && ($options->documentation_name || $options->documentation_ordinal || - $options->documentation_missing)) + $options->documentation_missing)) { local $_; @@ -337,6 +315,7 @@ foreach my $file (@c_files) { # $output->write("@external_names\n"); } else { $documentation_modified = 1; + $substitute_line{$line3}{search} = $search; $substitute_line{$line3}{replace} = $replace; @@ -345,7 +324,7 @@ foreach my $file (@c_files) { } if(!$spec_modified && !$documentation_modified && - $options->documentation_missing && $documentation) + $options->documentation_missing && defined($documentation)) { my $part1; my $part2; @@ -385,6 +364,8 @@ foreach my $file (@c_files) { !$win32api->is_function_stub_in_module($module2, $internal_name)) { if($line3 > 0) { + $documentation_modified = 1; + $part2 = $external_name2 . " " x (length($part2) - length($external_name2)); $insert_line{$line3} = "$part1$part2$part3\U$module2\E.$ordinal2$part4\n"; } else { @@ -395,6 +376,7 @@ foreach my $file (@c_files) { } if(!$documentation_modified && + defined($documentation) && $options->documentation_wrong) { my $line2 = $documentation_line - 1; @@ -418,6 +400,8 @@ foreach my $file (@c_files) { } if(!$found) { if(1) { + $documentation_modified = 1; + $delete_line{$line2} = "^\Q$_\E\$"; } else { $output->write("$external_name (\U$module\E.$ordinal) wrong (fixup not supported)\n"); @@ -427,24 +411,22 @@ foreach my $file (@c_files) { } } - if(0) # !$spec_modified && !$documentation + if(!$spec_modified && !$documentation_modified && !defined($documentation)) { - # FIXME: Not correct - - my $external_name; - my $module; - my $ordinal; + my $insert = ""; foreach my $winapi (@winapis) { - $external_name = ($winapi->function_external_name($internal_name) || $external_name); - $module = ($winapi->function_internal_module($internal_name) || $module); - $ordinal = ($winapi->function_internal_ordinal($internal_name) || $ordinal); - if(defined($external_name) || defined($module) || defined($ordinal)) { last; } - } + my $external_name = $winapi->function_external_name($internal_name); + my $module = $winapi->function_internal_module($internal_name); + my $ordinal = $winapi->function_internal_ordinal($internal_name); - if(defined($external_name) && defined($module) && defined($ordinal)) { + if(defined($external_name) && defined($module) && defined($ordinal)) { + $insert .= " *\t\t$external_name (\U$module\E.$ordinal)\n"; + } + } + if($insert) { $insert_line{$function_line} = "/" . "*" x 71 . "\n" . - " *\t\t$external_name (\U$module\E.$ordinal)\n" . + "$insert" . " */\n"; } } @@ -457,7 +439,7 @@ foreach my $file (@c_files) { my $argument = shift; }; - winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor; + &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor); my $editor = sub { local *IN = shift; @@ -617,5 +599,3 @@ foreach my $file (@c_files) { } $output->hide_progress; - - diff --git a/tools/winapi/winapi_fixup_options.pm b/tools/winapi/winapi_fixup_options.pm new file mode 100644 index 00000000000..e2a26ddbab5 --- /dev/null +++ b/tools/winapi/winapi_fixup_options.pm @@ -0,0 +1,48 @@ +package winapi_fixup_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" }, + + "win16" => { default => 1, description => "Win16 fixup" }, + "win32" => { default => 1, description => "Win32 fixup" }, + + "local" => { default => 1, description => "local fixup" }, + "documentation" => { default => 1, parent => "local", description => "documentation fixup" }, + "documentation-missing" => { default => 1, parent => "documentation", description => "documentation missing fixup" }, + "documentation-name" => { default => 1, parent => "documentation", description => "documentation name fixup" }, + "documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" }, + "documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" }, + "stub" => { default => 0, parent => "local", description => "stub fixup" }, + + "global" => { default => 1, description => "global fixup" }, + + "modify" => { default => 0, description => "actually perform the fixups" }, +); + +my %options_short = ( + "d" => "debug", + "?" => "help", + "v" => "verbose" +); + +my $options_usage = "usage: winapi_fixup [--help] []\n"; + +$options = '_options'->new(\%options_long, \%options_short, $options_usage); + +1; diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check index d79be72dcba..0c64082ee2f 100755 --- a/tools/winapi_check/winapi_check +++ b/tools/winapi_check/winapi_check @@ -26,7 +26,7 @@ use config qw( ); use modules; use nativeapi; -use output; +use output qw($output); use preprocessor; use util qw(&is_subset); use winapi; @@ -34,21 +34,9 @@ use winapi_documentation; use winapi_function; use winapi_local; use winapi_global; -use winapi_options; +use winapi_check_options qw($options); use winapi_parser; -my $output = 'output'->new; - -my $options = winapi_options->new($output, \@ARGV, $wine_dir); -if(!defined($options)) { - $output->write("usage: winapi_check [--help] []\n"); - - exit 1; -} elsif($options->help) { - $options->show_help; - exit; -} - 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"); @@ -140,10 +128,12 @@ if($options->headers) { my $found_function = sub { my $function = shift; - $output->prefix($function->prefix); + $output->prefix_callback(sub { return $function->prefix; }); my $function_line = $function->function_line; + my $linkage = $function->linkage; my $internal_name = $function->internal_name; + my $external_name = $function->external_name; my $statements = $function->statements; if($options->headers_misplaced && @@ -154,7 +144,9 @@ if($options->headers) { $output->write("declaration misplaced\n"); } - if(!defined($statements)) { + if(defined($external_name) && !defined($statements) && + ($linkage eq "" || $linkage eq "extern")) + { my $previous_function = $declared_functions{$internal_name}; if(!defined($previous_function)) { $declared_functions{$internal_name} = $function; @@ -171,7 +163,7 @@ if($options->headers) { my $argument = shift; }; - winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor; + &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor); } } @@ -182,6 +174,8 @@ foreach my $file (@c_files) { my %functions = (); my %includes = (); + $includes{$file}++; + my $file_module16 = $modules->allowed_modules_in_file("$current_dir/$file"); my $file_module32 = $modules->allowed_modules_in_file("$current_dir/$file"); @@ -198,7 +192,7 @@ foreach my $file (@c_files) { my $found_function = sub { my $function = shift; - $output->prefix($function->prefix); + $output->prefix_callback(sub { return $function->prefix; }); my $internal_name = $function->internal_name; $functions{$internal_name} = $function; @@ -210,20 +204,44 @@ foreach my $file (@c_files) { my $linkage = $function->linkage; my $return_type = $function->return_type; my $calling_convention = $function->calling_convention; - my @argument_types = @{$function->argument_types}; - my @argument_names = @{$function->argument_names}; - my @argument_documentations = @{$function->argument_documentations}; my $statements = $function->statements; my $module16 = $function->module16; my $module32 = $function->module32; + my $external_name = $function->external_name; my $external_name16 = $function->external_name16; my $external_name32 = $function->external_name32; + if(defined($external_name) && !defined($statements) && + ($linkage eq "" || $linkage eq "extern")) + { + my $previous_function = $declared_functions{$internal_name}; + if(!defined($previous_function)) { + $declared_functions{$internal_name} = $function; + } else { + my $file = $previous_function->file; + my $function_line = $previous_function->function_line; + + my $header = $file; + $header =~ s%^(include|$file_dir)/%%; + if($header !~ m%^msvcrt/% || $file_dir =~ m%^dlls/msvcrt%) { + $output->write("duplicate declaration (first declaration at $file:$function_line)\n"); + } + } + } + foreach my $module ($function->modules) { $module2functions{$module}{$internal_name} = $function; - for my $type ($return_type, @argument_types) { + + my @types = ($return_type); + + my $refargument_types = $function->argument_types; + if(defined($refargument_types)) { + push @types, @$refargument_types; + } + + for my $type (@types) { $type_found{$module}{$type}++; } } @@ -240,16 +258,36 @@ foreach my $file (@c_files) { } } - if($options->headers_needed && defined($declared_function)) { + if($options->headers && $options->headers_needed && + defined($declared_function) && defined($external_name) && + defined($statements)) + { my $needed_include = $declared_function->file; if(!defined($includes{$needed_include})) { my $header = $needed_include; $header =~ s%^(include|$file_dir)/%%; - $output->write("prototype not included: #include \"$header\" is needed\n"); + if($header !~ m%^msvcrt/% || $file_dir =~ m%^dlls/msvcrt%) { + $output->write("prototype not included: #include \"$header\" is needed\n"); + } } } + if($options->local && $options->argument) { + &winapi_local::check_function($function); + } + + if($options->local && $options->statements) { + &winapi_local::check_statements(\%functions, $function); + } + + if($options->local && $options->documentation && + (defined($module16) || defined($module32)) && + $linkage ne "static" && ($linkage ne "" || defined($statements))) + { + &winapi_documentation::check_documentation($function); + } + if(1) { # FIXME: Not correct if(defined($external_name16)) { @@ -316,36 +354,9 @@ foreach my $file (@c_files) { } } } - - if($options->local && $options->argument) { - if($options->win16 && $options->report_module($module16)) { - winapi_local::check_function $options, $output, - $return_type, $calling_convention, $external_name16, $internal_name, [@argument_types], $nativeapi, $win16api; - } - if($options->win32 && $options->report_module($module32)) { - winapi_local::check_function $options, $output, - $return_type, $calling_convention, $external_name32, $internal_name, [@argument_types], $nativeapi, $win32api; - } - } - - if($options->local && $options->statements) { - if($options->win16 && $options->report_module($module16)) { - winapi_local::check_statements $options, $output, $win16api, \%functions, $function; - } - - if($options->win32 && $options->report_module($module32)) { - winapi_local::check_statements $options, $output, $win32api, \%functions, $function; - } - } - - if($options->local && $options->documentation && - (defined($module16) || defined($module32)) && - $linkage ne "static" && ($linkage ne "" || defined($statements))) - { - winapi_documentation::check_documentation $options, $output, $win16api, $win32api, $modules, $function; - } - $output->prefix(""); } + + $output->prefix(""); }; my $config = 0; @@ -500,7 +511,7 @@ foreach my $file (@c_files) { } }; - winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor; + &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor); if($options->config_unnessary) { if($config && $conditional == 0) { @@ -508,7 +519,7 @@ foreach my $file (@c_files) { } } - winapi_local::check_file $options, $output, $file, \%functions; + &winapi_local::check_file($file, \%functions); } $output->hide_progress; @@ -565,7 +576,7 @@ if($options->declared) { } if($options->global) { - winapi_documentation::report_documentation $options, $output; + &winapi_documentation::report_documentation; if($options->headers_unused) { foreach my $name (sort(keys(%include2info))) { @@ -577,8 +588,7 @@ if($options->global) { } } - winapi_global::check $options, $output, $win16api, $nativeapi, \%type_found if $options->win16; - winapi_global::check $options, $output, $win32api, $nativeapi, \%type_found if $options->win32; + &winapi_global::check(\%type_found); $modules->global_report; $nativeapi->global_report; diff --git a/tools/winapi_check/winapi_documentation.pm b/tools/winapi_check/winapi_documentation.pm index 36eb4386486..695f11a77fc 100644 --- a/tools/winapi_check/winapi_documentation.pm +++ b/tools/winapi_check/winapi_documentation.pm @@ -3,7 +3,11 @@ package winapi_documentation; use strict; use config qw($current_dir $wine_dir); +use modules qw($modules); use nativeapi qw($nativeapi); +use options qw($options); +use output qw($output); +use winapi qw($win16api $win32api @winapis); my %comment_width; my %comment_indent; @@ -12,11 +16,6 @@ my %comment_spacing; sub check_documentation { local $_; - my $options = shift; - my $output = shift; - my $win16api = shift; - my $win32api = shift; - my $modules = shift; my $function = shift; my $file = $function->file; @@ -29,7 +28,6 @@ sub check_documentation { my $ordinal32 = $function->ordinal32; my $documentation = $function->documentation; my $documentation_line = $function->documentation_line; - my @argument_documentations = @{$function->argument_documentations}; my $documentation_error = 0; my $documentation_warning = 0; @@ -159,12 +157,16 @@ sub check_documentation { } if($options->documentation_arguments) { - my $n = 0; - for my $argument_documentation (@argument_documentations) { - $n++; - if($argument_documentation ne "") { - if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) { - $output->write("argument $n documentation: \\\n$argument_documentation\n"); + my $refargument_documentations = $function->argument_documentations; + + if(defined($refargument_documentations)) { + my $n = 0; + for my $argument_documentation (@$refargument_documentations) { + $n++; + if($argument_documentation ne "") { + if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) { + $output->write("argument $n documentation: \\\n$argument_documentation\n"); + } } } } @@ -172,9 +174,6 @@ sub check_documentation { } sub report_documentation { - my $options = shift; - my $output = shift; - if($options->documentation_comment_indent) { foreach my $indent (sort(keys(%comment_indent))) { my $count = $comment_indent{$indent}; diff --git a/tools/winapi_check/winapi_function.pm b/tools/winapi_check/winapi_function.pm index a43ff57669e..6a3d0ec6572 100644 --- a/tools/winapi_check/winapi_function.pm +++ b/tools/winapi_check/winapi_function.pm @@ -74,13 +74,27 @@ sub _external_names { } } +sub external_name { + my $self = shift; + + foreach my $winapi (@winapis) { + my $external_name = $self->_external_name($winapi, @_); + + if(defined($external_name)) { + return $external_name; + } + } + + return undef; +} + sub external_name16 { my $self = shift; return $self->_external_name($win16api, @_); } sub external_name32 { my $self = shift; return $self->_external_name($win32api, @_); } sub external_names16 { my $self = shift; return $self->_external_names($win16api, @_); } sub external_names32 { my $self = shift; return $self->_external_names($win32api, @_); } -sub external_names { my $self = shift; return ($self->external_names16,$self->external_names32); } +sub external_names { my $self = shift; return ($self->external_names16, $self->external_names32); } ######################################################################## # module @@ -201,10 +215,14 @@ sub prefix { my $return_type = $self->return_type; my $internal_name = $self->internal_name; my $calling_convention = $self->calling_convention; - my @argument_types = @{$self->argument_types}; - if($#argument_types < 0) { - @argument_types = ("void"); + my $refargument_types = $self->argument_types; + my @argument_types = (); + if(defined($refargument_types)) { + @argument_types = @$refargument_types; + if($#argument_types < 0) { + @argument_types = ("void"); + } } my $prefix = ""; @@ -326,10 +344,14 @@ sub return_kind32 { sub _argument_kinds { my $self = shift; my $winapi = shift; - my @argument_types = @{$self->argument_types}; + my $refargument_types = $self->argument_types; + + if(!defined($refargument_types)) { + return undef; + } my @argument_kinds; - foreach my $argument_type (@argument_types) { + foreach my $argument_type (@$refargument_types) { my $argument_kind = $winapi->translate_argument($argument_type); if(defined($argument_kind) && $argument_kind eq "longlong") { diff --git a/tools/winapi_check/winapi_global.pm b/tools/winapi_check/winapi_global.pm index 72490620c8b..bb302e5141c 100644 --- a/tools/winapi_check/winapi_global.pm +++ b/tools/winapi_check/winapi_global.pm @@ -1,12 +1,26 @@ package winapi_global; use strict; - + +use nativeapi qw($nativeapi); +use options qw($options); +use output qw($output); +use winapi qw($win16api $win32api @winapis); + sub check { - my $options = shift; - my $output = shift; + my $type_found = shift; + + if($options->win16) { + _check($win16api, $type_found); + } + + if($options->win32) { + _check($win32api, $type_found); + } +} + +sub _check { my $winapi = shift; - my $nativeapi = shift; my $type_found = shift; my $winver = $winapi->name; diff --git a/tools/winapi_check/winapi_local.pm b/tools/winapi_check/winapi_local.pm index 2c73d75af8c..a4c523156a3 100644 --- a/tools/winapi_check/winapi_local.pm +++ b/tools/winapi_check/winapi_local.pm @@ -2,16 +2,51 @@ package winapi_local; use strict; +use nativeapi qw($nativeapi); +use options qw($options); +use output qw($output); +use winapi qw($win16api $win32api @winapis); + sub check_function { - my $options = shift; - my $output = shift; + my $function = shift; + + my $return_type = $function->return_type; + my $calling_convention = $function->calling_convention; + my $calling_convention16 = $function->calling_convention16; + my $calling_convention32 = $function->calling_convention32; + my $internal_name = $function->internal_name; + my $external_name16 = $function->external_name16; + my $external_name32 = $function->external_name32; + my $module16 = $function->module16; + my $module32 = $function->module32; + my $refargument_types = $function->argument_types; + + if(!defined($refargument_types)) { + return; + } + + if($options->win16 && $options->report_module($module16)) { + _check_function($return_type, + $calling_convention, $external_name16, + $internal_name, $refargument_types, + $win16api); + } + + if($options->win32 && $options->report_module($module32)) { + _check_function($return_type, + $calling_convention, $external_name32, + $internal_name, $refargument_types, + $win32api); + } +} + +sub _check_function { my $return_type = shift; my $calling_convention = shift; my $external_name = shift; my $internal_name = shift; my $refargument_types = shift; my @argument_types = @$refargument_types; - my $nativeapi = shift; my $winapi = shift; my $module = $winapi->function_internal_module($internal_name); @@ -212,8 +247,22 @@ sub check_function { } sub check_statements { - my $options = shift; - my $output = shift; + my $functions = shift; + my $function = shift; + + my $module16 = $function->module16; + my $module32 = $function->module32; + + if($options->win16 && $options->report_module($module16)) { + _check_statements($win16api, $functions, $function); + } + + if($options->win32 && $options->report_module($module32)) { + _check_statements($win16api, $functions, $function); + } +} + +sub _check_statements { my $winapi = shift; my $functions = shift; my $function = shift; @@ -288,8 +337,6 @@ sub check_statements { } sub check_file { - my $options = shift; - my $output = shift; my $file = shift; my $functions = shift; diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm index 21b9f2a950b..73b617c138e 100644 --- a/tools/winapi_check/winapi_options.pm +++ b/tools/winapi_check/winapi_options.pm @@ -2,6 +2,18 @@ package winapi_options; use strict; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); +require Exporter; + +@ISA = qw(Exporter); +@EXPORT = qw(&parse_comma_list); +@EXPORT_OK = qw($options); + +use vars qw($options); + +use config qw($current_dir $wine_dir); +use output qw($output); + sub parser_comma_list { my $prefix = shift; my $value = shift; @@ -138,12 +150,6 @@ sub new { my $self = {}; bless ($self, $class); - my $output = \${$self->{OUTPUT}}; - - $$output = shift; - my $refarguments = shift; - my $wine_dir = shift; - $self->options_set("default"); my $c_files = \@{$self->{C_FILES}}; @@ -160,7 +166,7 @@ sub new { $$global = 0; } - while(defined($_ = shift @$refarguments)) { + while(defined($_ = shift @ARGV)) { if(/^--(all|none)$/) { $self->options_set("$1"); next; @@ -185,7 +191,7 @@ sub new { $name = $1; $prefix = "no"; if(defined($value)) { - $$output->write("options with prefix 'no' can't take parameters\n"); + $output->write("options with prefix 'no' can't take parameters\n"); return undef; } @@ -258,12 +264,12 @@ sub new { $$module = { active => 1, filter => 1, hash => \%names }; } elsif(/^-(.*)$/) { - $$output->write("unknown option: $_\n"); + $output->write("unknown option: $_\n"); return undef; } else { if(!-e $_) { - $$output->write("$_: no such file or directory\n"); + $output->write("$_: no such file or directory\n"); return undef; } @@ -329,6 +335,9 @@ sub new { } } split(/\n/, `$h_command`)); } + + $options = $self; + return $self; } diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm index 8e99f839ab9..077ce10bae6 100644 --- a/tools/winapi_check/winapi_parser.pm +++ b/tools/winapi_check/winapi_parser.pm @@ -2,11 +2,11 @@ package winapi_parser; use strict; +use output qw($output); use winapi_function; sub parse_c_file { my $options = shift; - my $output = shift; my $file = shift; my $function_found_callback = shift; my $preprocessor_found_callback = shift; @@ -39,13 +39,17 @@ sub parse_c_file { $argument_names = shift; $argument_documentations = shift; - if($#$argument_names == -1) { + if(defined($argument_names) && defined($argument_types) && + $#$argument_names == -1) + { foreach my $n (0..$#$argument_types) { push @$argument_names, ""; } } - if($#$argument_documentations == -1) { + if(defined($argument_documentations) && + $#$argument_documentations == -1) + { foreach my $n (0..$#$argument_documentations) { push @$argument_documentations, ""; } @@ -69,9 +73,15 @@ sub parse_c_file { $function->return_type($return_type); $function->calling_convention($calling_convention); $function->internal_name($internal_name); - $function->argument_types([@$argument_types]); - $function->argument_names([@$argument_names]); - $function->argument_documentations([@$argument_documentations]); + 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); @@ -351,53 +361,89 @@ sub parse_c_file { &$function_end; } } elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) { + my @lines = split(/\n/, $&); + my $function_line = $. - scalar(@lines) + 1; + $_ = $'; $again = 1; - my @arguments = (); + &$function_begin($documentation_line, $documentation, - $function_line, "", "void", "__asm", $1, \@arguments); + $function_line, "", "void", "__asm", $1); + $statements = ""; &$function_end; - } elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { + } 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, "", $2, "WINAPI", $3, \@arguments); + $function_line, "", $return16, "WINAPI", $name16, \@arguments); + $statements = ""; &$function_end; - } elsif(/DC_(GET_VAL)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) { + } elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) { + my @lines = split(/\n/, $&); + my $function_line = $. - scalar(@lines) + 1; + $_ = $'; $again = 1; - my $return16 = $3 . "16"; - my $return32 = $3; - my $name16 = $2 . "16"; - my $name32 = $2; - my @arguments16 = ("HDC16"); + + my $return32 = $2; + my $name32 = $3; my @arguments32 = ("HDC"); - if($name16 eq "COLORREF16") { $name16 = "COLORREF"; } + &$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; - &$function_begin($documentation_line, $documentation, - $function_line, "", $name16, "WINAPI", $return16, \@arguments16); - &$function_end; - &$function_begin($documentation_line, $documentation, - $function_line, "", $name32, "WINAPI", $return32, \@arguments32); - &$function_end; - } elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { $_ = $'; $again = 1; + my @arguments16 = ("HDC16", "LP" . $5 . "16"); - my @arguments32 = ("HDC", "LP" . $5); &$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)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { + } 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"); - my @arguments32 = ("HDC", "INT"); &$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; } elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) { $_ = $'; $again = 1; @@ -405,27 +451,39 @@ sub parse_c_file { my @arguments32 = ("HWAVEIN"); &$function_begin($documentation_line, $documentation, $function_line, "", "UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16); + $statements = ""; &$function_end; &$function_begin($documentation_line, $documentation, $function_line, "", "UINT", "WINAPI", "waveIn" . $1, \@arguments32); + $statements = ""; &$function_end; } elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) { + my @lines = split(/\n/, $&); + my $function_line = $. - scalar(@lines) + 1; + $_ = $'; $again = 1; + my @arguments16 = ("HWAVEOUT16"); my @arguments32 = ("HWAVEOUT"); &$function_begin($documentation_line, $documentation, $function_line, "", "UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16); + $statements = ""; &$function_end; &$function_begin($documentation_line, $documentation, $function_line, "", "UINT", "WINAPI", "waveOut" . $1, \@arguments32); &$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; + $_ = $'; $again = 1; + if($1 eq "1") { my @arguments16 = ("HWAVEOUT16", $4); my @arguments32 = ("HWAVEOUT", $4); &$function_begin($documentation_line, $documentation, $function_line, "", "UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16); + $statements = ""; &$function_end; &$function_begin($documentation_line, $documentation, $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32); @@ -435,6 +493,7 @@ sub parse_c_file { my @arguments32 = ("UINT", $4); &$function_begin($documentation_line, $documentation, $function_line, "", "UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16); + $statements = ""; &$function_end; &$function_begin($documentation_line, $documentation, $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);