From aeb023f35209d2c18c3cd54ebbb2e3d34c336a43 Mon Sep 17 00:00:00 2001 From: Patrik Stridvall Date: Wed, 22 Aug 2001 18:09:15 +0000 Subject: [PATCH] - Continued on the new C parser. - More reorganizations and fixes. - API files update. --- tools/winapi/c_function.pm | 168 ++++ tools/winapi/c_parser.pm | 1008 ++++++++++++++++++++--- tools/winapi/make_parser.pm | 34 +- tools/winapi/output.pm | 9 +- tools/winapi/winapi_extract | 21 +- tools/winapi/winapi_fixup | 124 ++- tools/winapi/winapi_fixup_editor.pm | 2 +- tools/winapi/winapi_fixup_options.pm | 2 +- tools/winapi/winapi_fixup_statements.pm | 244 ++++-- tools/winapi/winapi_module_user.pm | 445 ++++++++++ tools/winapi_check/modules.pm | 4 +- tools/winapi_check/nativeapi.pm | 12 +- tools/winapi_check/win32/kernel32.api | 2 - tools/winapi_check/win32/oleaut32.api | 3 + tools/winapi_check/win32/quartz.api | 1 - tools/winapi_check/win32/shell32.api | 1 + tools/winapi_check/win32/ttydrv.api | 2 +- tools/winapi_check/win32/x11drv.api | 1 - tools/winapi_check/winapi.pm | 8 +- tools/winapi_check/winapi_check | 28 +- 20 files changed, 1844 insertions(+), 275 deletions(-) create mode 100644 tools/winapi/c_function.pm create mode 100644 tools/winapi/winapi_module_user.pm diff --git a/tools/winapi/c_function.pm b/tools/winapi/c_function.pm new file mode 100644 index 00000000000..ee96a91af4d --- /dev/null +++ b/tools/winapi/c_function.pm @@ -0,0 +1,168 @@ +package c_function; + +use strict; + +sub new { + my $proto = shift; + my $class = ref($proto) || $proto; + my $self = {}; + bless ($self, $class); + + return $self; +} + +sub file { + my $self = shift; + my $file = \${$self->{FILE}}; + + local $_ = shift; + + if(defined($_)) { $$file = $_; } + + return $$file; +} + +sub begin_line { + my $self = shift; + my $begin_line = \${$self->{BEGIN_LINE}}; + + local $_ = shift; + + if(defined($_)) { $$begin_line = $_; } + + return $$begin_line; +} + +sub begin_column { + my $self = shift; + my $begin_column = \${$self->{BEGIN_COLUMN}}; + + local $_ = shift; + + if(defined($_)) { $$begin_column = $_; } + + return $$begin_column; +} + +sub end_line { + my $self = shift; + my $end_line = \${$self->{END_LINE}}; + + local $_ = shift; + + if(defined($_)) { $$end_line = $_; } + + return $$end_line; +} + +sub end_column { + my $self = shift; + my $end_column = \${$self->{END_COLUMN}}; + + local $_ = shift; + + if(defined($_)) { $$end_column = $_; } + + return $$end_column; +} + +sub linkage { + my $self = shift; + my $linkage = \${$self->{LINKAGE}}; + + local $_ = shift; + + if(defined($_)) { $$linkage = $_; } + + return $$linkage; +} + +sub return_type { + my $self = shift; + my $return_type = \${$self->{RETURN_TYPE}}; + + local $_ = shift; + + if(defined($_)) { $$return_type = $_; } + + return $$return_type; +} + +sub calling_convention { + my $self = shift; + my $calling_convention = \${$self->{CALLING_CONVENTION}}; + + local $_ = shift; + + if(defined($_)) { $$calling_convention = $_; } + + return $$calling_convention; +} + +sub name { + my $self = shift; + my $name = \${$self->{NAME}}; + + local $_ = shift; + + if(defined($_)) { $$name = $_; } + + return $$name; +} + +sub argument_types { + my $self = shift; + my $argument_types = \${$self->{ARGUMENT_TYPES}}; + + local $_ = shift; + + if(defined($_)) { $$argument_types = $_; } + + return $$argument_types; +} + +sub argument_names { + my $self = shift; + my $argument_names = \${$self->{ARGUMENT_NAMES}}; + + local $_ = shift; + + if(defined($_)) { $$argument_names = $_; } + + return $$argument_names; +} + +sub statements_line { + my $self = shift; + my $statements_line = \${$self->{STATEMENTS_LINE}}; + + local $_ = shift; + + if(defined($_)) { $$statements_line = $_; } + + return $$statements_line; +} + +sub statements_column { + my $self = shift; + my $statements_column = \${$self->{STATEMENTS_COLUMN}}; + + local $_ = shift; + + if(defined($_)) { $$statements_column = $_; } + + return $$statements_column; +} + +sub statements { + my $self = shift; + my $statements = \${$self->{STATEMENTS}}; + + local $_ = shift; + + if(defined($_)) { $$statements = $_; } + + return $$statements; +} + +1; diff --git a/tools/winapi/c_parser.pm b/tools/winapi/c_parser.pm index 957723a34a7..87c880c6d5f 100644 --- a/tools/winapi/c_parser.pm +++ b/tools/winapi/c_parser.pm @@ -2,92 +2,218 @@ package c_parser; use strict; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); +require Exporter; + +@ISA = qw(Exporter); +@EXPORT = qw(); +@EXPORT_OK = qw(); + use options qw($options); use output qw($output); -sub _update_c_position { - local $_ = shift; - my $refline = shift; - my $refcolumn = shift; +use c_function; - my $line = $$refline; - my $column = $$refcolumn; +######################################################################## +# new +# +sub new { + my $proto = shift; + my $class = ref($proto) || $proto; + my $self = {}; + bless ($self, $class); - while($_) { - if(s/^[^\n\t\'\"]*//s) { - $column += length($&); - } + my $file = \${$self->{FILE}}; + my $found_comment = \${$self->{FOUND_COMMENT}}; + my $found_declaration = \${$self->{FOUND_DECLARATION}}; + my $create_function = \${$self->{CREATE_FUNCTION}}; + my $found_function = \${$self->{FOUND_FUNCTION}}; + my $found_function_call = \${$self->{FOUND_FUNCTION_CALL}}; + my $found_preprocessor = \${$self->{FOUND_PREPROCESSOR}}; + my $found_statement = \${$self->{FOUND_STATEMENT}}; + my $found_variable = \${$self->{FOUND_VARIABLE}}; - if(s/^\'//) { - $column++; - while(/^./ && !s/^\'//) { - s/^([^\'\\]*)//s; - $column += length($1); - if(s/^\\//) { - $column++; - if(s/^(.)//s) { - $column += length($1); - if($1 eq "0") { - s/^(\d{0,3})//s; - $column += length($1); - } - } - } - } - $column++; - } elsif(s/^\"//) { - $column++; - while(/^./ && !s/^\"//) { - s/^([^\"\\]*)//s; - $column += length($1); - if(s/^\\//) { - $column++; - if(s/^(.)//s) { - $column += length($1); - if($1 eq "0") { - s/^(\d{0,3})//s; - $column += length($1); - } - } - } - } - $column++; - } elsif(s/^\n//) { - $line++; - $column = 0; - } elsif(s/^\t//) { - $column = $column + 8 - $column % 8; - } - } + $$file = shift; - $$refline = $line; - $$refcolumn = $column; + $$found_comment = sub { return 1; }; + $$found_declaration = sub { return 1; }; + $$create_function = sub { return new c_function; }; + $$found_function = sub { return 1; }; + $$found_function_call = sub { return 1; }; + $$found_preprocessor = sub { return 1; }; + $$found_statement = sub { return 1; }; + $$found_variable = sub { return 1; }; + + return $self; } -sub parse_c { +######################################################################## +# set_found_comment_callback +# +sub set_found_comment_callback { + my $self = shift; + + my $found_comment = \${$self->{FOUND_COMMENT}}; + + $$found_comment = shift; +} + +######################################################################## +# set_found_declaration_callback +# +sub set_found_declaration_callback { + my $self = shift; + + my $found_declaration = \${$self->{FOUND_DECLARATION}}; + + $$found_declaration = shift; +} + +######################################################################## +# set_found_function_callback +# +sub set_found_function_callback { + my $self = shift; + + my $found_function = \${$self->{FOUND_FUNCTION}}; + + $$found_function = shift; +} + +######################################################################## +# set_found_function_call_callback +# +sub set_found_function_call_callback { + my $self = shift; + + my $found_function_call = \${$self->{FOUND_FUNCTION_CALL}}; + + $$found_function_call = shift; +} + +######################################################################## +# set_found_preprocessor_callback +# +sub set_found_preprocessor_callback { + my $self = shift; + + my $found_preprocessor = \${$self->{FOUND_PREPROCESSOR}}; + + $$found_preprocessor = shift; +} + +######################################################################## +# set_found_statement_callback +# +sub set_found_statement_callback { + my $self = shift; + + my $found_statement = \${$self->{FOUND_STATEMENT}}; + + $$found_statement = shift; +} + +######################################################################## +# set_found_variable_callback +# +sub set_found_variable_callback { + my $self = shift; + + my $found_variable = \${$self->{FOUND_VARIABLE}}; + + $$found_variable = shift; +} + +######################################################################## +# _parse_c + +sub _parse_c { + my $self = shift; + my $pattern = shift; my $refcurrent = shift; my $refline = shift; my $refcolumn = shift; + my $refmatch = shift; + local $_ = $$refcurrent; my $line = $$refline; my $column = $$refcolumn; - if(s/$pattern//) { - _update_c_position($&, \$line, \$column); + my $match; + if(s/^(?:$pattern)//s) { + $self->_update_c_position($&, \$line, \$column); + $match = $&; } else { return 0; } + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + $$refcurrent = $_; $$refline = $line; $$refcolumn = $column; + $$refmatch = $match; + return 1; } -sub parse_c_until_one_of { +######################################################################## +# _parse_c_error + +sub _parse_c_error { + my $self = shift; + + my $file = \${$self->{FILE}}; + + local $_ = shift; + my $line = shift; + my $column = shift; + my $context = shift; + + my @lines = split(/\n/, $_); + + my $current = "\n"; + $current .= $lines[0] . "\n" || ""; + $current .= $lines[1] . "\n" || ""; + + if($output->prefix) { + $output->write("\n"); + $output->prefix(""); + } + $output->write("$$file:$line." . ($column + 1) . ": $context: parse error: \\$current"); + + exit 1; +} + +######################################################################## +# _parse_c_output + +sub _parse_c_output { + my $self = shift; + + local $_ = shift; + my $line = shift; + my $column = shift; + my $message = shift; + + my @lines = split(/\n/, $_); + + my $current = "\n"; + $current .= $lines[0] . "\n" || ""; + $current .= $lines[1] . "\n" || ""; + + $output->write("$line." . ($column + 1) . ": $message: \\$current"); +} + +######################################################################## +# _parse_c_until_one_of + +sub _parse_c_until_one_of { + my $self = shift; + my $characters = shift; my $refcurrent = shift; my $refline = shift; @@ -98,11 +224,6 @@ sub parse_c_until_one_of { my $line = $$refline; my $column = $$refcolumn; - if(!defined($line) || !defined($column)) { - $output->write("error: \$characters = '$characters' \$_ = '$_'\n"); - exit 1; - } - if(!defined($match)) { my $blackhole; $match = \$blackhole; @@ -179,10 +300,80 @@ sub parse_c_until_one_of { return 1; } +######################################################################## +# _update_c_position + +sub _update_c_position { + my $self = shift; + + local $_ = shift; + my $refline = shift; + my $refcolumn = shift; + + my $line = $$refline; + my $column = $$refcolumn; + + while($_) { + if(s/^[^\n\t\'\"]*//s) { + $column += length($&); + } + + if(s/^\'//) { + $column++; + while(/^./ && !s/^\'//) { + s/^([^\'\\]*)//s; + $column += length($1); + if(s/^\\//) { + $column++; + if(s/^(.)//s) { + $column += length($1); + if($1 eq "0") { + s/^(\d{0,3})//s; + $column += length($1); + } + } + } + } + $column++; + } elsif(s/^\"//) { + $column++; + while(/^./ && !s/^\"//) { + s/^([^\"\\]*)//s; + $column += length($1); + if(s/^\\//) { + $column++; + if(s/^(.)//s) { + $column += length($1); + if($1 eq "0") { + s/^(\d{0,3})//s; + $column += length($1); + } + } + } + } + $column++; + } elsif(s/^\n//) { + $line++; + $column = 0; + } elsif(s/^\t//) { + $column = $column + 8 - $column % 8; + } + } + + $$refline = $line; + $$refcolumn = $column; +} + +######################################################################## +# parse_c_block + sub parse_c_block { + my $self = shift; + my $refcurrent = shift; my $refline = shift; my $refcolumn = shift; + my $refstatements = shift; my $refstatements_line = shift; my $refstatements_column = shift; @@ -191,6 +382,8 @@ sub parse_c_block { my $line = $$refline; my $column = $$refcolumn; + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + my $statements; if(s/^\{//) { $column++; @@ -199,7 +392,7 @@ sub parse_c_block { return 0; } - parse_c_until_one_of("\\S", \$_, \$line, \$column); + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); my $statements_line = $line; my $statements_column = $column; @@ -207,7 +400,7 @@ sub parse_c_block { my $plevel = 1; while($plevel > 0) { my $match; - parse_c_until_one_of("\\{\\}", \$_, \$line, \$column, \$match); + $self->_parse_c_until_one_of("\\{\\}", \$_, \$line, \$column, \$match); $column++; @@ -235,63 +428,161 @@ sub parse_c_block { return 1; } -sub parse_c_expression { +######################################################################## +# parse_c_declaration + +sub parse_c_declaration { + my $self = shift; + + my $found_declaration = \${$self->{FOUND_DECLARATION}}; + my $found_function = \${$self->{FOUND_FUNCTION}}; + my $refcurrent = shift; my $refline = shift; my $refcolumn = shift; - my $found_function_call_callback = shift; + local $_ = $$refcurrent; my $line = $$refline; my $column = $$refcolumn; + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + + my $begin_line = $line; + my $begin_column = $column + 1; + + my $end_line = $begin_line; + my $end_column = $begin_column; + $self->_update_c_position($_, \$end_line, \$end_column); + + if(!&$$found_declaration($begin_line, $begin_column, $end_line, $end_column, $_)) { + return 1; + } + + # Function + my $function = shift; + + my $linkage = shift; + my $calling_convention = shift; + my $return_type = shift; + my $name = shift; + my @arguments = shift; + my @argument_lines = shift; + my @argument_columns = shift; + + # Variable + my $type; + + # $self->_parse_c_output($_, $line, $column, "declaration"); + + if(0) { + # Nothing + } elsif(s/^(?:DEFAULT|DECLARE)_DEBUG_CHANNEL\s*\(\s*(\w+)\s*\)\s*//s) { # FIXME: Wine specific kludge + $self->_update_c_position($&, \$line, \$column); + } elsif(s/^extern\s*\"(.*?)\"\s*//s) { + $self->_update_c_position($&, \$line, \$column); + my $declarations; + my $declarations_line; + my $declarations_column; + if(!$self->parse_c_block(\$_, \$line, \$column, \$declarations, \$declarations_line, \$declarations_column)) { + return 0; + } + if(!$self->parse_c_declarations(\$declarations, \$declarations_line, \$declarations_column)) { + return 0; + } + } elsif($self->parse_c_function(\$_, \$line, \$column, \$function)) { + if(&$$found_function($function)) + { + my $statements = $function->statements; + my $statements_line = $function->statements_line; + my $statements_column = $function->statements_column; + + if(defined($statements)) { + if(!$self->parse_c_statements(\$statements, \$statements_line, \$statements_column)) { + return 0; + } + } + } + } elsif($self->parse_c_typedef(\$_, \$line, \$column)) { + # Nothing + } elsif($self->parse_c_variable(\$_, \$line, \$column, \$linkage, \$type, \$name)) { + # Nothing + } else { + $self->_parse_c_error($_, $line, $column, "declaration"); + } + + $$refcurrent = $_; + $$refline = $line; + $$refcolumn = $column; + + return 1; +} + +######################################################################## +# parse_c_declarations + +sub parse_c_declarations { + my $self = shift; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + return 1; +} + +######################################################################## +# parse_c_expression + +sub parse_c_expression { + my $self = shift; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + my $found_function_call = \${$self->{FOUND_FUNCTION_CALL}}; + local $_ = $$refcurrent; + my $line = $$refline; + my $column = $$refcolumn; - parse_c_until_one_of("\\S", \$_, \$line, \$column); + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + + if(s/^(.*?)(\w+\s*\()/$2/s) { + $column += length($1); - if(s/^(.*?)(\w+)(\s*)\(//s) { my $begin_line = $line; - my $begin_column = $column + length($1) + 1; - - $line = $begin_line; - $column = $begin_column + length("$2$3") - 1; - - my $name = $2; - - $_ = "($'"; - - # $output->write("$name: $line.$column: '$_'\n"); + my $begin_column = $column + 1; + my $name; my @arguments; my @argument_lines; my @argument_columns; - if(!parse_c_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) { + if(!$self->parse_c_function_call(\$_, \$line, \$column, \$name, \@arguments, \@argument_lines, \@argument_columns)) { return 0; } - if($name =~ /^sizeof$/) { - # Nothing - } else { - &$found_function_call_callback($begin_line, $begin_column, $line, $column, - $name, \@arguments); - } - - while(defined(my $argument = shift @arguments) && - defined(my $argument_line = shift @argument_lines) && - defined(my $argument_column = shift @argument_columns)) + if($name =~ /^sizeof$/ || + &$$found_function_call($begin_line, $begin_column, $line, $column, $name, \@arguments)) { - parse_c_expression(\$argument, \$argument_line, \$argument_column, $found_function_call_callback); + while(defined(my $argument = shift @arguments) && + defined(my $argument_line = shift @argument_lines) && + defined(my $argument_column = shift @argument_columns)) + { + $self->parse_c_expression(\$argument, \$argument_line, \$argument_column); + } } } elsif(s/^return//) { $column += length($&); - parse_c_until_one_of("\\S", \$_, \$line, \$column); - if(!parse_c_expression(\$_, \$line, \$column, $found_function_call_callback)) { + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + if(!$self->parse_c_expression(\$_, \$line, \$column)) { return 0; } } else { return 0; } - _update_c_position($_, \$line, \$column); + $self->_update_c_position($_, \$line, \$column); $$refcurrent = $_; $$refline = $line; @@ -300,22 +591,358 @@ sub parse_c_expression { return 1; } -sub parse_c_statement { +######################################################################## +# parse_c_file + +sub parse_c_file { + my $self = shift; + + my $found_comment = \${$self->{FOUND_COMMENT}}; + my $refcurrent = shift; my $refline = shift; my $refcolumn = shift; - my $found_function_call_callback = shift; - + + local $_ = $$refcurrent; my $line = $$refline; my $column = $$refcolumn; - local $_ = $$refcurrent; + my $declaration = ""; + my $declaration_line = $line; + my $declaration_column = $column; - parse_c_until_one_of("\\S", \$_, \$line, \$column); + my $previous_line = 0; + my $previous_column = -1; + + my $blevel = 1; + my $plevel = 1; + while($plevel > 0 || $blevel > 0) { + my $match; + $self->_parse_c_until_one_of("#/\\(\\)\\[\\]\\{\\};", \$_, \$line, \$column, \$match); + + if($line == $previous_line && $column == $previous_column) { + # $self->_parse_c_error($_, $line, $column, "file: no progress"); + } + $previous_line = $line; + $previous_column = $column; + + # $self->_parse_c_output($_, $line, $column, "'$match'"); + + if(!$declaration && $match =~ s/^\s+//s) { + $self->_update_c_position($&, \$declaration_line, \$declaration_column); + } + $declaration .= $match; + + if(/^[\#\/]/) { + my $blank_lines = 0; + if(s/^\#\s*//) { + my $preprocessor_line = $line; + my $preprocessor_column = $column; + + my $preprocessor = $&; + while(s/^(.*?)\\\s*\n//) { + $blank_lines++; + $preprocessor .= "$1\n"; + } + if(s/^(.*?)(\/[\*\/].*)?\n//) { + if(defined($2)) { + $_ = "$2\n$_"; + } else { + $blank_lines++; + } + $preprocessor .= $1; + } + + if(!$self->parse_c_preprocessor(\$preprocessor, \$preprocessor_line, \$preprocessor_column)) { + return 0; + } + } + + if(s/^\/\*(.*?)\*\///s) { + &$$found_comment($line, $column + 1, "/*$1*/"); + my @lines = split(/\n/, $1); + if($#lines > 0) { + $blank_lines += $#lines; + } else { + $column += length($1); + } + } elsif(s/^\/\/(.*?)\n//) { + &$$found_comment($line, $column + 1, "//$1"); + $blank_lines++; + } elsif(s/^\///) { + $declaration .= $&; + } + + $line += $blank_lines; + if($blank_lines > 0) { + $column = 0; + } + + if(!$declaration) { + $declaration_line = $line; + $declaration_column = $column; + } else { + $declaration .= "\n" x $blank_lines; + } + + next; + } + + $column++; + if(s/^[\(\[]//) { + $plevel++; + $declaration .= $&; + } elsif(s/^[\)\]]//) { + $plevel--; + $declaration .= $&; + } elsif(s/^\{//) { + $blevel++; + $declaration .= $&; + } elsif(s/^\}//) { + $blevel--; + $declaration .= $&; + if($plevel == 1 && $blevel == 1 && $declaration !~ /^typedef/) { + if(!$self->parse_c_declaration(\$declaration, \$declaration_line, \$declaration_column)) { + return 0; + } + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + $declaration = ""; + $declaration_line = $line; + $declaration_column = $column; + } + } elsif(s/^;//) { + if($plevel == 1 && $blevel == 1) { + if($declaration && !$self->parse_c_declaration(\$declaration, \$declaration_line, \$declaration_column)) { + return 0; + } + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + $declaration = ""; + $declaration_line = $line; + $declaration_column = $column; + } else { + $declaration .= $&; + } + } elsif(/^\s*$/ && $declaration =~ /^\s*$/ && $match =~ /^\s*$/) { + $plevel = 0; + $blevel = 0; + } else { + $self->_parse_c_error($_, $line, $column, "file"); + } + } + + $$refcurrent = $_; + $$refline = $line; + $$refcolumn = $column; + + return 1; +} + +######################################################################## +# parse_c_function + +sub parse_c_function { + my $self = shift; + + my $file = \${$self->{FILE}}; + my $create_function = \${$self->{CREATE_FUNCTION}}; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + my $reffunction = shift; + + local $_ = $$refcurrent; + my $line = $$refline; + my $column = $$refcolumn; + + my $linkage = ""; + my $calling_convention = ""; + my $return_type; + my $name; + my @arguments; + my @argument_lines; + my @argument_columns; + my $statements; + my $statements_line; + my $statements_column; + + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + + my $begin_line = $line; + my $begin_column = $column + 1; + + $self->_parse_c("inline", \$_, \$line, \$column); + $self->_parse_c("extern|static", \$_, \$line, \$column, \$linkage); + $self->_parse_c("inline", \$_, \$line, \$column); + if(!$self->parse_c_type(\$_, \$line, \$column, \$return_type)) { + return 0; + } + + $self->_parse_c("__cdecl|__stdcall|CDECL|VFWAPIV|VFWAPI|WINAPIV|WINAPI|CALLBACK", + \$_, \$line, \$column, \$calling_convention); + if(!$self->_parse_c("\\w+", \$_, \$line, \$column, \$name)) { + return 0; + } + if(!$self->parse_c_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) { + return 0; + } + if($_ && !$self->parse_c_block(\$_, \$line, \$column, \$statements, \$statements_line, \$statements_column)) { + return 0; + } + + my $end_line = $line; + my $end_column = $column; + + $$refcurrent = $_; + $$refline = $line; + $$refcolumn = $column; + + my $function = &$$create_function; + + $function->file($$file); + $function->begin_line($begin_line); + $function->begin_column($begin_column); + $function->end_line($end_line); + $function->end_column($end_column); + $function->linkage($linkage); + $function->return_type($return_type); + $function->calling_convention($calling_convention); + $function->name($name); + # if(defined($argument_types)) { + # $function->argument_types([@$argument_types]); + # } + # if(defined($argument_names)) { + # $function->argument_names([@$argument_names]); + # } + $function->statements_line($statements_line); + $function->statements_column($statements_column); + $function->statements($statements); + + $$reffunction = $function; + + return 1; +} + +######################################################################## +# parse_c_function_call + +sub parse_c_function_call { + my $self = shift; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + my $refname = shift; + my $refarguments = shift; + my $refargument_lines = shift; + my $refargument_columns = shift; + + local $_ = $$refcurrent; + my $line = $$refline; + my $column = $$refcolumn; + + my $name; + my @arguments; + my @argument_lines; + my @argument_columns; + + if(s/^(\w+)(\s*)\(/\(/s) { + $column += length("$1$2"); + + $name = $1; + + if(!$self->parse_c_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) { + return 0; + } + } else { + return 0; + } + + $$refcurrent = $_; + $$refline = $line; + $$refcolumn = $column; + + $$refname = $name; + @$refarguments = @arguments; + @$refargument_lines = @argument_lines; + @$refargument_columns = @argument_columns; + + return 1; +} + +######################################################################## +# parse_c_preprocessor + +sub parse_c_preprocessor { + my $self = shift; + + my $found_preprocessor = \${$self->{FOUND_PREPROCESSOR}}; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + local $_ = $$refcurrent; + my $line = $$refline; + my $column = $$refcolumn; + + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + + my $begin_line = $line; + my $begin_column = $column + 1; + + if(!&$$found_preprocessor($begin_line, $begin_column, "$_")) { + return 1; + } + + if(0) { + # Nothing + } elsif(/^\#\s*define\s+(.*?)$/s) { + $self->_update_c_position($_, \$line, \$column); + } elsif(/^\#\s*else/s) { + $self->_update_c_position($_, \$line, \$column); + } elsif(/^\#\s*endif/s) { + $self->_update_c_position($_, \$line, \$column); + } elsif(/^\#\s*(?:if|ifdef|ifndef)?\s+(.*?)$/s) { + $self->_update_c_position($_, \$line, \$column); + } elsif(/^\#\s*include\s+(.*?)$/s) { + $self->_update_c_position($_, \$line, \$column); + } elsif(/^\#\s*undef\s+(.*?)$/s) { + $self->_update_c_position($_, \$line, \$column); + } else { + $self->_parse_c_error($_, $line, $column, "preprocessor"); + } + + $$refcurrent = $_; + $$refline = $line; + $$refcolumn = $column; + + return 1; +} + +######################################################################## +# parse_c_statement + +sub parse_c_statement { + my $self = shift; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + my $found_function_call = \${$self->{FOUND_FUNCTION_CALL}}; + + local $_ = $$refcurrent; + my $line = $$refline; + my $column = $$refcolumn; + + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); if(s/^(?:case\s+)?(\w+)\s*://) { $column += length($&); - parse_c_until_one_of("\\S", \$_, \$line, \$column); + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); } # $output->write("$line.$column: '$_'\n"); @@ -326,10 +953,10 @@ sub parse_c_statement { my $statements; my $statements_line; my $statements_column; - if(!parse_c_block(\$_, \$line, \$column, \$statements, \$statements_line, \$statements_column)) { + if(!$self->parse_c_block(\$_, \$line, \$column, \$statements, \$statements_line, \$statements_column)) { return 0; } - if(!parse_c_statements(\$statements, \$statements_line, \$statements_column, $found_function_call_callback)) { + if(!$self->parse_c_statements(\$statements, \$statements_line, \$statements_column)) { return 0; } } elsif(/^(for|if|switch|while)(\s*)\(/) { @@ -341,35 +968,34 @@ sub parse_c_statement { my @arguments; my @argument_lines; my @argument_columns; - if(!parse_c_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) { + if(!$self->parse_c_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) { return 0; } - parse_c_until_one_of("\\S", \$_, \$line, \$column); - if(!parse_c_statement(\$_, \$line, \$column, $found_function_call_callback)) { + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + if(!$self->parse_c_statement(\$_, \$line, \$column)) { return 0; } - parse_c_until_one_of("\\S", \$_, \$line, \$column); + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); while(defined(my $argument = shift @arguments) && defined(my $argument_line = shift @argument_lines) && defined(my $argument_column = shift @argument_columns)) { - parse_c_expression(\$argument, \$argument_line, \$argument_column, $found_function_call_callback); + $self->parse_c_expression(\$argument, \$argument_line, \$argument_column); } } elsif(s/^else//) { $column += length($&); - if(!parse_c_statement(\$_, \$line, \$column, $found_function_call_callback)) { + if(!$self->parse_c_statement(\$_, \$line, \$column)) { return 0; } - } elsif(parse_c_expression(\$_, \$line, \$column, $found_function_call_callback)) { + } elsif($self->parse_c_expression(\$_, \$line, \$column)) { # Nothing } else { - # $output->write("error '$_'\n"); - # exit 1; + # $self->_parse_c_error($_, $line, $column, "statement"); } - _update_c_position($_, \$line, \$column); + $self->_update_c_position($_, \$line, \$column); $$refcurrent = $_; $$refline = $line; @@ -378,18 +1004,24 @@ sub parse_c_statement { return 1; } +######################################################################## +# parse_c_statements + sub parse_c_statements { + my $self = shift; + my $refcurrent = shift; my $refline = shift; my $refcolumn = shift; - my $found_function_call_callback = shift; + my $found_function_call = \${$self->{FOUND_FUNCTION_CALL}}; + + local $_ = $$refcurrent; my $line = $$refline; my $column = $$refcolumn; - local $_ = $$refcurrent; + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); - parse_c_until_one_of("\\S", \$_, \$line, \$column); my $statement = ""; my $statement_line = $line; my $statement_column = $column; @@ -398,7 +1030,7 @@ sub parse_c_statements { my $plevel = 1; while($plevel > 0 || $blevel > 0) { my $match; - parse_c_until_one_of("\\(\\)\\[\\]\\{\\};", \$_, \$line, \$column, \$match); + $self->_parse_c_until_one_of("\\(\\)\\[\\]\\{\\};", \$_, \$line, \$column, \$match); # $output->write("'$match' '$_'\n"); @@ -410,8 +1042,7 @@ sub parse_c_statements { } elsif(s/^[\)\]]//) { $plevel--; if($plevel <= 0) { - $output->write("error $plevel: '$statement' '$match' '$_'\n"); - exit 1; + $self->_parse_c_error($_, $line, $column, "statements"); } $statement .= $&; } elsif(s/^\{//) { @@ -421,21 +1052,21 @@ sub parse_c_statements { $blevel--; $statement .= $&; if($blevel == 1) { - if(!parse_c_statement(\$statement, \$statement_line, \$statement_column, $found_function_call_callback)) { + if(!$self->parse_c_statement(\$statement, \$statement_line, \$statement_column)) { return 0; } - parse_c_until_one_of("\\S", \$_, \$line, \$column); + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); $statement = ""; $statement_line = $line; $statement_column = $column; } } elsif(s/^;//) { if($plevel == 1 && $blevel == 1) { - if(!parse_c_statement(\$statement, \$statement_line, \$statement_column, $found_function_call_callback)) { + if(!$self->parse_c_statement(\$statement, \$statement_line, \$statement_column)) { return 0; } - parse_c_until_one_of("\\S", \$_, \$line, \$column); + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); $statement = ""; $statement_line = $line; $statement_column = $column; @@ -446,12 +1077,11 @@ sub parse_c_statements { $plevel = 0; $blevel = 0; } else { - $output->write("error $plevel: '$statement' '$match' '$_'\n"); - exit 1; + $self->_parse_c_error($_, $line, $column, "statements"); } } - _update_c_position($_, \$line, \$column); + $self->_update_c_position($_, \$line, \$column); $$refcurrent = $_; $$refline = $line; @@ -460,7 +1090,12 @@ sub parse_c_statements { return 1; } +######################################################################## +# parse_c_tuple + sub parse_c_tuple { + my $self = shift; + my $refcurrent = shift; my $refline = shift; my $refcolumn = shift; @@ -489,7 +1124,7 @@ sub parse_c_tuple { my $plevel = 1; while($plevel > 0) { my $match; - parse_c_until_one_of("\\(,\\)", \$_, \$line, \$column, \$match); + $self->_parse_c_until_one_of("\\(,\\)", \$_, \$line, \$column, \$match); $column++; @@ -512,7 +1147,7 @@ sub parse_c_tuple { push @$item_lines, $item_line; push @$item_columns, $item_column; push @$items, $item; - parse_c_until_one_of("\\S", \$_, \$line, \$column); + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); $item_line = $line; $item_column = $column + 1; $item = ""; @@ -531,4 +1166,125 @@ sub parse_c_tuple { return 1; } +######################################################################## +# parse_c_type + +sub parse_c_type { + my $self = shift; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + my $reftype = shift; + + local $_ = $$refcurrent; + my $line = $$refline; + my $column = $$refcolumn; + + my $type; + + $self->_parse_c("const", \$_, \$line, \$column); + + + if(0) { + # Nothing + } elsif($self->_parse_c('ICOM_VTABLE\(.*?\)', \$_, \$line, \$column, \$type)) { + # Nothing + } elsif($self->_parse_c('\w+\s*(\*\s*)*', \$_, \$line, \$column, \$type)) { + # Nothing + } else { + return 0; + } + $type =~ s/\s//g; + + $$refcurrent = $_; + $$refline = $line; + $$refcolumn = $column; + + $$reftype = $type; + + return 1; +} + +######################################################################## +# parse_c_typedef + +sub parse_c_typedef { + my $self = shift; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + my $reftype = shift; + + local $_ = $$refcurrent; + my $line = $$refline; + my $column = $$refcolumn; + + my $type; + + if(!$self->_parse_c("typedef", \$_, \$line, \$column)) { + return 0; + } + + $$refcurrent = $_; + $$refline = $line; + $$refcolumn = $column; + + $$reftype = $type; + + return 1; +} + +######################################################################## +# parse_c_variable + +sub parse_c_variable { + my $self = shift; + + my $found_variable = \${$self->{FOUND_VARIABLE}}; + + my $refcurrent = shift; + my $refline = shift; + my $refcolumn = shift; + + my $reflinkage = shift; + my $reftype = shift; + my $refname = shift; + + local $_ = $$refcurrent; + my $line = $$refline; + my $column = $$refcolumn; + + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + + my $begin_line = $line; + my $begin_column = $column + 1; + + my $linkage = ""; + my $type; + my $name; + + $self->_parse_c("extern|static", \$_, \$line, \$column, \$linkage); + if(!$self->parse_c_type(\$_, \$line, \$column, \$type)) { return 0; } + if(!$self->_parse_c("\\w+", \$_, \$line, \$column, \$name)) { return 0; } + + $$refcurrent = $_; + $$refline = $line; + $$refcolumn = $column; + + $$reflinkage = $linkage; + $$reftype = $type; + $$refname = $name; + + if(&$$found_variable($begin_line, $begin_column, $linkage, $type, $name)) + { + # Nothing + } + + return 1; +} + 1; diff --git a/tools/winapi/make_parser.pm b/tools/winapi/make_parser.pm index ff0b5172fca..1fa6e9d205d 100644 --- a/tools/winapi/make_parser.pm +++ b/tools/winapi/make_parser.pm @@ -51,9 +51,9 @@ sub error { } if(defined($tool)) { - $output->write("make_filter: $context: can't parse output: '$current'\n"); + $output->write("$directory: $context: can't parse output: '$current'\n"); } else { - $output->write("make_filter: $context: can't parse output: '$current'\n"); + $output->write("$directory: $context: can't parse output: '$current'\n"); } exit 1; } @@ -133,8 +133,12 @@ sub line { # Nothing } elsif($tool eq "gcc" && /^(?:In file included |\s*)from (.+?):(\d+)[,:]$/) { # Nothing - } elsif($tool =~ /^gcc|ld$/ && s/^(.+?\.o(?:\(.*?\))?):\s*//) { - ld_output($1, $_) + } elsif($tool =~ /^gcc|ld$/ && s/^(.+?\.s?o)(?:\(.*?\))?:\s*//) { + $tool = "ld"; + ld_output($1, $_); + } elsif($tool =~ /^gcc|ld$/ && s/^collect2:\s*//) { + $tool = "ld"; + ld_output("collect2", $_); } elsif($tool eq "gcc" && s/^(.+?\.[chly]):\s*//) { gcc_output($1, $_); } elsif($tool eq "winebuild" && s/^(.+?\.spec):\s*//) { @@ -427,13 +431,13 @@ sub gcc_output { # Nothing } elsif(/^((?:signed |unsigned )?(?:int|long)) format, (different type|\S+) arg \(arg (\d+)\)$/) { my $type = $2; - if($type =~ /^ - HACCEL|HANDLE|HBITMAP|HBRUSH|HCALL|HCURSOR|HDC|HDRVR|HDESK| - HGDIOBJ|HKL|HGLOBAL|HINSTANCE|HKEY| + if($type =~ /^(?: + HACCEL|HACMDRIVER|HANDLE|HBITMAP|HBRUSH|HCALL|HCURSOR|HDC|HDRVR|HDESK|HDRAWDIB + HGDIOBJ|HKL|HGLOBAL|HIMC|HINSTANCE|HKEY|HLOCAL| HMENU|HMIDISTRM|HMIDIIN|HMIDIOUT|HMIXER|HMIXEROBJ|HMMIO|HMODULE| - HLINE|HPHONE|HPHONEAPP| - HRASCONN|HRGN|HRSRC|HWAVEIN|HWAVEOUT|HWINSTA|HWND|WSAEVENT| - handle_t|pointer$/x) + HLINE|HPEN|HPHONE|HPHONEAPP| + HRASCONN|HRGN|HRSRC|HWAVEIN|HWAVEOUT|HWINSTA|HWND| + SC_HANDLE|WSAEVENT|handle_t|pointer)$/x) { $supress = 1; } else { @@ -580,8 +584,14 @@ sub ld_output { $file = shift; local $_ = shift; - if(/^the use of \`(.+?)\' is dangerous, better use \`(.+?)\'$/) { - # nothing + if(0) { + # Nothing + } elsif(/^In function \`(.*?)\':$/) { + $function = $1; + } elsif(0 && /^the use of \`(.+?)\' is dangerous, better use \`(.+?)\'$/) { + # Nothing + } else { + $message = "$_"; } } diff --git a/tools/winapi/output.pm b/tools/winapi/output.pm index 018d63f3e3f..c6154ed0d4b 100644 --- a/tools/winapi/output.pm +++ b/tools/winapi/output.pm @@ -162,8 +162,13 @@ sub prefix { my $prefix = \${$self->{PREFIX}}; my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; - $$prefix = shift; - $$prefix_callback = undef; + my $new_prefix = shift; + if(defined($new_prefix)) { + $$prefix = $new_prefix; + $$prefix_callback = undef; + } else { + return $$prefix; + } } sub prefix_callback { diff --git a/tools/winapi/winapi_extract b/tools/winapi/winapi_extract index 842383698d4..efae0ed662e 100755 --- a/tools/winapi/winapi_extract +++ b/tools/winapi/winapi_extract @@ -16,6 +16,12 @@ use config qw( use output qw($output); use winapi_extract_options qw($options); +if($options->progress) { + $output->enable_progress; +} else { + $output->disable_progress; +} + use function; use type; use winapi_function; @@ -144,9 +150,7 @@ foreach my $file (@c_files) { my %functions; $progress_current++; - if($options->progress) { - $output->progress("$file: file $progress_current of $progress_max"); - } + $output->progress("$file (file $progress_current of $progress_max)"); my $create_function = sub { if($options->stub_statistics) { @@ -159,19 +163,20 @@ foreach my $file (@c_files) { my $found_function = sub { my $function = shift; + my $internal_name = $function->internal_name; + $functions{$internal_name} = $function; + + $output->progress("$file (file $progress_current of $progress_max): $internal_name"); + $output->prefix_callback(sub { return $function->prefix; }); + my $documentation_line = $function->documentation_line; my $documentation = $function->documentation; my $function_line = $function->function_line; my $linkage = $function->linkage; my $return_type = $function->return_type; my $calling_convention = $function->calling_convention; - my $internal_name = $function->internal_name; my $statements = $function->statements; - $functions{$internal_name} = $function; - - $output->prefix_callback(sub { return $function->prefix; }); - if($options->spec_files) { documentation_specifications($function); } diff --git a/tools/winapi/winapi_fixup b/tools/winapi/winapi_fixup index 3583143508c..6f79c368496 100755 --- a/tools/winapi/winapi_fixup +++ b/tools/winapi/winapi_fixup @@ -19,9 +19,14 @@ use config qw( use output qw($output); use winapi_fixup_options qw($options); +if($options->progress) { + $output->enable_progress; +} else { + $output->disable_progress; +} + +use c_parser; use type; -use winapi_function; -use winapi_parser; use winapi_fixup_documentation qw(&fixup_documentation); use winapi_fixup_editor; @@ -39,50 +44,109 @@ foreach my $file (@c_files) { my $editor = new winapi_fixup_editor($file); $progress_current++; - if($options->progress) { - $output->progress("$file (file $progress_current of $progress_max)"); - } + $output->progress("$file (file $progress_current of $progress_max)"); + $output->prefix("$file:"); - my $create_function = sub { - return 'winapi_function'->new; + { + open(IN, "< $file"); + local $/ = undef; + $_ = ; + close(IN); + } + + my $parser = new c_parser($file); + + my $found_preprocessor = sub { + my $begin_line = shift; + my $begin_column = shift; + my $preprocessor = shift; + + # $output->write("$begin_line.$begin_column: preprocessor: $preprocessor\n"); + + return 1; }; + $parser->set_found_preprocessor_callback($found_preprocessor); + + my $found_comment = sub { + my $begin_line = shift; + my $begin_column = shift; + my $comment = shift; + + # $output->write("$begin_line.$begin_column: comment: $comment\n"); + + return 1; + }; + + $parser->set_found_comment_callback($found_comment); + + my $found_declaration = sub { + my $begin_line = shift; + my $begin_column = shift; + my $end_line = shift; + my $end_column = shift; + my $declaration = shift; + + # $output->write("$begin_line.$begin_column-$end_line.$end_column: declaration: \\\n$declaration\n"); + + return 1; + }; + + $parser->set_found_declaration_callback($found_declaration); + + my $function; + my $found_function = sub { - my $function = shift; - - my $internal_name = $function->internal_name; - if($options->progress) { - $output->progress("$file (file $progress_current of $progress_max): $internal_name"); - } - - $output->prefix_callback(sub { return $function->prefix; }); - + $function = shift; + + my $name = $function->name; + my $begin_line = $function->begin_line; + my $begin_column = $function->begin_column; + + $output->progress("$file (file $progress_current of $progress_max): $name"); + $output->prefix("$file:$begin_line: function $name: "); + # $output->prefix_callback(sub { return $function->prefix; }); + if($options->documentation) { - fixup_documentation($function, $editor); + # fixup_documentation($function, $editor); } - + if($options->statements) { fixup_statements($function, $editor); } + + my $statements = $function->statements; + if(!defined($statements)) { + $function = undef; + $output->prefix("$file: "); + } - $output->prefix(""); + return 0; }; + + $parser->set_found_function_callback($found_function); - my $create_type = sub { - return 'type'->new; - }; - - my $found_type = sub { + my $found_variable = sub { + my $begin_line = shift; + my $begin_column = shift; + my $linkage = shift; my $type = shift; + my $name = shift; + + # $output->write("$begin_line.$begin_column: $linkage $type $name\n"); + + return 1; }; - my $found_preprocessor = sub { - my $directive = shift; - my $argument = shift; - }; + $parser->set_found_variable_callback($found_variable); - &winapi_parser::parse_c_file($file, $create_function, $found_function, $create_type, $found_type, $found_preprocessor); + my $line = 1; + my $column = 0; + if(!$parser->parse_c_file(\$_, \$line, \$column)) { + $output->write("can't parse file\n"); + } + + $output->prefix(""); $editor->flush; } - diff --git a/tools/winapi/winapi_fixup_editor.pm b/tools/winapi/winapi_fixup_editor.pm index 89331b40184..49f0bde2f8d 100644 --- a/tools/winapi/winapi_fixup_editor.pm +++ b/tools/winapi/winapi_fixup_editor.pm @@ -94,7 +94,7 @@ sub flush { my $line = $. - $lookahead_count; foreach my $action (@{$$triggers{$line}}) { - if($. < $action->{end_line}) { + if($. < $action->{end_line}) { $lookahead = 1; next LINE; } diff --git a/tools/winapi/winapi_fixup_options.pm b/tools/winapi/winapi_fixup_options.pm index 2acc7045188..c4a15e5db51 100644 --- a/tools/winapi/winapi_fixup_options.pm +++ b/tools/winapi/winapi_fixup_options.pm @@ -29,7 +29,7 @@ my %options_long = ( "documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" }, "documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" }, "statements" => { default => 1, parent => "local", description => "statements fixup" }, - "statements-windowsx" => { default => 1, parent => "local", description => "statements windowsx fixup" }, + "statements-windowsx" => { default => 0, parent => "local", description => "statements windowsx fixup" }, "stub" => { default => 0, parent => "local", description => "stub fixup" }, "global" => { default => 1, description => "global fixup" }, diff --git a/tools/winapi/winapi_fixup_statements.pm b/tools/winapi/winapi_fixup_statements.pm index f7706db0876..9eb648c6d69 100644 --- a/tools/winapi/winapi_fixup_statements.pm +++ b/tools/winapi/winapi_fixup_statements.pm @@ -9,10 +9,19 @@ require Exporter; @EXPORT = qw(); @EXPORT_OK = qw(&fixup_statements); +use config qw($wine_dir); use options qw($options); use output qw($output); use c_parser; +use winapi_module_user qw( + &get_message_result_kind + &get_message_wparam_kind + &get_message_lparam_kind +); + +######################################################################## +# fixup_function_call sub fixup_function_call { my $name = shift; @@ -21,37 +30,58 @@ sub fixup_function_call { return "$name(" . join(", ", @arguments) . ")"; } +######################################################################## +# _parse_makelong + sub _parse_makelong { - my $value = shift; + local $_ = shift; my $low; my $high; - if($value =~ /^ - (?:\(\w+\)\s*)? - MAKE(?:LONG|LPARAM|LRESULT|WPARAM)\s* - \(\s*(.*?)\s*,\s*(.*?)\s*\)$/sx) + + my $name; + my @arguments; + my @argument_lines; + my @argument_columns; + + my $parser = new c_parser; + + my $line = 1; + my $column = 0; + if($parser->parse_c_function_call(\$_, \$line, \$column, \$name, \@arguments, \@argument_lines, \@argument_columns) && + $name =~ /^MAKE(?:LONG|LPARAM|LRESULT|WPARAM)$/) { - $low = $1; - $high = $2; - } elsif($value =~ /^(?:\(\w+\)\s*)?0L?$/) { + $low = $arguments[0]; + $high = $arguments[1]; + } elsif(/^(?:\(\w+\)\s*)?0L?$/) { $low = "0"; $high = "0"; } else { - $low = "($value) & 0xffff"; - $high = "($value) << 16"; + $low = "($_) & 0xffff"; + $high = "($_) << 16"; } + $low =~ s/^\s*(.*?)\s*$/$1/; + $high =~ s/^\s*(.*?)\s*$/$1/; + return ($low, $high); } -sub fixup_function_call_2_forward_wm_call { +######################################################################## +# fixup_function_call_2_windowsx + +sub fixup_user_message_2_windowsx { my $name = shift; (my $hwnd, my $msg, my $wparam, my $lparam) = @{(shift)}; - if($msg =~ /^(?:WM_BEGINDRAG|WM_ENTERMENULOOP|WM_EXITMENULOOP|WM_HELP| - WM_ISACTIVEICON|WM_LBTRACKPOINT|WM_NEXTMENU)$/x) + if($msg !~ /^WM_/) { + return undef; + } elsif($msg =~ /^(?:WM_BEGINDRAG|WM_ENTERMENULOOP|WM_EXITMENULOOP|WM_HELP| + WM_ISACTIVEICON|WM_LBTRACKPOINT|WM_NEXTMENU)$/x) { return undef; + } elsif($msg =~ /^WM_(?:GET|SET)TEXT$/) { + return undef; } my $suffix; @@ -62,8 +92,8 @@ sub fixup_function_call_2_forward_wm_call { $suffix = ""; } - $wparam =~ s/^\(WPARAM\)//; - $lparam =~ s/^\(LPARAM\)//; + $wparam =~ s/^\(WPARAM\)\s*//; + $lparam =~ s/^\(LPARAM\)\s*//; my @arguments; if(0) { @@ -131,67 +161,161 @@ sub fixup_function_call_2_forward_wm_call { return "FORWARD_" . $msg . "(" . join(", ", @arguments) . ", $name)"; } +######################################################################## +# _fixup_user_message + +sub _get_messages { + local $_ = shift; + + if(/^WM_\w+$/) { + return ($_) + } elsif(/^(.*?)\s*\?\s*(WM_\w+)\s*:\s*(WM_\w+)$/) { + return ($2, $3); + } elsif(/^\w+$/) { + return (); + } else { + $output->write("_fixup_user_message: '$_'\n"); + exit 1; + } +} + +######################################################################## +# _fixup_user_message + +sub _fixup_user_message { + my $name = shift; + (my $hwnd, my $msg, my $wparam, my $lparam) = @{(shift)}; + + my $modified = 0; + + my $wkind; + my $lkind; + foreach my $msg (_get_messages($msg)) { + my $new_wkind = &get_message_wparam_kind($msg); + if(defined($wkind) && $new_wkind ne $wkind) { + $output->write("messsages used together do not have the same type\n"); + } else { + $wkind = $new_wkind; + } + + my $new_lkind = &get_message_lparam_kind($msg); + if(defined($lkind) && $new_lkind ne $lkind) { + $output->write("messsages used together do not have the same type\n"); + } else { + $lkind = $new_lkind; + } + } + + my @entries = ( + [ \$wparam, $wkind, "W", "w" ], + [ \$lparam, $lkind, "L", "l" ] + ); + foreach my $entry (@entries) { + (my $refparam, my $kind, my $upper, my $lower) = @$entry; + + if(!defined($kind)) { + if($msg =~ /^WM_/) { + $output->write("messsage $msg not defined\n"); + } + } elsif($kind eq "ptr") { + if($$refparam =~ /^(\(${upper}PARAM\))?\s*($lower[pP]aram)$/) { + if(defined($1)) { + $$refparam = $2; + $modified = 1; + } + } elsif($$refparam =~ /^(\(${upper}PARAM\))?\s*0$/) { + $$refparam = "(${upper}PARAM) NULL"; + $modified = 1; + } elsif($$refparam !~ /^\(${upper}PARAM\)\s*/) { + $$refparam = "(${upper}PARAM) $$refparam"; + $modified = 1; + } + } elsif($kind eq "long") { + if($$refparam =~ s/^\(${upper}PARAM\)\s*//) { + $modified = 1; + } + } + } + + if($modified) { + my @arguments = ($hwnd, $msg, $wparam, $lparam); + return "$name(" . join(", ", @arguments) . ")"; + } else { + return undef; + } +} + +######################################################################## +# fixup_statements + sub fixup_statements { my $function = shift; my $editor = shift; + my $file = $function->file; my $linkage = $function->linkage; - my $internal_name = $function->internal_name; + my $name = $function->name; my $statements_line = $function->statements_line; + my $statements_column = $function->statements_column; my $statements = $function->statements; - - if(($linkage eq "extern" && !defined($statements)) || - ($linkage eq "" && !defined($statements))) - { + + if(!defined($statements)) { return; } - - if($options->statements_windowsx && defined($statements)) { - my $found_function_call = sub { - my $begin_line = shift; - my $begin_column = shift; - my $end_line = shift; - my $end_column = shift; - my $name = shift; - my $arguments = shift; - - foreach my $argument (@$arguments) { - $argument =~ s/^\s*(.*?)\s*$/$1/; - } - if($options->statements_windowsx && - $name =~ /^(?:DefWindowProc|SendMessage)[AW]$/ && - $$arguments[1] =~ /^WM_\w+$/) - { - fixup_replace(\&fixup_function_call_2_forward_wm_call, $editor, - $begin_line, $begin_column, $end_line, $end_column, - $name, $arguments); - } elsif(0) { - $output->write("$begin_line.$begin_column-$end_line.$end_column: " . - "$name(" . join(", ", @$arguments) . ")\n"); - } - }; + if(0 && $statements_line > 490) { + $output->write("$statements_line: \\\n"); my $line = $statements_line; - my $column = 1; - - if(!&c_parser::parse_c_statements(\$statements, \$line, \$column, $found_function_call)) { - $output->write("error: can't parse statements\n"); + foreach my $statement (split(/\n/, $statements)) { + $output->write("$line: $statement\n"); + $line++; } } -} -sub fixup_replace { - my $function = shift; - my $editor = shift; - my $begin_line = shift; - my $begin_column = shift; - my $end_line = shift; - my $end_column = shift; + my $parser = new c_parser($file); + + my $found_function_call = sub { + my $begin_line = shift; + my $begin_column = shift; + my $end_line = shift; + my $end_column = shift; + my $name = shift; + my $arguments = shift; + + foreach my $argument (@$arguments) { + $argument =~ s/^\s*(.*?)\s*$/$1/; + } - my $replace = &$function(@_); + my $fixup_function_call; + if($name =~ /^(?:DefWindowProc|SendMessage)[AW]$/) + { + if($options->statements_windowsx) { + $fixup_function_call = \&fixup_user_message_2_windowsx; + } else { + $fixup_function_call = \&_fixup_user_message; + } + } - if(defined($replace)) { - $editor->replace($begin_line, $begin_column, $end_line, $end_column, $replace); + if(defined($fixup_function_call)) { + my $replace = &$fixup_function_call($name, $arguments); + + if(defined($replace)) { + $editor->replace($begin_line, $begin_column, $end_line, $end_column, $replace); + } + } elsif(0 || $options->debug) { + $output->write("$begin_line.$begin_column-$end_line.$end_column: " . + "$name(" . join(", ", @$arguments) . ")\n"); + } + + return 0; + }; + + $parser->set_found_function_call_callback($found_function_call); + + my $line = $statements_line; + my $column = 0; + if(!$parser->parse_c_statements(\$statements, \$line, \$column)) { + $output->write("error: can't parse statements\n"); } } diff --git a/tools/winapi/winapi_module_user.pm b/tools/winapi/winapi_module_user.pm new file mode 100644 index 00000000000..be853c5a9aa --- /dev/null +++ b/tools/winapi/winapi_module_user.pm @@ -0,0 +1,445 @@ +package winapi_module_user; + +use strict; + +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); +require Exporter; + +@ISA = qw(Exporter); +@EXPORT = qw(); +@EXPORT_OK = qw( + &is_user_function + &get_message_result_type + &get_message_result_kind + &get_message_wparam_type + &get_message_wparam_kind + &get_message_lparam_type + &get_message_lparam_kind +); + +use config qw($wine_dir); +use options qw($options); +use output qw($output); + +use c_parser; + +######################################################################## + +my $message; + +######################################################################## +# is_user_function + +sub is_user_function { + my $name = shift; + if($name =~ /^(?:DefWindowProc|SendMessage)[AW]?$/) { + } +} + +######################################################################## +# $message + +$message = { + WM_ACTIVATE => { + id => 0, result => "void", wparam => ["", ""], lparam => "HWND" }, + WM_ACTIVATEAPP => { + id => 0, result => "void", wparam => "BOOL", lparam => "LPARAM" }, + + WM_BEGINDRAG => { + id => 0, result => "", wparam => "", lparam => "" }, + + WM_CANCELMODE => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + WM_CHAR => { + id => 0, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + WM_CHARTOITEM => { + id => 0x002f, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, + WM_CLOSE => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + WM_COMMAND => { + id => 0, result => "void", wparam => ["int", "UINT"], lparam => "HWND" }, + WM_COPY => { + id => 0x0301, result => "void", wparam => "void", lparam => "void" }, + WM_COMPACTING => { + id => 0, result => "void", wparam => "UINT", lparam => "void" }, + WM_COMPAREITEM => { + id => 0, result => "int", wparam => "UINT", lparam => "const COMPAREITEMSTRUCT *" }, + + WM_CREATE => { + id => 0, result => "BOOL", wparam => "void", lparam => "LPCREATESTRUCT" }, + WM_CTLCOLORBTN => { + id => 0x0135, result => "HBRUSH", wparam => "HDC", lparam => "HWND" }, + WM_CTLCOLORDLG => { + id => 0x136, result => "HBRUSH", wparam => "HDC", lparam => "HWND" }, + WM_CTLCOLOREDIT => { + id => 0x133, result => "HBRUSH", wparam => "HDC", lparam => "HWND" }, + WM_CTLCOLORLISTBOX => { + id => 0x134, result => "HBRUSH", wparam => "HDC", lparam => "HWND" }, + WM_CTLCOLORMSGBOX => { + id => 0x132, result => "HBRUSH", wparam => "HDC", lparam => "HWND" }, + WM_CTLCOLORSCROLLBAR => { + id => 0x137, result => "HBRUSH", wparam => "HDC", lparam => "HWND" }, + WM_CTLCOLORSTATIC => { + id => 0x138, result => "HBRUSH", wparam => "HDC", lparam => "HWND" }, + + WM_CUT => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + + WM_DEADCHAR => { + id => 0, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + WM_DELETEITEM => { + id => 0, result => "void", wparam => "UINT", lparam => "const DELETEITEMSTRUCT *" }, + WM_DEVMODECHANGE => { + id => 0, result => "void", wparam => "void", lparam => "LPCTSTR" }, + WM_DESTROY => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + WM_DRAWITEM => { + id => 0, result => "void", wparam => "void", lparam => "const DRAWITEMSTRUCT *" }, + WM_DROPFILES => { + id => 0, result => "void", wparam => "HDROP", lparam => "void" }, + + WM_ENABLE => { + id => 0, result => "void", wparam => "BOOL", lparam => "void" }, + WM_ENDSESSION => { + id => 0, result => "void", wparam => "BOOL", lparam => "void" }, + WM_ENTERIDLE => { + id => 0x0121, result => "void", wparam => "UINT", lparam => "HWND" }, + WM_ENTERMENULOOP => { + id => 0x0211, result => "", wparam => "", lparam => "" }, + WM_ERASEBKGND => { + id => 0, result => "BOOL", wparam => "HDC", lparam => "void" }, + WM_EXITMENULOOP => { + id => 0x0212, result => "", wparam => "", lparam => "" }, + + WM_FONTCHANGE => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + + WM_GETTEXT => { + id => 0, result => "int", wparam => "int", lparam => "LPTSTR" }, + WM_GETTEXTLENGTH => { + id => 0, result => "int", wparam => "void", lparam => "void" }, + + WM_HELP => { + id => 0x0053, result => "", wparam => "", lparam => "" }, + WM_HSCROLL => { + id => 0, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, + + WM_ICONERASEBKGND => { + id => 0, result => "BOOL", wparam => "HDC", lparam => "void" }, + WM_INITMENU => { + id => 0, result => "void", wparam => "HMENU", lparam => "void" }, + WM_INITMENUPOPUP => { + id => 0, result => "void", wparam => "HMENU", lparam => ["UINT", "BOOL"] }, + WM_ISACTIVEICON => { + id => 0, result => "", wparam => "", lparam => "" }, + + WM_KEYDOWN => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_KEYUP => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_KILLFOCUS => { + id => 0, result => "void", wparam => "HWND", lparam => "void" }, + + WM_LBTRACKPOINT => { + id => 0, result => "", wparam => "", lparam => "" }, + WM_LBUTTONDBLCLK => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_LBUTTONDOWN => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_LBUTTONUP => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + + WM_MBUTTONDBLCLK => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_MBUTTONDOWN => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_MBUTTONUP => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_MEASUREITEM => { + id => 0, result => "void", wparam => "UINT", lparam => "MEASUREITEMSTRUCT *" }, + WM_MENUSELECT => { + id => 0, result => "void", wparam => ["", ""], lparam => "HMENU" }, + WM_MENUCHAR => { + id => 0, result => "DWORD", wparam => ["", ""], lparam => "HMENU" }, + WM_MOUSEACTIVATE => { + id => 0, result => "int", wparam => "HWND", lparam => ["", ""] }, + WM_MOUSEMOVE => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_MOVE => { + id => 0, result => "void", wparam => "void", lparam => ["", ""] }, + + WM_NCACTIVATE => { + id => 0, result => "BOOL", wparam => "BOOL", lparam => "void" }, + WM_NCLBUTTONDBLCLK => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCLBUTTONDOWN => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCLBUTTONUP => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCMOUSEMOVE => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCMBUTTONDBLCLK => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCMBUTTONDOWN => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCMBUTTONUP => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCRBUTTONDBLCLK => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCRBUTTONDOWN => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCRBUTTONUP => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_NCCALCSIZE => { + id => 0, result => "UINT", wparam => "void", lparam => "LPARAM" }, + WM_NCCREATE => { + id => 0, result => "BOOL", wparam => "void", lparam => "LPCREATESTRUCT" }, + WM_NCDESTROY => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + WM_NCPAINT => { + id => 0, result => "void", wparam => "HRGN", lparam => "void" }, + WM_NEXTMENU => { + id => 0x0213, result => "", wparam => "", lparam => "" }, + WM_NOTIFY => { + id => 0x004e, result => "LRESULT", wparam => "int", lparam => "NMHDR *" }, + + + WM_PALETTEISCHANGING => { + id => 0, result => "void", wparam => "HWND", lparam => "void" }, + WM_PALETTECHANGED => { + id => 0, result => "void", wparam => "HWND", lparam => "void" }, + WM_PAINT => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + WM_PASTE => { + id => 0x0302, result => "void", wparam => "void", lparam => "void" }, + WM_POWER => { + id => 0, result => "void", wparam => "int", lparam => "void" }, + + WM_QUERYDRAGICON => { + id => 0, result => "HICON", wparam => "void", lparam => "void" }, + WM_QUERYENDSESSION => { + id => 0, result => "BOOL", wparam => "void", lparam => "void" }, + WM_QUERYNEWPALETTE => { + id => 0, result => "BOOL", wparam => "void", lparam => "void" }, + WM_QUERYOPEN => { + id => 0, result => "BOOL", wparam => "void", lparam => "void" }, + WM_QUIT => { + id => 0, result => "void", wparam => "WPARAM", lparam => "void" }, + + WM_RBUTTONDBLCLK => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_RBUTTONDOWN => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_RBUTTONUP => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + + WM_SETCURSOR => { + id => 0x0020, result => "", wparam => "HWND", lparam => ["UINT", "UINT"] }, + WM_SETFOCUS => { + id => 0, result => "void", wparam => "HWND", lparam => "void" }, + WM_SETFONT => { + id => 0x0030, result => "void", wparam => "HFONT", lparam => "BOOL" }, + WM_SETREDRAW => { + id => 0, result => "void", wparam => "BOOL", lparam => "void" }, + WM_SETTEXT => { + id => 0, result => "void", wparam => "void", lparam => "LPCTSTR" }, + WM_SHOWWINDOW => { + id => 0, result => "void", wparam => "BOOL", lparam => "UINT" }, + WM_SIZE => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_SPOOLERSTATUS => { + id => 0, result => "void", wparam => "WPARAM", lparam => ["", ""] }, + WM_SYSCHAR => { + id => 0, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + WM_SYSCOLORCHANGE => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + WM_SYSDEADCHAR => { + id => 0, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + WM_SYSKEYDOWN => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_SYSKEYUP => { + id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + + WM_TIMECHANGE => { + id => 0, result => "void", wparam => "void", lparam => "void" }, + + WM_VKEYTOITEM => { + id => 0x002e, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, + WM_VSCROLL => { + id => 0, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, + + WM_WINDOWPOSCHANGING => { + id => 0, result => "BOOL", wparam => "void", lparam => "LPWINDOWPOS" }, + WM_WINDOWPOSCHANGED => { + id => 0, result => "void", wparam => "void", lparam => "LPARAM" }, + WM_WININICHANGE => { + id => 0, result => "void", wparam => "void", lparam => "LPCTSTR" } +}; + +######################################################################## +# _get_kind + +sub _get_kind { + local $_ = shift; + + if(!defined($_)) { + return undef; + } elsif(/^(?:HBRUSH|HDC|HFONT|HMENU|HRGN|HWND)$/ || /\*$/ || + /^LP(?!ARAM)/) + { + return "ptr"; + } else { + return "long"; + } +} + +######################################################################## +# get_message_result_type + +sub get_message_result_type { + my $name = shift; + return $$message{$name}{result}; +} + +######################################################################## +# get_message_result_kind + +sub get_message_result_kind { + return _get_kind(get_message_result_type(@_)); +} + +######################################################################## +# get_message_wparam_type + +sub get_message_wparam_type { + my $name = shift; + return $$message{$name}{wparam}; +} + +######################################################################## +# get_message_wparam_kind + +sub get_message_wparam_kind { + return _get_kind(get_message_wparam_type(@_)); +} + +######################################################################## +# get_message_lparam_type + +sub get_message_lparam_type { + my $name = shift; + return $$message{$name}{lparam}; +} + +######################################################################## +# get_message_lparam_kind + +sub get_message_lparam_kind { + return _get_kind(get_message_lparam_type(@_)); +} + +######################################################################## +# _parse_windowsx_h + +sub _parse_windowsx_h { + my $file = "$wine_dir/include/windowsx.h"; + { + open(IN, "< $file"); + local $/ = undef; + $_ = ; + close(IN); + } + + my $parser = new c_parser($file); + + my $found_preprocessor = sub { + my $begin_line = shift; + my $begin_column = shift; + local $_ = shift; + + if(!s/^\#\s*define\s*// || !/^FORWARD_WM_/) { + return 1; + } + + my $msg; + if(s/^FORWARD_(\w+)\([^\)]*\)\s*(.*?)\s*$/$2/s) { + $msg = $1; + } + + if($msg eq "WM_SYSTEMERROR") { + return 1; + } + + my $return_type; + if(s/^\(\s*(\w+)\s*\)(?:\(\s*\w+\s*\))*\(\s*\w+\s*\)\(\s*(?:hwnd|\(hwnd\))\s*,\s*(.*?)\s*\)$/$2/) { + $return_type = $1; + } else { + die "$msg: '$_'"; + } + + my @msgs = (); + if(s/^$msg\s*,\s*//) { + @msgs = $msg; + } elsif(s/^\(\w+\)\s*\?\s*(\w+)\s*:\s*(\w+)\s*,\s*//s) { + @msgs = ($1, $2); + } else { + die "$msg: '$_'"; + } + + my $wparam; + if(s/^\(WPARAM\)(?:\(\s*(\w+)\s*\))*\((.*?)\)\s*,\s*//) { + if(defined($1)) { + $wparam = $1; + } else { + $wparam = "WPARAM"; + } + } elsif(s/^MAKEWPARAM\(\s*(.*?)\s*,\s*(.*?)\s*\)\s*,\s*//) { + $wparam = "(,)"; # "($1, $2)"; + } elsif(s/^\((.*?)\)$//) { + $wparam = "WPARAM"; + } elsif(s/^0L\s*,\s*//) { + $wparam = "void"; + } else { + die "$msg: '$_'"; + } + + my $lparam; + if(s/^\(LPARAM\)(?:\(\s*(\w+)\s*\))*\((.*?)\)$//) { + if(defined($1)) { + $lparam = $1; + } else { + $lparam = "LPARAM"; + } + } elsif(s/^MAKELPARAM\(\s*(.*?)\s*,\s*(.*?)\s*\)$//) { + $lparam = "(,)"; # "($1, $2)"; + } elsif(s/^\((.*?)\)$//) { + $lparam = "LPARAM"; + } elsif(s/^0L$//) { + $lparam = "void"; + } else { + die "$msg: '$_'"; + } + + foreach my $msg (@msgs) { + $output->write("$msg => { result => \"$return_type\", wparam => \"$wparam\", lparam => \"$lparam\" },\n"); + } + + return 1; + }; + + $parser->set_found_preprocessor_callback($found_preprocessor); + + my $line = 1; + my $column = 0; + + my $old_prefix = $output->prefix; + $output->progress("$file"); + $output->prefix("$file: "); + + if(!$parser->parse_c_file(\$_, \$line, \$column)) { + $output->write("can't parse file\n"); + } + + $output->prefix($old_prefix); +} + diff --git a/tools/winapi_check/modules.pm b/tools/winapi_check/modules.pm index 1880b490b36..a6598b6736d 100644 --- a/tools/winapi_check/modules.pm +++ b/tools/winapi_check/modules.pm @@ -70,9 +70,7 @@ sub new { my $module_file = "$winapi_check_dir/modules.dat"; - if($options->progress) { - $output->progress("modules.dat"); - } + $output->progress("modules.dat"); my %spec_file_found; my $allowed_dir; diff --git a/tools/winapi_check/nativeapi.pm b/tools/winapi_check/nativeapi.pm index dc5bf38d349..969e58ca157 100644 --- a/tools/winapi_check/nativeapi.pm +++ b/tools/winapi_check/nativeapi.pm @@ -36,9 +36,7 @@ sub new { $configure_in_file =~ s/^\.\///; $config_h_in_file =~ s/^\.\///; - if($options->progress) { - $output->progress("$api_file"); - } + $output->progress("$api_file"); open(IN, "< $api_file"); local $/ = "\n"; @@ -51,9 +49,7 @@ sub new { } close(IN); - if($options->progress) { - $output->progress("$configure_in_file"); - } + $output->progress("$configure_in_file"); my $again = 0; open(IN, "< $configure_in_file"); @@ -102,9 +98,7 @@ sub new { } close(IN); - if($options->progress) { - $output->progress("$config_h_in_file"); - } + $output->progress("$config_h_in_file"); open(IN, "< $config_h_in_file"); local $/ = "\n"; diff --git a/tools/winapi_check/win32/kernel32.api b/tools/winapi_check/win32/kernel32.api index a062a4e32b7..2106c836b65 100644 --- a/tools/winapi_check/win32/kernel32.api +++ b/tools/winapi_check/win32/kernel32.api @@ -136,8 +136,6 @@ PLARGE_INTEGER PLONG PTIMERAPCROUTINE PULARGE_INTEGER -PVOID -PVOID * SECURITY_ATTRIBUTES * SYSLEVEL * SYSLEVEL ** diff --git a/tools/winapi_check/win32/oleaut32.api b/tools/winapi_check/win32/oleaut32.api index 5eebc418f99..616df9dc564 100644 --- a/tools/winapi_check/win32/oleaut32.api +++ b/tools/winapi_check/win32/oleaut32.api @@ -66,10 +66,12 @@ LPFONTDESC LPOCPFIPARAMS LPPICTDESC LPSTREAM +LPSYSTEMTIME LPUNKNOWN LPUNKNOWN * LPVOID LPVOID * +NUMPARSE * OLECHAR * OLECHAR ** REFCLSID @@ -78,6 +80,7 @@ REFIID SAFEARRAY * SAFEARRAY ** SAFEARRAYBOUND * +UDATE * UINT * ULONG * USHORT * diff --git a/tools/winapi_check/win32/quartz.api b/tools/winapi_check/win32/quartz.api index b4d509696a5..c9b87919974 100644 --- a/tools/winapi_check/win32/quartz.api +++ b/tools/winapi_check/win32/quartz.api @@ -1,6 +1,5 @@ %long -DWORD HRESULT %ptr diff --git a/tools/winapi_check/win32/shell32.api b/tools/winapi_check/win32/shell32.api index 20ce34709e5..d4afdf25b2a 100644 --- a/tools/winapi_check/win32/shell32.api +++ b/tools/winapi_check/win32/shell32.api @@ -6,6 +6,7 @@ DWORD HANDLE HBITMAP HDROP +HGLOBAL HMENU HICON HINSTANCE diff --git a/tools/winapi_check/win32/ttydrv.api b/tools/winapi_check/win32/ttydrv.api index e08e9d34a75..39439a3a173 100644 --- a/tools/winapi_check/win32/ttydrv.api +++ b/tools/winapi_check/win32/ttydrv.api @@ -43,7 +43,7 @@ POINT * RECT * WINDOWPOS * struct tagCURSORICONINFO * -struct tagWND * + void * %str diff --git a/tools/winapi_check/win32/x11drv.api b/tools/winapi_check/win32/x11drv.api index 77363b9bef4..f81114539b4 100644 --- a/tools/winapi_check/win32/x11drv.api +++ b/tools/winapi_check/win32/x11drv.api @@ -53,7 +53,6 @@ POINT * RECT * TEXTMETRICW * WINDOWPOS * -WND * void * %str diff --git a/tools/winapi_check/winapi.pm b/tools/winapi_check/winapi.pm index 4eb33e47adb..b7d32fe5501 100644 --- a/tools/winapi_check/winapi.pm +++ b/tools/winapi_check/winapi.pm @@ -105,9 +105,7 @@ sub parse_api_file { my $extension = 0; my $forbidden = 0; - if($options->progress) { - $output->lazy_progress("$file"); - } + $output->lazy_progress("$file"); open(IN, "< $wine_dir/$file") || die "$wine_dir/$file: $!\n"; $/ = "\n"; @@ -217,9 +215,7 @@ sub parse_spec_file { my $module; my $module_file; - if($options->progress) { - $output->lazy_progress("$file"); - } + $output->lazy_progress("$file"); open(IN, "< $file") || die "$file: $!\n"; $/ = "\n"; diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check index b7feb3744e4..16b6102635d 100755 --- a/tools/winapi_check/winapi_check +++ b/tools/winapi_check/winapi_check @@ -26,6 +26,13 @@ use config qw( ); use output qw($output); use winapi_check_options qw($options); + +if($options->progress) { + $output->enable_progress; +} else { + $output->disable_progress; +} + use modules qw($modules); use nativeapi qw($nativeapi); use winapi qw($win16api $win32api @winapis); @@ -50,9 +57,7 @@ my %include2info; foreach my $file (@files) { $progress_current++; - if($options->progress) { - $output->lazy_progress("$file: file $progress_current of $progress_max"); - } + $output->lazy_progress("$file: file $progress_current of $progress_max"); my $file_dir = $file; if(!($file_dir =~ s%(.*?)/[^/]+$%$1%)) { @@ -128,9 +133,7 @@ if($options->headers) { my %functions; $progress_current++; - if($options->progress) { - $output->progress("$file: file $progress_current of $progress_max"); - } + $output->progress("$file: file $progress_current of $progress_max"); my $create_function = sub { return 'winapi_function'->new; @@ -139,11 +142,13 @@ if($options->headers) { my $found_function = sub { my $function = shift; + my $internal_name = $function->internal_name; + + $output->progress("$file (file $progress_current of $progress_max): $internal_name"); $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; @@ -200,9 +205,7 @@ foreach my $file (@c_files) { my $file_module32 = $modules->allowed_modules_in_file("$current_dir/$file"); $progress_current++; - if($options->progress) { - $output->progress("$file: file $progress_current of $progress_max"); - } + $output->progress("$file (file $progress_current of $progress_max)"); my $file_dir = $file; if(!($file_dir =~ s/(.*?)\/[^\/]*$/$1/)) { @@ -216,11 +219,12 @@ foreach my $file (@c_files) { my $found_function = sub { my $function = shift; - $output->prefix_callback(sub { return $function->prefix; }); - my $internal_name = $function->internal_name; $functions{$internal_name} = $function; + $output->progress("$file (file $progress_current of $progress_max): $internal_name"); + $output->prefix_callback(sub { return $function->prefix; }); + my $declared_function = $declared_functions{$internal_name}; my $documentation_line = $function->documentation_line;