- FreeBSD now supported.

- Much more work on the new C parser.
- API files update.
oldstable
Patrik Stridvall 2001-09-10 23:16:05 +00:00 committed by Alexandre Julliard
parent 872784fc2f
commit d171a552bb
11 changed files with 1187 additions and 346 deletions

View File

@ -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);
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($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))
{
$self->parse_c_expression(\$argument, \$argument_line, \$argument_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))
{
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(!$self->parse_c_preprocessor(\$preprocessor, \$preprocessor_line, \$preprocessor_column)) {
return 0;
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(s/^\/\*(.*?)\*\///s) {
&$$found_comment($line, $column + 1, "/*$1*/");
my @lines = split(/\n/, $1);
if($#lines > 0) {
$blank_lines += $#lines;
} else {
$column += length($1);
if(!$self->parse_c_preprocessor(\$preprocessor, \$preprocessor_line, \$preprocessor_column)) {
return 0;
}
}
if(s/^\/\*.*?\*\///s) {
&$$found_comment($line, $column + 1, $&);
local $_ = $&;
while(s/^.*?\n//) {
$blank_lines++;
}
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,30 @@ 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/^\{//) {
$blevel++;
} elsif(s/^\)//) {
$plevel--;
$declaration .= $&;
} elsif(s/^\}//) {
$blevel--;
$declaration .= $&;
if($plevel == 1 && $blevel == 1 && $declaration !~ /^typedef/) {
if($plevel == 1 && $declaration =~ /^__ASM_GLOBAL_FUNC/) {
if(!$self->parse_c_declaration(\$declaration, \$declaration_line, \$declaration_column)) {
return 0;
}
@ -710,8 +774,38 @@ sub parse_c_file {
$declaration_line = $line;
$declaration_column = $column;
}
} elsif(s/^\{//) {
$blevel++;
$declaration .= $&;
} elsif(s/^\}//) {
$blevel--;
$declaration .= $&;
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;
}
$self->_parse_c_until_one_of("\\S", \$_, \$line, \$column);
$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 = "";
$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; }
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);
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;

View File

@ -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 = "$_";
}

View File

@ -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)) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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");
}

View File

@ -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_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" },
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 => 0x0310, result => "void", wparam => "HWND", lparam => "void" },
WM_PALETTECHANGED => {
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,84 +614,22 @@ sub _parse_windowsx_h {
close(IN);
}
my @lines = split(/\n/, $_);
my $max_line = scalar(@lines);
my $parser = new c_parser($file);
my $found_preprocessor = sub {
my $begin_line = shift;
my $begin_column = shift;
$parser->set_found_preprocessor_callback($found_preprocessor);
$parser->set_found_comment_callback($found_comment);
my $found_line = sub {
my $line = 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;
$output->progress("$file: line $line of $max_line");
};
$parser->set_found_preprocessor_callback($found_preprocessor);
$parser->set_found_line_callback($found_line);
my $line = 1;
my $column = 0;
@ -443,3 +645,247 @@ sub _parse_windowsx_h {
$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;
local $_ = shift;
if(!s/^\#\s*define\s*// || !/^FORWARD_WM_/) {
return 1;
}
my $name;
if(s/^FORWARD_(\w+)\([^\)]*\)\s*(.*?)\s*$/$2/s) {
$name = $1;
}
if($name eq "WM_SYSTEMERROR") {
return 1;
}
my $result;
if(s/^\(\s*(\w+)\s*\)(?:\(\s*\w+\s*\))*\(\s*\w+\s*\)//) {
$result = $1;
} else {
die "$name: '$_'";
}
(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 "$name: '$_'";
}
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: '$_'";
}
}
# $output->write("$1: $_\n");
} else {
die "$name: '$_'";
}
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 {
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");
}
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;
};
my $found_comment = sub {
my $begin_line = shift;
my $begin_column = shift;
my $comment = shift;
$last_comment = $comment;
return 1;
};
_parse_file("$wine_dir/include/windowsx.h", $found_preprocessor, $found_comment);
}
########################################################################
# _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;

View File

@ -11,7 +11,7 @@ u_long
%ptr
INT16 *
LPWSADATA
LPWSADATA16
ULONG *
char *
struct sockaddr *

View File

@ -1,5 +1,6 @@
%long
DWORD
HRESULT
%ptr
@ -7,3 +8,11 @@ HRESULT
CLSID *
IID *
void **
%str
LPSTR
%wstr
LPWSTR

View File

@ -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

View File

@ -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("");