diff --git a/tools/winapi/c_parser.pm b/tools/winapi/c_parser.pm index 87c880c6d5f5f437b12ac6b05e9f1d5b9cdb0463..ac517e65715bf65ca2b0c6d164c502d97ba1bfb6 100644 --- a/tools/winapi/c_parser.pm +++ b/tools/winapi/c_parser.pm @@ -29,6 +29,7 @@ sub new { my $create_function = \${$self->{CREATE_FUNCTION}}; my $found_function = \${$self->{FOUND_FUNCTION}}; my $found_function_call = \${$self->{FOUND_FUNCTION_CALL}}; + my $found_line = \${$self->{FOUND_LINE}}; my $found_preprocessor = \${$self->{FOUND_PREPROCESSOR}}; my $found_statement = \${$self->{FOUND_STATEMENT}}; my $found_variable = \${$self->{FOUND_VARIABLE}}; @@ -40,6 +41,7 @@ sub new { $$create_function = sub { return new c_function; }; $$found_function = sub { return 1; }; $$found_function_call = sub { return 1; }; + $$found_line = sub { return 1; }; $$found_preprocessor = sub { return 1; }; $$found_statement = sub { return 1; }; $$found_variable = sub { return 1; }; @@ -91,6 +93,17 @@ sub set_found_function_call_callback { $$found_function_call = shift; } +######################################################################## +# set_found_line_callback +# +sub set_found_line_callback { + my $self = shift; + + my $found_line = \${$self->{FOUND_LINE}}; + + $$found_line = shift; +} + ######################################################################## # set_found_preprocessor_callback # @@ -162,6 +175,8 @@ sub _parse_c { ######################################################################## # _parse_c_error +# +# FIXME: Use caller (See man perlfunc) sub _parse_c_error { my $self = shift; @@ -172,40 +187,43 @@ sub _parse_c_error { my $line = shift; my $column = shift; my $context = shift; + my $message = shift; - my @lines = split(/\n/, $_); + $message = "parse error" if !$message; - my $current = "\n"; - $current .= $lines[0] . "\n" || ""; - $current .= $lines[1] . "\n" || ""; + my $current = ""; + if($_) { + my @lines = split(/\n/, $_); + + $current .= $lines[0] . "\n" if $lines[0]; + $current .= $lines[1] . "\n" if $lines[1]; + } if($output->prefix) { $output->write("\n"); $output->prefix(""); } - $output->write("$$file:$line." . ($column + 1) . ": $context: parse error: \\$current"); + + if($current) { + $output->write("$$file:$line." . ($column + 1) . ": $context: $message: \\\n$current"); + } else { + $output->write("$$file:$line." . ($column + 1) . ": $context: $message\n"); + } exit 1; } ######################################################################## -# _parse_c_output +# _parse_c_warning -sub _parse_c_output { +sub _parse_c_warning { 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"); + $output->write("$line." . ($column + 1) . ": $message\n"); } ######################################################################## @@ -472,23 +490,25 @@ sub parse_c_declaration { # 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) { + } elsif(s/^__ASM_GLOBAL_FUNC\(\s*(\w+)\s*,\s*//s) { # FIXME: Wine specific kludge $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; + $self->_parse_c_until_one_of("\)", \$_, \$line, \$column); + if(s/\)//) { + $column++; } + } elsif(s/^(?:jump|strong)_alias//s) { # FIXME: GNU C library specific kludge + } elsif(s/^extern\s*\"C\"\s*{//s) { + $self->_update_c_position($&, \$line, \$column); + } elsif(s/^(?:__asm__|asm)\s*\(//) { + $self->_update_c_position($&, \$line, \$column); + } elsif($self->parse_c_typedef(\$_, \$line, \$column)) { + # Nothing + } elsif($self->parse_c_variable(\$_, \$line, \$column, \$linkage, \$type, \$name)) { + # Nothing } elsif($self->parse_c_function(\$_, \$line, \$column, \$function)) { if(&$$found_function($function)) { @@ -502,10 +522,6 @@ sub parse_c_declaration { } } } - } 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"); } @@ -548,38 +564,33 @@ sub parse_c_expression { $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); - if(s/^(.*?)(\w+\s*\()/$2/s) { - $column += length($1); - - my $begin_line = $line; - my $begin_column = $column + 1; - - my $name; - my @arguments; - my @argument_lines; - my @argument_columns; - if(!$self->parse_c_function_call(\$_, \$line, \$column, \$name, \@arguments, \@argument_lines, \@argument_columns)) { - return 0; - } - - if($name =~ /^sizeof$/ || - &$$found_function_call($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)) + while($_) { + if(s/^(.*?)(\w+\s*\()/$2/s) { + $self->_update_c_position($1, \$line, \$column); + + my $begin_line = $line; + my $begin_column = $column + 1; + + my $name; + my @arguments; + my @argument_lines; + my @argument_columns; + if(!$self->parse_c_function_call(\$_, \$line, \$column, \$name, \@arguments, \@argument_lines, \@argument_columns)) { + return 0; + } + + if(&$$found_function_call($begin_line, $begin_column, $line, $column, $name, \@arguments)) { - $self->parse_c_expression(\$argument, \$argument_line, \$argument_column); + 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); + } } + } else { + $_ = ""; } - } elsif(s/^return//) { - $column += length($&); - $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); - if(!$self->parse_c_expression(\$_, \$line, \$column)) { - return 0; - } - } else { - return 0; } $self->_update_c_position($_, \$line, \$column); @@ -598,6 +609,7 @@ sub parse_c_file { my $self = shift; my $found_comment = \${$self->{FOUND_COMMENT}}; + my $found_line = \${$self->{FOUND_LINE}}; my $refcurrent = shift; my $refline = shift; @@ -614,24 +626,46 @@ sub parse_c_file { my $previous_line = 0; my $previous_column = -1; + my $if = 0; + my $if0 = 0; + 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"); + + if($line != $previous_line) { + &$$found_line($line); + } elsif($column == $previous_column) { + $self->_parse_c_error($_, $line, $column, "file", "no progress"); + } else { + # &$$found_line("$line.$column"); } $previous_line = $line; $previous_column = $column; - # $self->_parse_c_output($_, $line, $column, "'$match'"); + # $output->write("file: $plevel $blevel: '$match'\n"); if(!$declaration && $match =~ s/^\s+//s) { $self->_update_c_position($&, \$declaration_line, \$declaration_column); } - $declaration .= $match; + if(!$if0) { + $declaration .= $match; + } else { + my $blank_lines = 0; + + local $_ = $match; + while(s/^.*?\n//) { $blank_lines++; } + + if(!$declaration) { + $declaration_line = $line; + $declaration_column = $column; + } else { + $declaration .= "\n" x $blank_lines; + } + + } if(/^[\#\/]/) { my $blank_lines = 0; @@ -644,7 +678,14 @@ sub parse_c_file { $blank_lines++; $preprocessor .= "$1\n"; } - if(s/^(.*?)(\/[\*\/].*)?\n//) { + if(s/^(.*?)(\/\*.*?\*\/)(.*?)\n//) { + $_ = "$2\n$_"; + if(defined($3)) { + $preprocessor .= "$1$3"; + } else { + $preprocessor .= $1; + } + } elsif(s/^(.*?)(\/[\*\/].*?)?\n//) { if(defined($2)) { $_ = "$2\n$_"; } else { @@ -653,24 +694,44 @@ sub parse_c_file { $preprocessor .= $1; } + if($if0 && $preprocessor =~ /^\#\s*endif/) { + if($if0 > 0) { + if($if > 0) { + $if--; + } else { + $if0--; + } + } + } elsif($preprocessor =~ /^\#\s*if/) { + if($preprocessor =~ /^\#\s*if\s*0/) { + $if0++; + } elsif($if0 > 0) { + $if++; + } + } + if(!$self->parse_c_preprocessor(\$preprocessor, \$preprocessor_line, \$preprocessor_column)) { - return 0; + return 0; + } + } + + if(s/^\/\*.*?\*\///s) { + &$$found_comment($line, $column + 1, $&); + local $_ = $&; + while(s/^.*?\n//) { + $blank_lines++; } - } - - if(s/^\/\*(.*?)\*\///s) { - &$$found_comment($line, $column + 1, "/*$1*/"); - my @lines = split(/\n/, $1); - if($#lines > 0) { - $blank_lines += $#lines; - } else { - $column += length($1); + if($_) { + $column += length($_); } } elsif(s/^\/\/(.*?)\n//) { - &$$found_comment($line, $column + 1, "//$1"); + &$$found_comment($line, $column + 1, $&); $blank_lines++; } elsif(s/^\///) { - $declaration .= $&; + if(!$if0) { + $declaration .= $&; + $column++; + } } $line += $blank_lines; @@ -681,27 +742,49 @@ sub parse_c_file { if(!$declaration) { $declaration_line = $line; $declaration_column = $column; - } else { + } elsif($blank_lines > 0) { $declaration .= "\n" x $blank_lines; } next; - } + } $column++; + + if($if0) { + s/^.//; + next; + } + if(s/^[\(\[]//) { $plevel++; $declaration .= $&; - } elsif(s/^[\)\]]//) { + } elsif(s/^\]//) { + $plevel--; + $declaration .= $&; + } elsif(s/^\)//) { $plevel--; $declaration .= $&; + if($plevel == 1 && $declaration =~ /^__ASM_GLOBAL_FUNC/) { + 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/^\{//) { $blevel++; $declaration .= $&; } elsif(s/^\}//) { $blevel--; $declaration .= $&; - if($plevel == 1 && $blevel == 1 && $declaration !~ /^typedef/) { + if($declaration =~ /^typedef/s || + $declaration =~ /^(?:const\s+|extern\s+|static\s+)*(?:struct|union)(?:\s+\w+)?\s*\{/s) + { + # Nothing + } elsif($plevel == 1 && $blevel == 1) { if(!$self->parse_c_declaration(\$declaration, \$declaration_line, \$declaration_column)) { return 0; } @@ -709,9 +792,20 @@ sub parse_c_file { $declaration = ""; $declaration_line = $line; $declaration_column = $column; + } elsif($column == 1) { + $self->_parse_c_error("", $line, $column, "file", "inner } ends on column 1"); } } elsif(s/^;//) { - if($plevel == 1 && $blevel == 1) { + $declaration .= $&; + if($blevel == 1 && + $declaration !~ /^typedef/ && + $declaration !~ /^(?:const\s+|extern\s+|static\s+)(?:struct|union)(?:\s+\w+)?\s*\{/s && + $declaration =~ /^(?:\w+\s*)*(?:(?:\*\s*)+|\s+)(\w+)\s*\(\s*(?:(?:\w+\s*,\s*)*\w+\s*)?\)(.*?);/s && + $1 ne "ICOM_VTABLE" && $2) # K&R + { + $self->_parse_c_warning($line, $column, "function $1: warning: function has K&R format"); + } elsif($plevel == 1 && $blevel == 1) { + $declaration =~ s/\s*;$//; if($declaration && !$self->parse_c_declaration(\$declaration, \$declaration_line, \$declaration_column)) { return 0; } @@ -719,14 +813,12 @@ sub parse_c_file { $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"); + $self->_parse_c_error($_, $line, $column, "file", "'$declaration' '$match'"); } } @@ -772,21 +864,51 @@ sub parse_c_function { 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; + my $match; + while($self->_parse_c('const|inline|extern|static|volatile|' . + 'signed(?=\\s+char|s+int|\s+long(?:\s+long)?|\s+short)|' . + 'unsigned(?=\s+char|\s+int|\s+long(?:\s+long)?|\s+short)', + \$_, \$line, \$column, \$match)) + { + if($match =~ /^extern|static$/) { + if(!$linkage) { + $linkage = $match; + } + } } - $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(0) { + # Nothing + } elsif($self->_parse_c('DECL_GLOBAL_CONSTRUCTOR', \$_, \$line, \$column, \$name)) { # FIXME: Wine specific kludge + # Nothing + } elsif($self->_parse_c('WINE_EXCEPTION_FILTER\(\w+\)', \$_, \$line, \$column, \$name)) { # FIXME: Wine specific kludge + # Nothing + } else { + if(!$self->parse_c_type(\$_, \$line, \$column, \$return_type)) { + return 0; + } + + $self->_parse_c("__cdecl|__stdcall|inline|CDECL|VFWAPIV|VFWAPI|WINAPIV|WINAPI|CALLBACK|WINE_UNUSED|PASCAL", + \$_, \$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_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) { - return 0; + + my $kar; + # FIXME: Implement proper handling of K&R C functions + $self->_parse_c_until_one_of("{", \$_, \$line, \$column, $kar); + + if($kar) { + $output->write("K&R: $kar\n"); } + if($_ && !$self->parse_c_block(\$_, \$line, \$column, \$statements, \$statements_line, \$statements_column)) { return 0; } @@ -848,8 +970,8 @@ sub parse_c_function_call { my @argument_lines; my @argument_columns; - if(s/^(\w+)(\s*)\(/\(/s) { - $column += length("$1$2"); + if(s/^(\w+)(\s*)(?=\()//s) { + $self->_update_c_position($&, \$line, \$column); $name = $1; @@ -899,13 +1021,13 @@ sub parse_c_preprocessor { if(0) { # Nothing - } elsif(/^\#\s*define\s+(.*?)$/s) { + } 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) { + } elsif(/^\#\s*(?:if|ifdef|ifndef)?\s*(.*?)$/s) { $self->_update_c_position($_, \$line, \$column); } elsif(/^\#\s*include\s+(.*?)$/s) { $self->_update_c_position($_, \$line, \$column); @@ -940,12 +1062,9 @@ sub parse_c_statement { $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); - if(s/^(?:case\s+)?(\w+)\s*://) { - $column += length($&); - $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); - } + $self->_parse_c('(?:case\s+)?(\w+)\s*:\s*', \$_, \$line, \$column); - # $output->write("$line.$column: '$_'\n"); + # $output->write("$line.$column: statement: '$_'\n"); if(/^$/) { # Nothing @@ -959,11 +1078,10 @@ sub parse_c_statement { if(!$self->parse_c_statements(\$statements, \$statements_line, \$statements_column)) { return 0; } - } elsif(/^(for|if|switch|while)(\s*)\(/) { - $column += length("$1$2"); - my $name = $1; + } elsif(s/^(for|if|switch|while)\s*(?=\()//) { + $self->_update_c_position($&, \$line, \$column); - $_ = "($'"; + my $name = $1; my @arguments; my @argument_lines; @@ -985,10 +1103,16 @@ sub parse_c_statement { $self->parse_c_expression(\$argument, \$argument_line, \$argument_column); } } elsif(s/^else//) { - $column += length($&); + $self->_update_c_position($&, \$line, \$column); if(!$self->parse_c_statement(\$_, \$line, \$column)) { return 0; } + } elsif(s/^return//) { + $self->_update_c_position($&, \$line, \$column); + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + if(!$self->parse_c_expression(\$_, \$line, \$column)) { + return 0; + } } elsif($self->parse_c_expression(\$_, \$line, \$column)) { # Nothing } else { @@ -1022,20 +1146,31 @@ sub parse_c_statements { $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + # $output->write("$line.$column: statements: '$_'\n"); + my $statement = ""; my $statement_line = $line; my $statement_column = $column; + my $previous_line = -1; + 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($previous_line == $line && $previous_column == $column) { + $self->_parse_c_error($_, $line, $column, "statements", "no progress"); + } + $previous_line = $line; + $previous_column = $column; + # $output->write("'$match' '$_'\n"); - $column++; $statement .= $match; + $column++; if(s/^[\(\[]//) { $plevel++; $statement .= $&; @@ -1186,12 +1321,11 @@ sub parse_c_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 + } elsif($self->_parse_c('(?:enum\s+|struct\s+|union\s+)?\w+\s*(\*\s*)*', \$_, \$line, \$column, \$type)) { # Nothing } else { return 0; @@ -1225,7 +1359,11 @@ sub parse_c_typedef { my $type; - if(!$self->_parse_c("typedef", \$_, \$line, \$column)) { + if($self->_parse_c("typedef", \$_, \$line, \$column)) { + # Nothing + } elsif($self->_parse_c('enum(?:\s+\w+)?\s*\{', \$_, \$line, \$column)) { + # Nothing + } else { return 0; } @@ -1264,12 +1402,137 @@ sub parse_c_variable { my $begin_column = $column + 1; my $linkage = ""; - my $type; - my $name; + my $type = ""; + my $name = ""; + + my $match; + while($self->_parse_c('const|inline|extern|static|volatile|' . + 'signed(?=\\s+char|s+int|\s+long(?:\s+long)?|\s+short)|' . + 'unsigned(?=\s+char|\s+int|\s+long(?:\s+long)?|\s+short)', + \$_, \$line, \$column, \$match)) + { + if($match =~ /^extern|static$/) { + if(!$linkage) { + $linkage = $match; + } + } + } + + my $finished = 0; + + if($finished) { + # Nothing + } elsif($self->_parse_c('SEQ_DEFINEBUF', \$_, \$line, \$column, \$match)) { # Linux specific + $type = $match; + $finished = 1; + } elsif($self->_parse_c('DEFINE_GUID', \$_, \$line, \$column, \$match)) { # Windows specific + $type = $match; + $finished = 1; + } elsif($self->_parse_c('DEFINE_REGS_ENTRYPOINT_\w+|DPQ_DECL_\w+|HANDLER_DEF|IX86_ONLY', # Wine specific + \$_, \$line, \$column, \$match)) + { + $type = $match; + $finished = 1; + } elsif($self->_parse_c('(?:struct\s+)?ICOM_VTABLE\s*\(\w+\)', \$_, \$line, \$column, \$match)) { + $type = $match; + $finished = 1; + } elsif(s/^(?:enum\s+|struct\s+|union\s+)(\w+)?\s*\{.*?\}\s*//s) { + $self->_update_c_position($&, \$line, \$column); + + if(defined($1)) { + $type = "struct $1 { }"; + } else { + $type = "struct { }"; + } + if(defined($2)) { + my $stars = $2; + $stars =~ s/\s//g; + if($stars) { + $type .= " $type"; + } + } + } elsif(s/^((?:enum\s+|struct\s+|union\s+)?\w+)\s*(?:\*\s*)*//s) { + $type = $&; + $type =~ s/\s//g; + } else { + return 0; + } + + # $output->write("$type: '$_'\n"); + + if($finished) { + # Nothing + } elsif(s/^WINAPI\s*//) { + $self->_update_c_position($&, \$line, \$column); + } + + if($finished) { + # Nothing + } elsif(s/^(\((?:__cdecl)?\s*\*?\s*(?:__cdecl)?\w+\s*(?:\[[^\]]*\]\s*)*\))\s*\(//) { + $self->_update_c_position($&, \$line, \$column); + + $name = $1; + $name =~ s/\s//g; + + $self->_parse_c_until_one_of("\\)", \$_, \$line, \$column); + if(s/^\)//) { $column++; } + $self->_parse_c_until_one_of("\\S", \$_, \$line, \$column); + + if(!s/^(?:=\s*|,\s*|$)//) { + return 0; + } + } elsif(s/^(?:\*\s*)*(?:const\s+)?(\w+)\s*(?:\[[^\]]*\]\s*)*\s*(?:=\s*|,\s*|$)//) { + $self->_update_c_position($&, \$line, \$column); + + $name = $1; + $name =~ s/\s//g; + } elsif(/^$/) { + $name = ""; + } else { + return 0; + } + + # $output->write("$type: $name: '$_'\n"); + + if(1) { + # Nothing + } elsif($self->_parse_c('(?:struct\s+)?ICOM_VTABLE\s*\(.*?\)', \$_, \$line, \$column, \$match)) { + $type = "<type>"; + $name = "<name>"; + } elsif(s/^((?:enum\s+|struct\s+|union\s+)?\w+)\s* + (?:\*\s*)*(\w+|\s*\*?\s*\w+\s*\))\s*(?:\[[^\]]*\]|\([^\)]*\))? + (?:,\s*(?:\*\s*)*(\w+)\s*(?:\[[^\]]*\])?)* + \s*(?:=|$)//sx) + { + $self->_update_c_position($&, \$line, \$column); + + $type = $1; + $name = $2; + + $type =~ s/\s//g; + $type =~ s/^struct/struct /; + } elsif(/^(?:enum|struct|union)(?:\s+(\w+))?\s*\{.*?\}\s*((?:\*\s*)*)(\w+)\s*(?:=|$)/s) { + $self->_update_c_position($&, \$line, \$column); - $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; } + if(defined($1)) { + $type = "struct $1 { }"; + } else { + $type = "struct { }"; + } + my $stars = $2; + $stars =~ s/\s//g; + if($stars) { + $type .= " $type"; + } + + $name = $3; + } else { + return 0; + } + + if(!$name) { + $name = "<name>"; + } $$refcurrent = $_; $$refline = $line; diff --git a/tools/winapi/make_parser.pm b/tools/winapi/make_parser.pm index 1fa6e9d205d9d992f93e86eb7eb1197b42f8c605..3b389c590d1f8e5c1b05301e897387c08202640f 100644 --- a/tools/winapi/make_parser.pm +++ b/tools/winapi/make_parser.pm @@ -80,20 +80,22 @@ sub line { my $progress = ""; if($directory && $directory ne ".") { $progress .= "$directory: "; + } + if($tool) { + $progress .= "$tool: "; } - $progress .= "$tool: "; if($tool =~ /^cd|make$/) { # Nothing } elsif($tool =~ /^ld$/) { foreach my $file (@{$read_files}) { - $output->lazy_progress("$progress: reading '$file'"); + $output->lazy_progress("${progress}reading '$file'"); } my $file = $$write_files[0]; $output->progress("$progress: writing '$file'"); } elsif($tool =~ /^rm$/) { foreach my $file (@{$remove_files}) { - $output->lazy_progress("$progress: removing '$file'"); + $output->lazy_progress("${progress}removing '$file'"); } } else { if($#$read_files >= 0) { @@ -118,24 +120,34 @@ sub line { return 0; } + my $make = $options->make; + if(/^Wine build complete\.$/) { # Nothing } elsif(/^(.*?) is newer than (.*?), please rerun (.*?)\!$/) { $message = "$_"; } elsif(/^(.*?) is older than (.*?), please rerun (.*?)$/) { $message = "$_"; - } elsif(s/^make(?:\[(\d+)\])?:\s*//) { + } elsif(/^\`(.*?)\' is up to date.$/) { + $tool = "make"; + make_output($1, $_); + } elsif(s/^$make(?:\[(\d+)\])?:\s*//) { $tool = "make"; make_output($1, $_); } elsif(!defined($tool)) { error("line"); + } elsif($tool eq "make") { + make_output($1, $_); } elsif($tool eq "bison" && /^conflicts:\s+\d+\s+shift\/reduce$/) { # Nothing } elsif($tool eq "gcc" && /^(?:In file included |\s*)from (.+?):(\d+)[,:]$/) { # Nothing } elsif($tool =~ /^gcc|ld$/ && s/^(.+?\.s?o)(?:\(.*?\))?:\s*//) { $tool = "ld"; - ld_output($1, $_); + ld_output($1, $_) + } elsif($tool =~ /^gcc|ld$/ && s/^(.*?)ld:\s*//) { + $tool = "ld"; + ld_output("", $_) } elsif($tool =~ /^gcc|ld$/ && s/^collect2:\s*//) { $tool = "ld"; ld_output("collect2", $_); @@ -149,6 +161,8 @@ sub line { wrc_output($1, $_); } elsif($tool eq "cd" && s/^\/bin\/sh:\s*cd:\s*//) { parse_cd_output($_); + } elsif(/^\s*$/) { + # Nothing } else { error("line"); } @@ -172,7 +186,9 @@ sub make_output { if(0) { # Nothing } elsif(/^\*\*\* \[(.*?)\] Error (\d+)$/) { - $message = "$_"; + # Nothing + } elsif(/^\*\*\* Error code (\d+)$/) { + # Nothing } elsif(/^\*\*\* Warning:\s+/) { # if(/^File \`(.+?)\' has modification time in the future \((.+?) > \(.+?\)\)$/) { # Nothing @@ -183,6 +199,8 @@ sub make_output { # Nothing } elsif(/^\[(.*?)\] Error (\d+) \(ignored\)$/) { # Nothing + } elsif(/^don\'t know how to make (.*?)\. Stop$/) { + $message = "$_"; } elsif(/^(Entering|Leaving) directory \`(.*?)\'$/) { if($1 eq "Entering") { $directory = $2; @@ -209,6 +227,10 @@ sub make_output { } else { error("make_output"); } + } elsif(/^Stop in (.*?)\.$/) { + # Nothing + } elsif(/^\s*$/) { + # Nothing } else { error("make_output"); } @@ -399,13 +421,27 @@ sub gcc_command { my $write_files; if(/-o\s+(\S+)\s+(\S+)$/) { - $write_files = [$1]; - $read_files = [$2]; + my $write_file = $1; + my $read_file = $2; + + $write_file =~ s%^\./%%; + $read_file =~ s%^\./%%; + + $write_files = [$write_file]; + $read_files = [$read_file]; } elsif(/-o\s+(\S+)/) { - $write_files = [$1]; + my $write_file = $1; + + $write_file =~ s%^\./%%; + + $write_files = [$write_file]; $read_files = ["<???>"]; } elsif(/^-shared.*?-o\s+(\S+)/) { - $write_files = [$1]; + my $write_file = $1; + + $write_file =~ s%^\./%%; + + $write_files = [$write_file]; $read_files = ["<???>"]; } else { error("gcc_command"); @@ -588,8 +624,16 @@ sub ld_output { # Nothing } elsif(/^In function \`(.*?)\':$/) { $function = $1; - } elsif(0 && /^the use of \`(.+?)\' is dangerous, better use \`(.+?)\'$/) { + } elsif(/^more undefined references to \`(.*?)\' follow$/) { + # Nothing + } elsif(/^the use of \`(.+?)\' is dangerous, better use \`(.+?)\'$/) { # Nothing + } elsif(/^undefined reference to \`(.*?)\'$/) { + # Nothing + } elsif(/^warning: (.*?)\(\) possibly used unsafely; consider using (.*?)\(\)$/) { + # Nothing + } elsif(/^warning: type and size of dynamic symbol \`(.*?)\' are not defined$/) { + $message = "$_"; } else { $message = "$_"; } diff --git a/tools/winapi/options.pm b/tools/winapi/options.pm index 4f2e6c51c2b6414ba90fd294f09c2fa69de9c4db..3f7cdf6659b841d4cc6896b4fbf097853ffbf252 100644 --- a/tools/winapi/options.pm +++ b/tools/winapi/options.pm @@ -63,6 +63,7 @@ sub new { $self->options_set("default"); my $arguments = \@{$self->{_ARGUMENTS}}; + @$arguments = (); my $end_of_options = 0; while(defined($_ = shift @ARGV)) { @@ -121,6 +122,9 @@ sub new { } if(defined($parser)) { + if(!defined($value)) { + $value = shift @ARGV; + } $$refvalue = &$parser($prefix,$value); } else { if(defined($value)) { diff --git a/tools/winapi/output.pm b/tools/winapi/output.pm index c6154ed0d4b8bbec7e9cebb0b7193e244932f66d..49939740f82774cc566c4452bd6fbca163e21569 100644 --- a/tools/winapi/output.pm +++ b/tools/winapi/output.pm @@ -137,10 +137,17 @@ sub progress { my $progress = \${$self->{PROGRESS}}; my $last_time = \${$self->{LAST_TIME}}; - $$progress = shift; + my $new_progress = shift; + if(defined($new_progress)) { + if(!defined($$progress) || $new_progress ne $$progress) { + $$progress = $new_progress; - $self->update_progress; - $$last_time = 0; + $self->update_progress; + $$last_time = 0; + } + } else { + return $$progress; + } } sub lazy_progress { @@ -164,8 +171,10 @@ sub prefix { my $new_prefix = shift; if(defined($new_prefix)) { - $$prefix = $new_prefix; - $$prefix_callback = undef; + if(!defined($$prefix) || $new_prefix ne $$prefix) { + $$prefix = $new_prefix; + $$prefix_callback = undef; + } } else { return $$prefix; } diff --git a/tools/winapi/winapi_fixup b/tools/winapi/winapi_fixup index 6f79c368496ccb670e39812f5c217f7565590762..4ac4b3946ed89772a42b2868d5f6f3d0b8cdc6b5 100755 --- a/tools/winapi/winapi_fixup +++ b/tools/winapi/winapi_fixup @@ -53,9 +53,43 @@ foreach my $file (@c_files) { $_ = <IN>; close(IN); } - + + my $max_line = 0; + { + local $_ = $_; + while(s/^.*?\n//) { $max_line++; } + if($_) { $max_line++; } + } + my $parser = new c_parser($file); + my $function; + my $line; + + my $update_output = sub { + my $progress = ""; + my $prefix = ""; + + $progress .= "$file (file $progress_current of $progress_max)"; + $prefix .= "$file:"; + + if(defined($function)) { + my $name = $function->name; + my $begin_line = $function->begin_line; + my $begin_column = $function->begin_column; + + $progress .= ": function $name"; + $prefix .= "$begin_line.$begin_column: function $name: "; + } + + if(defined($line)) { + $progress .= ": line $line of $max_line"; + } + + $output->progress($progress); + $output->prefix($prefix); + }; + my $found_preprocessor = sub { my $begin_line = shift; my $begin_column = shift; @@ -80,6 +114,17 @@ foreach my $file (@c_files) { $parser->set_found_comment_callback($found_comment); + my $found_line = sub { + $line = shift; + # local $_ = shift; + + &$update_output; + + # $output->progress("$file: line $line of ?"); + }; + + $parser->set_found_line_callback($found_line); + my $found_declaration = sub { my $begin_line = shift; my $begin_column = shift; @@ -94,19 +139,17 @@ foreach my $file (@c_files) { $parser->set_found_declaration_callback($found_declaration); - my $function; - my $found_function = sub { $function = shift; - + + &$update_output; + 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; }); - + my $end_line = $function->end_line; + my $end_column = $function->end_column; + if($options->documentation) { # fixup_documentation($function, $editor); } @@ -119,6 +162,8 @@ foreach my $file (@c_files) { if(!defined($statements)) { $function = undef; $output->prefix("$file: "); + } else { + # $output->write("$begin_line.$begin_column-$end_line.$end_column: function $name\n"); } return 0; @@ -133,20 +178,38 @@ foreach my $file (@c_files) { my $type = shift; my $name = shift; - # $output->write("$begin_line.$begin_column: $linkage $type $name\n"); + # $output->write("$begin_line.$begin_column: $linkage $type $name = /* ... */\n"); return 1; }; $parser->set_found_variable_callback($found_variable); - my $line = 1; - my $column = 0; - if(!$parser->parse_c_file(\$_, \$line, \$column)) { - $output->write("can't parse file\n"); + 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; + + $output->write("$begin_line.$begin_column-$end_line.$end_column: $name(" . join(", ", @$arguments) . ")\n"); + + return 1; + }; + + $parser->set_found_function_call_callback($found_function_call); + + { + 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_statements.pm b/tools/winapi/winapi_fixup_statements.pm index 9eb648c6d693d5cde7b6bafb560adbadf7a88e53..83b92febfc777f7bf56da43eaf91c7ff1e02ff6b 100644 --- a/tools/winapi/winapi_fixup_statements.pm +++ b/tools/winapi/winapi_fixup_statements.pm @@ -162,20 +162,26 @@ sub fixup_user_message_2_windowsx { } ######################################################################## -# _fixup_user_message +# _get_messages sub _get_messages { local $_ = shift; - if(/^WM_\w+$/) { - return ($_) - } elsif(/^(.*?)\s*\?\s*(WM_\w+)\s*:\s*(WM_\w+)$/) { + if(/^(?:BM|CB|EM|LB|STM|WM)_\w+(.*?)$/) { + if(!$1) { + return ($_); + } else { + return (); + } + } elsif(/^(.*?)\s*\?\s*((?:BM|CB|EM|LB|STM|WM)_\w+)\s*:\s*((?:BM|CB|EM|LB|STM|WM)_\w+)$/) { return ($2, $3); } elsif(/^\w+$/) { return (); + } elsif(/^RegisterWindowMessage[AW]\s*\(.*?\)$/) { + return (); } else { - $output->write("_fixup_user_message: '$_'\n"); - exit 1; + $output->write("warning: _get_messages: '$_'\n"); + return (); } } @@ -215,7 +221,9 @@ sub _fixup_user_message { if(!defined($kind)) { if($msg =~ /^WM_/) { - $output->write("messsage $msg not defined\n"); + $output->write("messsage $msg not properly defined\n"); + $modified = 0; + last; } } elsif($kind eq "ptr") { if($$refparam =~ /^(\(${upper}PARAM\))?\s*($lower[pP]aram)$/) { @@ -263,15 +271,6 @@ sub fixup_statements { return; } - if(0 && $statements_line > 490) { - $output->write("$statements_line: \\\n"); - my $line = $statements_line; - foreach my $statement (split(/\n/, $statements)) { - $output->write("$line: $statement\n"); - $line++; - } - } - my $parser = new c_parser($file); my $found_function_call = sub { @@ -302,7 +301,7 @@ sub fixup_statements { if(defined($replace)) { $editor->replace($begin_line, $begin_column, $end_line, $end_column, $replace); } - } elsif(0 || $options->debug) { + } elsif($options->debug) { $output->write("$begin_line.$begin_column-$end_line.$end_column: " . "$name(" . join(", ", @$arguments) . ")\n"); } diff --git a/tools/winapi/winapi_module_user.pm b/tools/winapi/winapi_module_user.pm index be853c5a9aa5aece5e96909a6296708db6ea57e9..afb23dcdb39c9951147b6006c41ca325702400f1 100644 --- a/tools/winapi/winapi_module_user.pm +++ b/tools/winapi/winapi_module_user.pm @@ -41,32 +41,65 @@ sub is_user_function { $message = { WM_ACTIVATE => { - id => 0, result => "void", wparam => ["", ""], lparam => "HWND" }, + id => 0x0006, result => "void", wparam => ["", ""], lparam => "HWND" }, WM_ACTIVATEAPP => { - id => 0, result => "void", wparam => "BOOL", lparam => "LPARAM" }, + id => 0x001c, result => "void", wparam => "BOOL", lparam => "DWORD" }, + WM_ACTIVATESHELLWINDOW => { + id => 0x003e, result => "", wparam => "", lparam => "" }, + WM_ACTIVATETOPLEVEL => { + id => 0x036e, result => "", wparam => "", lparam => "" }, + WM_ALTTABACTIVE => { + id => 0x0029, result => "", wparam => "", lparam => "" }, + WM_APP => { + id => 0x8000, result => "", wparam => "", lparam => "" }, + WM_ASKCBFORMATNAME => { + id => 0x030c, result => "void", wparam => "int", lparam => "LPTSTR" }, WM_BEGINDRAG => { - id => 0, result => "", wparam => "", lparam => "" }, + id => 0x022c, result => "", wparam => "", lparam => "" }, WM_CANCELMODE => { - id => 0, result => "void", wparam => "void", lparam => "void" }, + id => 0x001f, result => "void", wparam => "void", lparam => "void" }, + WM_CANCELJOURNAL => { + id => 0x004b, result => "", wparam => "", lparam => "" }, + WM_CAPTURECHANGED => { + id => 0x0215, result => "void", wparam => "void", lparam => "HWND" }, + WM_CHANGECBCHAIN => { + id => 0x030d, result => "void", wparam => "HWND", lparam => "HWND" }, + WM_CHILDACTIVATE => { + id => 0x0022, result => "void", wparam => "void", lparam => "void" }, + WM_CLEAR => { + id => 0x0303, result => "void", wparam => "void", lparam => "void" }, WM_CHAR => { - id => 0, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + id => 0x0102, result => "void", wparam => "TCHAR", lparam => ["", ""] }, WM_CHARTOITEM => { - id => 0x002f, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, + id => 0x002f, result => "int", wparam => ["UINT", "UINT"], lparam => "HWND" }, WM_CLOSE => { - id => 0, result => "void", wparam => "void", lparam => "void" }, + id => 0x0010, result => "void", wparam => "void", lparam => "void" }, + WM_COALESCE_FIRST => { + id => 0x0390, result => "", wparam => "", lparam => "" }, + WM_COALESCE_LAST => { + id => 0x039f, result => "", wparam => "", lparam => "" }, WM_COMMAND => { - id => 0, result => "void", wparam => ["int", "UINT"], lparam => "HWND" }, + id => 0x0111, result => "void", wparam => ["UINT", "UINT"], lparam => "HWND" }, + WM_COMMANDHELP => { + id => 0x0365, result => "", wparam => "", lparam => "" }, + WM_COMMNOTIFY => { + id => 0x0044, result => "void", wparam => "int", lparam => ["", ""] }, + WM_CONTEXTMENU => { + id => 0x007b, result => "void", wparam => "HWND", lparam => ["UINT", "UINT"] }, WM_COPY => { id => 0x0301, result => "void", wparam => "void", lparam => "void" }, + WM_COPYDATA => { + id => 0x004a, result => "", wparam => "", lparam => "" }, WM_COMPACTING => { - id => 0, result => "void", wparam => "UINT", lparam => "void" }, + id => 0x0041, result => "void", wparam => "UINT", lparam => "void" }, WM_COMPAREITEM => { - id => 0, result => "int", wparam => "UINT", lparam => "const COMPAREITEMSTRUCT *" }, - + id => 0x0039, result => "int", wparam => "UINT", lparam => "const COMPAREITEMSTRUCT *" }, WM_CREATE => { - id => 0, result => "BOOL", wparam => "void", lparam => "LPCREATESTRUCT" }, + id => 0x0001, result => "BOOL", wparam => "void", lparam => "LPCREATESTRUCT" }, + WM_CTLCOLOR => { + id => 0x0019, result => "", wparam => "", lparam => "" }, WM_CTLCOLORBTN => { id => 0x0135, result => "HBRUSH", wparam => "HDC", lparam => "HWND" }, WM_CTLCOLORDLG => { @@ -81,199 +114,427 @@ $message = { 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" }, + id => 0x0300, result => "void", wparam => "void", lparam => "void" }, + WM_DDE_ACK => { # FIXME: Only correct if replying to WM_DDE_INITIATE + id => 0x03E4, result => "void", wparam => "HWND", lparam => ["ATOM", "ATOM"] }, + WM_DDE_INITIATE => { + id => 0x03E0, result => "void", wparam => "HWND", lparam => ["ATOM", "ATOM"] }, WM_DEADCHAR => { - id => 0, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + id => 0x0103, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + WM_DEVICECHANGE => { + id => 0x0219, result => "BOOL", wparam => "UINT", lparam => "DWORD" }, WM_DELETEITEM => { - id => 0, result => "void", wparam => "UINT", lparam => "const DELETEITEMSTRUCT *" }, + id => 0x002d, result => "void", wparam => "UINT", lparam => "const DELETEITEMSTRUCT *" }, WM_DEVMODECHANGE => { - id => 0, result => "void", wparam => "void", lparam => "LPCTSTR" }, + id => 0x001b, result => "void", wparam => "void", lparam => "LPCTSTR" }, WM_DESTROY => { - id => 0, result => "void", wparam => "void", lparam => "void" }, + id => 0x0002, result => "void", wparam => "void", lparam => "void" }, + WM_DESTROYCLIPBOARD => { + id => 0x0307, result => "void", wparam => "void", lparam => "void" }, + WM_DISABLEMODAL => { + id => 0x036c, result => "", wparam => "", lparam => "" }, + WM_DISPLAYCHANGE => { + id => 0x007e, result => "void", wparam => "UINT", lparam => ["UINT", "UINT"] }, + WM_DRAGLOOP => { + id => 0x022d, result => "", wparam => "", lparam => "" }, + WM_DRAGMOVE => { + id => 0x022f, result => "", wparam => "", lparam => "" }, + WM_DRAGSELECT => { + id => 0x022e, result => "", wparam => "", lparam => "" }, + WM_DRAWCLIPBOARD => { + id => 0x0308, result => "void", wparam => "void", lparam => "void" }, WM_DRAWITEM => { - id => 0, result => "void", wparam => "void", lparam => "const DRAWITEMSTRUCT *" }, + id => 0x002b, result => "void", wparam => "UINT", lparam => "const DRAWITEMSTRUCT *" }, WM_DROPFILES => { - id => 0, result => "void", wparam => "HDROP", lparam => "void" }, + id => 0x0233, result => "void", wparam => "HDROP", lparam => "void" }, + WM_DROPOBJECT => { + id => 0x022a, result => "", wparam => "", lparam => "" }, WM_ENABLE => { - id => 0, result => "void", wparam => "BOOL", lparam => "void" }, + id => 0x000a, result => "void", wparam => "BOOL", lparam => "void" }, WM_ENDSESSION => { - id => 0, result => "void", wparam => "BOOL", lparam => "void" }, + id => 0x0016, result => "void", wparam => "BOOL", lparam => "void" }, WM_ENTERIDLE => { id => 0x0121, result => "void", wparam => "UINT", lparam => "HWND" }, + WM_ENTERSIZEMOVE => { + id => 0x0231, result => "", wparam => "", lparam => "" }, WM_ENTERMENULOOP => { id => 0x0211, result => "", wparam => "", lparam => "" }, WM_ERASEBKGND => { - id => 0, result => "BOOL", wparam => "HDC", lparam => "void" }, + id => 0x0014, result => "BOOL", wparam => "HDC", lparam => "void" }, + WM_EXITHELPMODE => { + id => 0x0367, result => "", wparam => "", lparam => "" }, WM_EXITMENULOOP => { id => 0x0212, result => "", wparam => "", lparam => "" }, + WM_EXITSIZEMOVE => { + id => 0x0232, result => "", wparam => "", lparam => "" }, + WM_FILESYSCHANGE => { + id => 0x0034, result => "", wparam => "", lparam => "" }, + WM_FLOATSTATUS => { + id => 0x036d, result => "", wparam => "", lparam => "" }, WM_FONTCHANGE => { - id => 0, result => "void", wparam => "void", lparam => "void" }, - + id => 0x001d, result => "void", wparam => "void", lparam => "void" }, + + WM_GETDLGCODE => { + id => 0x0087, result => "UINT", wparam => "WPARAM", lparam => "LPMSG" }, + WM_GETFONT => { + id => 0x0031, result => "HFONT", wparam => "void", lparam => "void" }, + WM_GETHOTKEY => { + id => 0x0033, result => "", wparam => "", lparam => "" }, + WM_GETICON => { + id => 0x007f, result => "", wparam => "", lparam => "" }, + WM_GETMINMAXINFO => { + id => 0x0024, result => "void", wparam => "void", lparam => "LPMINMAXINFO" }, WM_GETTEXT => { - id => 0, result => "int", wparam => "int", lparam => "LPTSTR" }, + id => 0x000d, result => "int", wparam => "int", lparam => "LPTSTR" }, WM_GETTEXTLENGTH => { - id => 0, result => "int", wparam => "void", lparam => "void" }, + id => 0x000e, result => "int", wparam => "void", lparam => "void" }, WM_HELP => { - id => 0x0053, result => "", wparam => "", lparam => "" }, + id => 0x0053, result => "void", wparam => "void", lparam => "LPHELPINFO" }, + WM_HELPHITTEST => { + id => 0x0366, result => "", wparam => "", lparam => "" }, + WM_HOTKEY => { + id => 0x0312, result => "", wparam => "", lparam => "" }, WM_HSCROLL => { - id => 0, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, + id => 0x0114, result => "void", wparam => ["int", "int"], lparam => "HWND" }, + WM_HSCROLLCLIPBOARD => { + id => 0x030e, result => "void", wparam => "HWND", lparam => "" }, WM_ICONERASEBKGND => { - id => 0, result => "BOOL", wparam => "HDC", lparam => "void" }, + id => 0x0027, result => "BOOL", wparam => "HDC", lparam => "void" }, + WM_IME_CHAR => { + id => 0x0286, result => "", wparam => "", lparam => "" }, + WM_IME_COMPOSITION => { + id => 0x010f, result => "", wparam => "", lparam => "" }, + WM_IME_COMPOSITIONFULL => { + id => 0x0284, result => "", wparam => "", lparam => "" }, + WM_IME_CONTROL => { + id => 0x0283, result => "", wparam => "", lparam => "" }, + WM_IME_ENDCOMPOSITION => { + id => 0x010e, result => "", wparam => "", lparam => "" }, + WM_IME_KEYDOWN => { + id => 0x0290, result => "void", wparam => "UINT", lparam => ["int", "UINT"] }, + WM_IME_KEYLAST => { + id => 0x010f, result => "", wparam => "", lparam => "" }, + WM_IME_KEYUP => { + id => 0x0291, result => "void", wparam => "UINT", lparam => ["int", "UINT"] }, + WM_IME_NOTIFY => { + id => 0x0282, result => "", wparam => "", lparam => "" }, + WM_IME_REQUEST => { + id => 0x0288, result => "", wparam => "", lparam => "" }, + WM_IME_SELECT => { + id => 0x0285, result => "", wparam => "", lparam => "" }, + WM_IME_SETCONTEXT => { + id => 0x0281, result => "", wparam => "", lparam => "" }, + WM_IME_STARTCOMPOSITION => { + id => 0x010d, result => "", wparam => "", lparam => "" }, + WM_IDLEUPDATECMDUI => { + id => 0x0363, result => "", wparam => "", lparam => "" }, + WM_INITDIALOG => { + id => 0x0110, result => "BOOL", wparam => "HWND", lparam => "LPARAM" }, + WM_INITIALUPDATE => { + id => 0x0364, result => "", wparam => "", lparam => "" }, WM_INITMENU => { - id => 0, result => "void", wparam => "HMENU", lparam => "void" }, + id => 0x0116, result => "void", wparam => "HMENU", lparam => "void" }, WM_INITMENUPOPUP => { - id => 0, result => "void", wparam => "HMENU", lparam => ["UINT", "BOOL"] }, + id => 0x0117, result => "void", wparam => "HMENU", lparam => ["UINT", "BOOL"] }, + WM_INPUTLANGCHANGE => { + id => 0x0051, result => "", wparam => "", lparam => "" }, + WM_INPUTLANGCHANGEREQUEST => { + id => 0x0050, result => "", wparam => "", lparam => "" }, WM_ISACTIVEICON => { - id => 0, result => "", wparam => "", lparam => "" }, + id => 0x0035, result => "", wparam => "", lparam => "" }, WM_KEYDOWN => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0100, result => "void", wparam => "UINT", lparam => ["int", "UINT"] }, + WM_KEYLAST => { + id => 0x0108, result => "", wparam => "", lparam => "" }, + WM_KICKIDLE => { + id => 0x036a, result => "", wparam => "", lparam => "" }, WM_KEYUP => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0101, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_KILLFOCUS => { - id => 0, result => "void", wparam => "HWND", lparam => "void" }, + id => 0x0008, result => "void", wparam => "HWND", lparam => "void" }, WM_LBTRACKPOINT => { - id => 0, result => "", wparam => "", lparam => "" }, + id => 0x0131, result => "", wparam => "", lparam => "" }, WM_LBUTTONDBLCLK => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0203, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_LBUTTONDOWN => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0201, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_LBUTTONUP => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0202, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_MBUTTONDBLCLK => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0209, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_MBUTTONDOWN => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0207, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_MBUTTONUP => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0208, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_MDIACTIVATE => { + id => 0x0222, result => "void", wparam => "HWND", lparam => "HWND" }, + WM_MDICASCADE => { + id => 0x0227, result => "BOOL", wparam => "UINT", lparam => "void" }, + WM_MDICREATE => { + id => 0x0220, result => "HWND", wparam => "void", lparam => "const LPMDICREATESTRUCT" }, + WM_MDIDESTROY => { + id => 0x0221, result => "void", wparam => "HWND", lparam => "void" }, + WM_MDIGETACTIVE => { + id => 0x0229, result => "HWND", wparam => "void", lparam => "void" }, + WM_MDIICONARRANGE => { + id => 0x0228, result => "void", wparam => "void", lparam => "void" }, + WM_MDIMAXIMIZE => { + id => 0x0225, result => "void", wparam => "HWND", lparam => "void" }, + WM_MDINEXT => { + id => 0x0224, result => "HWND", wparam => "HWND", lparam => "BOOL" }, + WM_MDIREFRESHMENU => { + id => 0x0234, result => "", wparam => "", lparam => "" }, + WM_MDIRESTORE => { + id => 0x0223, result => "void", wparam => "HWND", lparam => "void" }, + WM_MDISETMENU => { + id => 0x0230, result => "HMENU", wparam => "BOOL", lparam => "HMENU" }, + WM_MDITILE => { + id => 0x0226, result => "BOOL", wparam => "UINT", lparam => "void" }, WM_MEASUREITEM => { - id => 0, result => "void", wparam => "UINT", lparam => "MEASUREITEMSTRUCT *" }, + id => 0x002c, result => "void", wparam => "UINT", lparam => "MEASUREITEMSTRUCT *" }, WM_MENUSELECT => { - id => 0, result => "void", wparam => ["", ""], lparam => "HMENU" }, + id => 0x011f, result => "void", wparam => ["", ""], lparam => "HMENU" }, WM_MENUCHAR => { - id => 0, result => "DWORD", wparam => ["", ""], lparam => "HMENU" }, + id => 0x0120, result => "DWORD", wparam => ["", "WORD"], lparam => "HMENU" }, WM_MOUSEACTIVATE => { - id => 0, result => "int", wparam => "HWND", lparam => ["", ""] }, + id => 0x0021, result => "int", wparam => "HWND", lparam => ["", ""] }, WM_MOUSEMOVE => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0200, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_MOUSEWHEEL => { + id => 0x020a, result => "void", wparam => ["DWORD", "int"], lparam => ["UINT", "UINT"] }, WM_MOVE => { - id => 0, result => "void", wparam => "void", lparam => ["", ""] }, + id => 0x0003, result => "void", wparam => "void", lparam => ["", ""] }, + WM_MOVING => { + id => 0x0216, result => "", wparam => "", lparam => "" }, WM_NCACTIVATE => { - id => 0, result => "BOOL", wparam => "BOOL", lparam => "void" }, + id => 0x0086, result => "BOOL", wparam => "BOOL", lparam => "void" }, WM_NCLBUTTONDBLCLK => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a3, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCLBUTTONDOWN => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a1, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCLBUTTONUP => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a2, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCMOUSEMOVE => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a0, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCMBUTTONDBLCLK => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a9, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCMBUTTONDOWN => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a7, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCMBUTTONUP => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a8, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCRBUTTONDBLCLK => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a6, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCRBUTTONDOWN => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a4, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCRBUTTONUP => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x00a5, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_NCCALCSIZE => { - id => 0, result => "UINT", wparam => "void", lparam => "LPARAM" }, + id => 0x0083, result => "UINT", wparam => "void", lparam => "NCCALCSIZE_PARAMS *" }, WM_NCCREATE => { - id => 0, result => "BOOL", wparam => "void", lparam => "LPCREATESTRUCT" }, + id => 0x0081, result => "BOOL", wparam => "void", lparam => "LPCREATESTRUCT" }, WM_NCDESTROY => { - id => 0, result => "void", wparam => "void", lparam => "void" }, + id => 0x0082, result => "void", wparam => "void", lparam => "void" }, + WM_NCHITTEST => { + id => 0x0084, result => "UINT", wparam => "void", lparam => ["int", "int"] }, WM_NCPAINT => { - id => 0, result => "void", wparam => "HRGN", lparam => "void" }, + id => 0x0085, result => "void", wparam => "HRGN", lparam => "void" }, + WM_NEXTDLGCTL => { + id => 0x0028, result => "HWND", wparam => "HWND", lparam => "BOOL" }, WM_NEXTMENU => { - id => 0x0213, result => "", wparam => "", lparam => "" }, + id => 0x0213, result => "void", wparam => "UINT", lparam => "LPMDINEXTMENU" }, WM_NOTIFY => { id => 0x004e, result => "LRESULT", wparam => "int", lparam => "NMHDR *" }, + WM_NOTIFYFORMAT => { + id => 0x0055, result => "", wparam => "", lparam => "" }, + WM_NULL => { + id => 0x0000, result => "", wparam => "", lparam => "" }, + + WM_OCC_INITNEW => { + id => 0x0378, result => "", wparam => "", lparam => "" }, + WM_OCC_LOADFROMSTORAGE => { + id => 0x0377, result => "", wparam => "", lparam => "" }, + WM_OCC_LOADFROMSTORAGE_EX => { + id => 0x037b, result => "", wparam => "", lparam => "" }, + WM_OCC_LOADFROMSTREAM => { + id => 0x0376, result => "", wparam => "", lparam => "" }, + WM_OCC_LOADFROMSTREAM_EX => { + id => 0x037a, result => "", wparam => "", lparam => "" }, + WM_OTHERWINDOWCREATED => { + id => 0x003c, result => "", wparam => "", lparam => "" }, + WM_OTHERWINDOWDESTROYED => { + id => 0x003d, result => "", wparam => "", lparam => "" }, - + WM_PAINT => { + id => 0x000f, result => "void", wparam => "void", lparam => "void" }, + WM_PAINTCLIPBOARD => { + id => 0x0309, result => "void", wparam => "HWND", lparam => "const LPPAINTSTRUCT" }, + WM_PAINTICON => { + id => 0x0026, result => "", wparam => "", lparam => "" }, WM_PALETTEISCHANGING => { - id => 0, result => "void", wparam => "HWND", lparam => "void" }, + id => 0x0310, 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" }, + id => 0x0311, result => "void", wparam => "HWND", lparam => "void" }, + WM_PARENTNOTIFY => { + id => 0x0210, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, WM_PASTE => { id => 0x0302, result => "void", wparam => "void", lparam => "void" }, + WM_PENWINFIRST => { + id => 0x0380, result => "", wparam => "", lparam => "" }, + WM_PENWINLAST => { + id => 0x038f, result => "", wparam => "", lparam => "" }, + WM_POPMESSAGESTRING => { + id => 0x0375, result => "", wparam => "", lparam => "" }, WM_POWER => { - id => 0, result => "void", wparam => "int", lparam => "void" }, - + id => 0x0048, result => "void", wparam => "int", lparam => "void" }, + WM_POWERBROADCAST => { + id => 0x0218, result => "", wparam => "", lparam => "" }, + WM_PRINT => { + id => 0x0317, result => "", wparam => "", lparam => "" }, + WM_PRINTCLIENT => { + id => 0x0318, result => "void", wparam => "HDC", lparam => "DWORD" }, + + WM_QUERY3DCONTROLS => { + id => 0x036f, result => "", wparam => "", lparam => "" }, + WM_QUERYAFXWNDPROC => { + id => 0x0360, result => "", wparam => "", lparam => "" }, + WM_QUERYCENTERWND => { + id => 0x036b, result => "", wparam => "", lparam => "" }, WM_QUERYDRAGICON => { - id => 0, result => "HICON", wparam => "void", lparam => "void" }, + id => 0x0037, result => "HICON", wparam => "void", lparam => "void" }, + WM_QUERYDROPOBJECT => { + id => 0x022b, result => "", wparam => "", lparam => "" }, WM_QUERYENDSESSION => { - id => 0, result => "BOOL", wparam => "void", lparam => "void" }, + id => 0x0011, result => "BOOL", wparam => "void", lparam => "void" }, WM_QUERYNEWPALETTE => { - id => 0, result => "BOOL", wparam => "void", lparam => "void" }, + id => 0x030f, result => "BOOL", wparam => "void", lparam => "void" }, WM_QUERYOPEN => { - id => 0, result => "BOOL", wparam => "void", lparam => "void" }, + id => 0x0013, result => "BOOL", wparam => "void", lparam => "void" }, + WM_QUERYPARKICON => { + id => 0x0036, result => "", wparam => "", lparam => "" }, + WM_QUERYSAVESTATE => { + id => 0x0038, result => "", wparam => "", lparam => "" }, + WM_QUEUESYNC => { + id => 0x0023, result => "void", wparam => "void", lparam => "void" }, + WM_QUEUE_SENTINEL => { + id => 0x0379, result => "", wparam => "", lparam => "" }, WM_QUIT => { - id => 0, result => "void", wparam => "WPARAM", lparam => "void" }, + id => 0x0012, result => "void", wparam => "int", lparam => "void" }, WM_RBUTTONDBLCLK => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0206, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_RBUTTONDOWN => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0204, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_RBUTTONUP => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0205, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_RECALCPARENT => { + id => 0x0368, result => "", wparam => "", lparam => "" }, + WM_RENDERALLFORMATS => { + id => 0x0306, result => "void", wparam => "void", lparam => "void" }, + WM_RENDERFORMAT => { + id => 0x0305, result => "HANDLE", wparam => "UINT", lparam => "void" }, WM_SETCURSOR => { - id => 0x0020, result => "", wparam => "HWND", lparam => ["UINT", "UINT"] }, + id => 0x0020, result => "BOOL", wparam => "HWND", lparam => ["UINT", "UINT"] }, WM_SETFOCUS => { - id => 0, result => "void", wparam => "HWND", lparam => "void" }, + id => 0x0007, result => "void", wparam => "HWND", lparam => "void" }, WM_SETFONT => { id => 0x0030, result => "void", wparam => "HFONT", lparam => "BOOL" }, + WM_SETHOTKEY => { + id => 0x0032, result => "", wparam => "", lparam => "" }, + WM_SETICON => { + id => 0x0080, result => "HICON", wparam => "DWORD", lparam => "HICON" }, + WM_SETMESSAGESTRING => { + id => 0x0362, result => "", wparam => "", lparam => "" }, WM_SETREDRAW => { - id => 0, result => "void", wparam => "BOOL", lparam => "void" }, + id => 0x000b, result => "void", wparam => "BOOL", lparam => "void" }, WM_SETTEXT => { - id => 0, result => "void", wparam => "void", lparam => "LPCTSTR" }, + id => 0x000c, result => "void", wparam => "void", lparam => "LPCTSTR" }, + WM_SETVISIBLE => { + id => 0x0009, result => "", wparam => "", lparam => "" }, WM_SHOWWINDOW => { - id => 0, result => "void", wparam => "BOOL", lparam => "UINT" }, + id => 0x0018, result => "void", wparam => "BOOL", lparam => "UINT" }, WM_SIZE => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0005, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_SIZECHILD => { + id => 0x0369, result => "", wparam => "", lparam => "" }, + WM_SIZECLIPBOARD => { + id => 0x030b, result => "void", wparam => "HWND", lparam => "const LPRECT" }, + WM_SIZEPARENT => { + id => 0x0361, result => "", wparam => "", lparam => "" }, + WM_SIZEWAIT => { + id => 0x0004, result => "", wparam => "", lparam => "" }, + WM_SIZING => { + id => 0x0214, result => "", wparam => "", lparam => "" }, + WM_SOCKET_DEAD => { + id => 0x0374, result => "", wparam => "", lparam => "" }, + WM_SOCKET_NOTIFY => { + id => 0x0373, result => "", wparam => "", lparam => "" }, WM_SPOOLERSTATUS => { - id => 0, result => "void", wparam => "WPARAM", lparam => ["", ""] }, + id => 0x002a, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_STYLECHANGED => { + id => 0x007d, result => "void", wparam => "DWORD", lparam => "LPSTYLESTRUCT" }, + WM_STYLECHANGING => { + id => 0x007c, result => "void", wparam => "DWORD", lparam => "LPSTYLESTRUCT" }, + WM_SYNCPAINT => { + id => 0x0088, result => "", wparam => "", lparam => "" }, + WM_SYNCTASK => { + id => 0x0089, result => "", wparam => "", lparam => "" }, WM_SYSCHAR => { - id => 0, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + id => 0x0106, result => "void", wparam => "TCHAR", lparam => ["", ""] }, WM_SYSCOLORCHANGE => { - id => 0, result => "void", wparam => "void", lparam => "void" }, + id => 0x0015, result => "void", wparam => "void", lparam => "void" }, + WM_SYSCOMMAND => { + id => 0x0112, result => "void", wparam => "UINT", lparam => "int" }, WM_SYSDEADCHAR => { - id => 0, result => "void", wparam => "TCHAR", lparam => ["", ""] }, + id => 0x0107, result => "void", wparam => "TCHAR", lparam => ["", ""] }, WM_SYSKEYDOWN => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, + id => 0x0104, result => "void", wparam => "UINT", lparam => ["", ""] }, WM_SYSKEYUP => { - id => 0, result => "void", wparam => "UINT", lparam => ["", ""] }, - + id => 0x0105, result => "void", wparam => "UINT", lparam => ["", ""] }, + WM_SYSTEMERROR => { + id => 0x0017, result => "", wparam => "", lparam => "" }, + WM_SYSTIMER => { + id => 0x0118, result => "", wparam => "", lparam => "" }, + + WM_TCARD => { + id => 0x0052, result => "", wparam => "", lparam => "" }, + WM_TESTING => { + id => 0x003a, result => "", wparam => "", lparam => "" }, WM_TIMECHANGE => { - id => 0, result => "void", wparam => "void", lparam => "void" }, + id => 0x001e, result => "void", wparam => "void", lparam => "void" }, + WM_TIMER => { + id => 0x0113, result => "void", wparam => "UINT", lparam => "void" }, + + WM_UNDO => { + id => 0x0304, result => "void", wparam => "void", lparam => "void" }, + WM_USER => { + id => 0x0400, result => "", wparam => "", lparam => "" }, + WM_USERCHANGED => { + id => 0x0054, result => "", wparam => "", lparam => "" }, WM_VKEYTOITEM => { - id => 0x002e, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, + id => 0x002e, result => "int", wparam => ["UINT", "int"], lparam => "HWND" }, WM_VSCROLL => { - id => 0, result => "void", wparam => ["UINT", "int"], lparam => "HWND" }, + id => 0x0115, result => "void", wparam => ["int", "int"], lparam => "HWND" }, + WM_VSCROLLCLIPBOARD => { + id => 0x030a, result => "void", wparam => "HWND", lparam => ["", ""] }, WM_WINDOWPOSCHANGING => { - id => 0, result => "BOOL", wparam => "void", lparam => "LPWINDOWPOS" }, + id => 0x0046, result => "BOOL", wparam => "void", lparam => "LPWINDOWPOS" }, WM_WINDOWPOSCHANGED => { - id => 0, result => "void", wparam => "void", lparam => "LPARAM" }, + id => 0x0047, result => "void", wparam => "void", lparam => "const LPWINDOWPOS" }, WM_WININICHANGE => { - id => 0, result => "void", wparam => "void", lparam => "LPCTSTR" } + id => 0x001a, result => "void", wparam => "void", lparam => "LPCTSTR" } }; ######################################################################## @@ -282,7 +543,7 @@ $message = { sub _get_kind { local $_ = shift; - if(!defined($_)) { + if(!$_) { return undef; } elsif(/^(?:HBRUSH|HDC|HFONT|HMENU|HRGN|HWND)$/ || /\*$/ || /^LP(?!ARAM)/) @@ -339,10 +600,13 @@ sub get_message_lparam_kind { } ######################################################################## -# _parse_windowsx_h +# _parse_file + +sub _parse_file { + my $file = shift; + my $found_preprocessor = shift; + my $found_comment = shift; -sub _parse_windowsx_h { - my $file = "$wine_dir/include/windowsx.h"; { open(IN, "< $file"); local $/ = undef; @@ -350,8 +614,65 @@ sub _parse_windowsx_h { close(IN); } + my @lines = split(/\n/, $_); + my $max_line = scalar(@lines); + my $parser = new c_parser($file); + $parser->set_found_preprocessor_callback($found_preprocessor); + $parser->set_found_comment_callback($found_comment); + + my $found_line = sub { + my $line = shift; + local $_ = shift; + + $output->progress("$file: line $line of $max_line"); + }; + + $parser->set_found_line_callback($found_line); + + 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); +} + +######################################################################## +# _get_tuple_arguments + +sub _get_tuple_arguments { + local $_ = shift; + + my $parser = new c_parser; + + my $line = 1; + my $column = 0; + + my @arguments; + my @argument_lines; + my @argument_columns; + if(!$parser->parse_c_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) { + return undef; + } + + return @arguments; +} + +######################################################################## +# _parse_windowsx_h + + +sub _parse_windowsx_h { + my $last_comment; + my $found_preprocessor = sub { my $begin_line = shift; my $begin_column = shift; @@ -361,85 +682,210 @@ sub _parse_windowsx_h { return 1; } - my $msg; + my $name; if(s/^FORWARD_(\w+)\([^\)]*\)\s*(.*?)\s*$/$2/s) { - $msg = $1; + $name = $1; } - if($msg eq "WM_SYSTEMERROR") { + if($name 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; + my $result; + if(s/^\(\s*(\w+)\s*\)(?:\(\s*\w+\s*\))*\(\s*\w+\s*\)//) { + $result = $1; } else { - die "$msg: '$_'"; + die "$name: '$_'"; } - - my @msgs = (); - if(s/^$msg\s*,\s*//) { - @msgs = $msg; - } elsif(s/^\(\w+\)\s*\?\s*(\w+)\s*:\s*(\w+)\s*,\s*//s) { - @msgs = ($1, $2); + + (undef, $_, my $wparam, my $lparam) = _get_tuple_arguments($_); + + my @names = (); + if(/^$name$/) { + @names = $name; + } elsif(/^\(\w+\)\s*\?\s*(\w+)\s*:\s*(\w+)$/) { + @names = ($1, $2); } else { - die "$msg: '$_'"; + die "$name: '$_'"; } - - my $wparam; - if(s/^\(WPARAM\)(?:\(\s*(\w+)\s*\))*\((.*?)\)\s*,\s*//) { - if(defined($1)) { - $wparam = $1; - } else { - $wparam = "WPARAM"; + + local $_ = $last_comment; + s%^/\*\s*(.*?)\s*\*/$%$1%; + + my %arguments; + if(s/^(\w+)\s+\w+\s*\(\s*(.*?)\s*\)$/$2/) { + my $result2 = $1; + if($result2 eq "INT") { $result2 = "int"; } + if($result ne $result2) { + $output->write("message $name: result type mismatch '$result' != '$result2'\n"); + } + foreach (split(/\s*,\s*/)) { + if(/^((?:const\s+)?\w+(?:\s*\*\s*|\s+)?)(\w+)$/) { + my $type = $1; + my $name = $2; + + $type =~ s/^\s*(.*?)\s*$/$1/; + + $arguments{$name} = $type; + } else { + die "$name: '$_'"; + } } - } elsif(s/^MAKEWPARAM\(\s*(.*?)\s*,\s*(.*?)\s*\)\s*,\s*//) { - $wparam = "(,)"; # "($1, $2)"; - } elsif(s/^\((.*?)\)$//) { - $wparam = "WPARAM"; - } elsif(s/^0L\s*,\s*//) { - $wparam = "void"; + # $output->write("$1: $_\n"); } else { - die "$msg: '$_'"; - } + die "$name: '$_'"; + } - my $lparam; - if(s/^\(LPARAM\)(?:\(\s*(\w+)\s*\))*\((.*?)\)$//) { - if(defined($1)) { - $lparam = $1; + my $find_inner_cast = sub { + local $_ = shift; + if(/^(?:\(\s*((?:const\s+)?\w+(?:\s*\*)?)\s*\))*\(.*?\)$/) { + if(defined($1)) { + return $1; + } else { + return ""; + } + } + + }; + + my @entries = ( + [ \$wparam, "W", "w" ], + [ \$lparam, "L", "l" ] + ); + foreach my $entry (@entries) { + (my $refparam, my $upper, my $lower) = @$entry; + + local $_ = $$refparam; + if(s/^\(\s*$upper(?:)PARAM\s*\)\s*(?:\(\s*((?:const\s+)?\w+(?:\s*\*)?)\s*\))*\(\s*(.*?)\s*\)$/$2/) { + if(defined($1)) { + $$refparam = $1; + } else { + $$refparam = ""; + } + + if(/^\w+$/) { + if(exists($arguments{$_})) { + $$refparam = $arguments{$_}; + } + } elsif(/^\(\s*(\w+)\s*\)\s*\?\s*\(\s*(\w+)\s*\)\s*:\s*(?:\(\s*(\w+)\s*\)|0)$/) { + foreach ($1, $2, $3) { + if(exists($arguments{$_})) { + $$refparam = $arguments{$_}; + last; + } + } + } elsif(/^\(\((?:const\s+)?\w+\s*(?:\*\s*)?\)\s*(?:\(\s*\w+\s*\)|\w+)\s*\)\s*\->\s*\w+$/) { + $$refparam = "UINT"; + } else { + die "$name: '$_'"; + } + } elsif(s/^(?:\(\s*$upper(?:)PARAM\s*\)\s*)?MAKE$upper(?:)PARAM\s*//) { + (my $low, my $high) = _get_tuple_arguments($_); + + $low = &$find_inner_cast($low); + $high = &$find_inner_cast($high); + + $$refparam = "($low,$high)"; + } elsif(s/^\(.*?$lower(?:)Param.*?\)$//) { + $$refparam = $upper . "PARAM"; + } elsif(s/^\(\s*(.*?)\s*\)$//) { + $$refparam = "$1"; + } elsif(s/^0L$//) { + $$refparam = "void"; } else { - $lparam = "LPARAM"; + die "$name: '$_'"; + } + } + + # $output->write("$result: '@names', '$wparam', '$lparam'\n"); + + foreach my $name (@names) { + my $result2 = $$message{$name}{result}; + my $wparam2 = $$message{$name}{wparam}; + my $lparam2 = $$message{$name}{lparam}; + + if(ref($wparam2)) { + $wparam2 = "(" . join(",", @$wparam2) . ")"; + } + + if(ref($lparam2)) { + $lparam2 = "(" . join(",", @$lparam2) . ")"; + } + + if($result ne $result2) { + $output->write("message $name: wrong result type '$result2' should be '$result'\n"); } - } 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"); + if($wparam ne $wparam2) { + # if($wparam ne "WPARAM" && $wparam ne "(,)") { + $output->write("message $name: wrong wparam type '$wparam2' should be '$wparam'\n"); + # } + } + + if($lparam ne $lparam2) { + # if($lparam ne "LPARAM" && $lparam ne "(,)") { + $output->write("message $name: wrong lparam type '$lparam2' should be '$lparam'\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; - my $line = 1; - my $column = 0; + $last_comment = $comment; - my $old_prefix = $output->prefix; - $output->progress("$file"); - $output->prefix("$file: "); + return 1; + }; - if(!$parser->parse_c_file(\$_, \$line, \$column)) { - $output->write("can't parse file\n"); - } + _parse_file("$wine_dir/include/windowsx.h", $found_preprocessor, $found_comment); +} - $output->prefix($old_prefix); + +######################################################################## +# _parse_winuser_h + +sub _parse_winuser_h { + my %not_found = (); + + my $found_preprocessor = sub { + my $begin_line = shift; + my $begin_column = shift; + local $_ = shift; + + if(/^\#\s*define\s+(WM_\w+)\s+(0x[0-9a-fA-F]+)\s*$/) { + my $name = $1; + my $id = lc($2); + + if(exists($$message{$name})) { + my $id2 = sprintf("0x%04x", $$message{$name}{id}); + if($id ne $id2) { + $output->write("message $name: wrong value ($id2) should be $id\n"); + } + } else { + $output->write("message $name: exists but is not supported\n"); + $not_found{$name} = $id; + } + } + + return 1; + }; + + _parse_file("$wine_dir/include/winuser.h", $found_preprocessor); + + foreach my $name (sort(keys(%not_found))) { + my $id = $not_found{$name}; + + print " $name => {\n"; + print "\tid => $id, result => \"\", wparam => \"\", lparam => \"\" },\n"; + } } +# _parse_windowsx_h; +# _parse_winuser_h; + +1; diff --git a/tools/winapi_check/win16/winsock.api b/tools/winapi_check/win16/winsock.api index 436577f3886abd06eed426c6cf2a0ef85b24607f..1fa77a0d68d3d65f1d285c28107acab5209b258e 100644 --- a/tools/winapi_check/win16/winsock.api +++ b/tools/winapi_check/win16/winsock.api @@ -11,7 +11,7 @@ u_long %ptr INT16 * -LPWSADATA +LPWSADATA16 ULONG * char * struct sockaddr * diff --git a/tools/winapi_check/win32/quartz.api b/tools/winapi_check/win32/quartz.api index c9b87919974abd123a5f05b02b350d0a6fd4496a..555b0339011b29df685f01b568f5b8ef377e61e0 100644 --- a/tools/winapi_check/win32/quartz.api +++ b/tools/winapi_check/win32/quartz.api @@ -1,5 +1,6 @@ %long +DWORD HRESULT %ptr @@ -7,3 +8,11 @@ HRESULT CLSID * IID * void ** + +%str + +LPSTR + +%wstr + +LPWSTR diff --git a/tools/winapi_check/win32/rpcrt4.api b/tools/winapi_check/win32/rpcrt4.api index 57223adb7b8a31c5eb3bf4ddf8574434fa89404d..0acc8bc308cb3592906364092f128665296a7260 100644 --- a/tools/winapi_check/win32/rpcrt4.api +++ b/tools/winapi_check/win32/rpcrt4.api @@ -18,8 +18,10 @@ RPC_AUTH_KEY_RETRIEVAL_FN RPC_BINDING_HANDLE * RPC_IF_CALLBACK_FN * RPC_MGR_EPV * +RPC_STATUS * UUID * unsigned char ** +unsigned short void ** %str diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check index 16b6102635d7b6392a5a3bebcc3136c18d2e42fe..24ce8392045fcaac0418ee47d6e0419ea6e18736 100755 --- a/tools/winapi_check/winapi_check +++ b/tools/winapi_check/winapi_check @@ -169,7 +169,9 @@ if($options->headers) { } elsif($options->headers_duplicated) { my $file = $previous_function->file; my $function_line = $previous_function->function_line; - $output->write("duplicate declaration (first declaration at $file:$function_line)\n"); + if($file =~ /\.h$/) { + $output->write("duplicate declaration (first declaration at $file:$function_line)\n"); + } } } $output->prefix("");