- Improved alignment and offset calculations.
- Reorganized and improved enum/union/struct parsing.
This commit is contained in:
parent
1cc2cee66f
commit
65442cd763
|
@ -696,6 +696,80 @@ sub parse_c_declarations {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# parse_c_enum
|
||||||
|
|
||||||
|
sub parse_c_enum {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $refcurrent = shift;
|
||||||
|
my $refline = shift;
|
||||||
|
my $refcolumn = shift;
|
||||||
|
|
||||||
|
local $_ = $$refcurrent;
|
||||||
|
my $line = $$refline;
|
||||||
|
my $column = $$refcolumn;
|
||||||
|
|
||||||
|
$self->_parse_c_until_one_of("\\S", \$_, \$line, \$column);
|
||||||
|
|
||||||
|
if (!s/^enum\s+((?:MSVCRT|WS)\(\s*\w+\s*\)|\w+)?\s*\{\s*//s) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $_name = $1 || "";
|
||||||
|
|
||||||
|
$self->_update_c_position($&, \$line, \$column);
|
||||||
|
|
||||||
|
my $name = "";
|
||||||
|
|
||||||
|
my $match;
|
||||||
|
while ($self->_parse_c_on_same_level_until_one_of(',', \$_, \$line, \$column, \$match)) {
|
||||||
|
if ($match) {
|
||||||
|
if ($match !~ /^(\w+)\s*(?:=\s*(.*?)\s*)?$/) {
|
||||||
|
$self->_parse_c_error($_, $line, $column, "enum");
|
||||||
|
}
|
||||||
|
my $enum_name = $1;
|
||||||
|
my $enum_value = $2 || "";
|
||||||
|
|
||||||
|
# $output->write("enum:$_name:$enum_name:$enum_value\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($self->_parse_c(',', \$_, \$line, \$column)) {
|
||||||
|
next;
|
||||||
|
} elsif ($self->_parse_c('}', \$_, \$line, \$column)) {
|
||||||
|
# FIXME: Kludge
|
||||||
|
my $tuple = "($_)";
|
||||||
|
my $tuple_line = $line;
|
||||||
|
my $tuple_column = $column - 1;
|
||||||
|
|
||||||
|
my @arguments;
|
||||||
|
my @argument_lines;
|
||||||
|
my @argument_columns;
|
||||||
|
|
||||||
|
if(!$self->parse_c_tuple(\$tuple, \$tuple_line, \$tuple_column,
|
||||||
|
\@arguments, \@argument_lines, \@argument_columns))
|
||||||
|
{
|
||||||
|
$self->_parse_c_error($_, $line, $column, "enum");
|
||||||
|
}
|
||||||
|
|
||||||
|
# FIXME: Kludge
|
||||||
|
if ($#arguments >= 0) {
|
||||||
|
$name = $arguments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
last;
|
||||||
|
} else {
|
||||||
|
$self->_parse_c_error($_, $line, $column, "enum");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->_update_c_position($_, \$line, \$column);
|
||||||
|
|
||||||
|
$$refcurrent = $_;
|
||||||
|
$$refline = $line;
|
||||||
|
$$refcolumn = $column;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# parse_c_expression
|
# parse_c_expression
|
||||||
|
|
||||||
|
@ -1502,6 +1576,104 @@ sub parse_c_statements {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# parse_c_struct_union
|
||||||
|
|
||||||
|
sub parse_c_struct_union {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $refcurrent = shift;
|
||||||
|
my $refline = shift;
|
||||||
|
my $refcolumn = shift;
|
||||||
|
|
||||||
|
my $refkind = shift;
|
||||||
|
my $ref_name = shift;
|
||||||
|
my $reffield_type_names = shift;
|
||||||
|
my $reffield_names = shift;
|
||||||
|
my $refnames = shift;
|
||||||
|
|
||||||
|
local $_ = $$refcurrent;
|
||||||
|
my $line = $$refline;
|
||||||
|
my $column = $$refcolumn;
|
||||||
|
|
||||||
|
my $kind;
|
||||||
|
my $_name;
|
||||||
|
my @field_type_names = ();
|
||||||
|
my @field_names = ();
|
||||||
|
my @names = ();
|
||||||
|
|
||||||
|
$self->_parse_c_until_one_of("\\S", \$_, \$line, \$column);
|
||||||
|
|
||||||
|
if (!s/^(struct\s+|union\s+)((?:MSVCRT|WS)\(\s*\w+\s*\)|\w+)?\s*\{\s*//s) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
$kind = $1;
|
||||||
|
$_name = $2 || "";
|
||||||
|
|
||||||
|
$self->_update_c_position($&, \$line, \$column);
|
||||||
|
|
||||||
|
$kind =~ s/\s+//g;
|
||||||
|
|
||||||
|
my $match;
|
||||||
|
while ($_ && $self->_parse_c_on_same_level_until_one_of(';', \$_, \$line, \$column, \$match))
|
||||||
|
{
|
||||||
|
my $field_linkage;
|
||||||
|
my $field_type_name;
|
||||||
|
my $field_name;
|
||||||
|
|
||||||
|
if ($self->parse_c_variable(\$match, \$line, \$column, \$field_linkage, \$field_type_name, \$field_name)) {
|
||||||
|
$field_type_name =~ s/\s+/ /g;
|
||||||
|
|
||||||
|
push @field_type_names, $field_type_name;
|
||||||
|
push @field_names, $field_name;
|
||||||
|
# $output->write("$kind:$_name:$field_type_name:$field_name\n");
|
||||||
|
} elsif ($match) {
|
||||||
|
$self->_parse_c_error($_, $line, $column, "typedef $kind: '$match'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($self->_parse_c(';', \$_, \$line, \$column)) {
|
||||||
|
next;
|
||||||
|
} elsif ($self->_parse_c('}', \$_, \$line, \$column)) {
|
||||||
|
# FIXME: Kludge
|
||||||
|
my $tuple = "($_)";
|
||||||
|
my $tuple_line = $line;
|
||||||
|
my $tuple_column = $column - 1;
|
||||||
|
|
||||||
|
my @arguments;
|
||||||
|
my @argument_lines;
|
||||||
|
my @argument_columns;
|
||||||
|
|
||||||
|
if(!$self->parse_c_tuple(\$tuple, \$tuple_line, \$tuple_column,
|
||||||
|
\@arguments, \@argument_lines, \@argument_columns))
|
||||||
|
{
|
||||||
|
$self->_parse_c_error($_, $line, $column, "$kind");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $argument (@arguments) {
|
||||||
|
my $name = $argument;
|
||||||
|
|
||||||
|
push @names, $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
last;
|
||||||
|
} else {
|
||||||
|
$self->_parse_c_error($_, $line, $column, "$kind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$$refcurrent = $_;
|
||||||
|
$$refline = $line;
|
||||||
|
$$refcolumn = $column;
|
||||||
|
|
||||||
|
$$refkind = $kind;
|
||||||
|
$$ref_name = $_name;
|
||||||
|
@$reffield_type_names = @field_type_names;
|
||||||
|
@$reffield_names = @field_names;
|
||||||
|
@$refnames = @names;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# parse_c_tuple
|
# parse_c_tuple
|
||||||
|
|
||||||
|
@ -1634,178 +1806,104 @@ sub parse_c_typedef {
|
||||||
my $refline = shift;
|
my $refline = shift;
|
||||||
my $refcolumn = shift;
|
my $refcolumn = shift;
|
||||||
|
|
||||||
my $reftype = shift;
|
|
||||||
|
|
||||||
local $_ = $$refcurrent;
|
local $_ = $$refcurrent;
|
||||||
my $line = $$refline;
|
my $line = $$refline;
|
||||||
my $column = $$refcolumn;
|
my $column = $$refcolumn;
|
||||||
|
|
||||||
my $type;
|
my $type;
|
||||||
|
|
||||||
if (0) {
|
if (!$self->_parse_c("typedef", \$_, \$line, \$column)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $finished = 0;
|
||||||
|
|
||||||
|
if ($finished) {
|
||||||
# Nothing
|
# Nothing
|
||||||
} elsif (s/^(?:typedef\s+)?(enum\s+|struct\s+|union\s+)((?:MSVCRT|WS)\(\s*\w+\s*\)|\w+)?\s*\{\s*//s) {
|
} elsif ($self->parse_c_enum(\$_, \$line, \$column)) {
|
||||||
$self->_update_c_position($&, \$line, \$column);
|
$finished = 1;
|
||||||
|
}
|
||||||
|
|
||||||
my $kind = $1;
|
my $kind;
|
||||||
my $_name = $2 || "";
|
my $_name;
|
||||||
|
my @field_type_names;
|
||||||
$kind =~ s/\s+//g;
|
my @field_names;
|
||||||
|
my @names;
|
||||||
if ($kind =~ /^struct|union$/) {
|
if ($finished) {
|
||||||
my $name = "";
|
# Nothing
|
||||||
my @field_type_names = ();
|
} elsif ($self->parse_c_struct_union(\$_, \$line, \$column,
|
||||||
my @field_names = ();
|
\$kind, \$_name, \@field_type_names, \@field_names, \@names))
|
||||||
|
{
|
||||||
my $match;
|
my $base_name;
|
||||||
while ($_ && $self->_parse_c_on_same_level_until_one_of(';', \$_, \$line, \$column, \$match))
|
foreach my $name (@names) {
|
||||||
{
|
if ($name =~ /^\w+$/) {
|
||||||
my $field_linkage;
|
|
||||||
my $field_type_name;
|
|
||||||
my $field_name;
|
|
||||||
|
|
||||||
if ($self->parse_c_variable(\$match, \$line, \$column, \$field_linkage, \$field_type_name, \$field_name)) {
|
|
||||||
$field_type_name =~ s/\s+/ /g;
|
|
||||||
|
|
||||||
push @field_type_names, $field_type_name;
|
|
||||||
push @field_names, $field_name;
|
|
||||||
# $output->write("$kind:$_name:$field_type_name:$field_name\n");
|
|
||||||
} elsif ($match) {
|
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef $kind: '$match'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($self->_parse_c(';', \$_, \$line, \$column)) {
|
|
||||||
next;
|
|
||||||
} elsif ($self->_parse_c('}', \$_, \$line, \$column)) {
|
|
||||||
# FIXME: Kludge
|
|
||||||
my $tuple = "($_)";
|
|
||||||
my $tuple_line = $line;
|
|
||||||
my $tuple_column = $column - 1;
|
|
||||||
|
|
||||||
my @arguments;
|
|
||||||
my @argument_lines;
|
|
||||||
my @argument_columns;
|
|
||||||
|
|
||||||
if(!$self->parse_c_tuple(\$tuple, \$tuple_line, \$tuple_column,
|
|
||||||
\@arguments, \@argument_lines, \@argument_columns))
|
|
||||||
{
|
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef $kind");
|
|
||||||
}
|
|
||||||
|
|
||||||
# FIXME: Kludge
|
|
||||||
if ($#arguments >= 0) {
|
|
||||||
$name = $arguments[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
last;
|
|
||||||
} else {
|
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef $kind");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my $type = &$$create_type();
|
|
||||||
|
|
||||||
$type->kind($kind);
|
|
||||||
$type->_name($_name);
|
|
||||||
$type->name($name);
|
|
||||||
$type->field_type_names([@field_type_names]);
|
|
||||||
$type->field_names([@field_names]);
|
|
||||||
|
|
||||||
&$$found_type($type);
|
|
||||||
} else {
|
|
||||||
my $name = "";
|
|
||||||
|
|
||||||
my $match;
|
|
||||||
while ($self->_parse_c_on_same_level_until_one_of(',', \$_, \$line, \$column, \$match)) {
|
|
||||||
if ($match) {
|
|
||||||
if ($match !~ /^(\w+)\s*(?:=\s*(.*?)\s*)?$/) {
|
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef $kind");
|
|
||||||
}
|
|
||||||
my $enum_name = $1;
|
|
||||||
my $enum_value = $2 || "";
|
|
||||||
|
|
||||||
# $output->write("$kind:$_name:$enum_name:$enum_value\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($self->_parse_c(',', \$_, \$line, \$column)) {
|
|
||||||
next;
|
|
||||||
} elsif ($self->_parse_c('}', \$_, \$line, \$column)) {
|
|
||||||
# FIXME: Kludge
|
|
||||||
my $tuple = "($_)";
|
|
||||||
my $tuple_line = $line;
|
|
||||||
my $tuple_column = $column - 1;
|
|
||||||
|
|
||||||
my @arguments;
|
|
||||||
my @argument_lines;
|
|
||||||
my @argument_columns;
|
|
||||||
|
|
||||||
if(!$self->parse_c_tuple(\$tuple, \$tuple_line, \$tuple_column,
|
|
||||||
\@arguments, \@argument_lines, \@argument_columns))
|
|
||||||
{
|
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef $kind");
|
|
||||||
}
|
|
||||||
|
|
||||||
# FIXME: Kludge
|
|
||||||
if ($#arguments >= 0) {
|
|
||||||
$name = $arguments[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
last;
|
|
||||||
} else {
|
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef $kind");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# FIXME: Not correct
|
|
||||||
# $output->write("typedef:$name:$_name\n");
|
|
||||||
}
|
|
||||||
} elsif ($self->_parse_c("typedef", \$_, \$line, \$column)) {
|
|
||||||
my $linkage;
|
|
||||||
my $type_name;
|
|
||||||
my $name;
|
|
||||||
|
|
||||||
if ($self->parse_c_variable(\$_, \$line, \$column, \$linkage, \$type_name, \$name)) {
|
|
||||||
$type_name =~ s/\s+/ /g;
|
|
||||||
|
|
||||||
if(defined($type_name) && defined($name)) {
|
|
||||||
my $type = &$$create_type();
|
my $type = &$$create_type();
|
||||||
|
|
||||||
if (length($name) == 0) {
|
$type->kind($kind);
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef");
|
$type->_name($_name);
|
||||||
}
|
$type->name($name);
|
||||||
|
$type->field_type_names([@field_type_names]);
|
||||||
|
$type->field_names([@field_names]);
|
||||||
|
|
||||||
|
&$$found_type($type);
|
||||||
|
|
||||||
|
$base_name = $name;
|
||||||
|
} elsif (!defined($base_name)) {
|
||||||
|
$self->_parse_c_error($_, $line, $column, "typedef 1");
|
||||||
|
} elsif ($name =~ /^(\*+)\s*(?:RESTRICTED_POINTER\s+)?(\w+)$/) {
|
||||||
|
my $type_name = "$base_name $1";
|
||||||
|
$name = $2;
|
||||||
|
|
||||||
|
my $type = &$$create_type();
|
||||||
|
|
||||||
$type->kind("");
|
$type->kind("");
|
||||||
$type->name($name);
|
$type->name($name);
|
||||||
$type->pack(1);
|
|
||||||
$type->field_type_names([$type_name]);
|
$type->field_type_names([$type_name]);
|
||||||
$type->field_names([""]);
|
$type->field_names([""]);
|
||||||
|
|
||||||
&$$found_type($type);
|
&$$found_type($type);
|
||||||
|
} else {
|
||||||
|
$self->_parse_c_error($_, $line, $column, "typedef 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$finished = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $linkage;
|
||||||
|
my $type_name;
|
||||||
|
my $name;
|
||||||
|
if ($finished) {
|
||||||
|
# Nothing
|
||||||
|
} elsif ($self->parse_c_variable(\$_, \$line, \$column, \$linkage, \$type_name, \$name)) {
|
||||||
|
$type_name =~ s/\s+/ /g;
|
||||||
|
|
||||||
|
if(defined($type_name) && defined($name)) {
|
||||||
|
my $type = &$$create_type();
|
||||||
|
|
||||||
|
if (length($name) == 0) {
|
||||||
|
$self->_parse_c_error($_, $line, $column, "typedef");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 && $_ && !/^,/) {
|
$type->kind("");
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef");
|
$type->name($name);
|
||||||
}
|
$type->field_type_names([$type_name]);
|
||||||
} else {
|
$type->field_names([""]);
|
||||||
$self->_parse_c_error($_, $line, $column, "typedef");
|
|
||||||
|
&$$found_type($type);
|
||||||
}
|
}
|
||||||
} elsif (0 && $self->_parse_c("typedef", \$_, \$line, \$column)) {
|
|
||||||
my $type_name;
|
|
||||||
$self->_parse_c('\w+', \$_, \$line, \$column, \$type_name);
|
|
||||||
|
|
||||||
my $name;
|
|
||||||
$self->_parse_c('\w+', \$_, \$line, \$column, \$name);
|
|
||||||
|
|
||||||
|
if (0 && $_ && !/^,/) {
|
||||||
|
$self->_parse_c_error($_, $line, $column, "typedef");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
$self->_parse_c_error($_, $line, $column, "typedef");
|
||||||
}
|
}
|
||||||
|
|
||||||
$$refcurrent = $_;
|
$$refcurrent = $_;
|
||||||
$$refline = $line;
|
$$refline = $line;
|
||||||
$$refcolumn = $column;
|
$$refcolumn = $column;
|
||||||
|
|
||||||
$$reftype = $type;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1860,7 +1958,7 @@ sub parse_c_variable {
|
||||||
# Nothing
|
# Nothing
|
||||||
} elsif(/^$/) {
|
} elsif(/^$/) {
|
||||||
return 0;
|
return 0;
|
||||||
} elsif(s/^(enum|struct|union)(?:\s+(\w+))?\s*\{//s) {
|
} elsif (s/^(enum\s+|struct\s+|union\s+)((?:MSVCRT|WS)\(\s*\w+\s*\)|\w+)?\s*\{\s*//s) {
|
||||||
my $kind = $1;
|
my $kind = $1;
|
||||||
my $_name = $2;
|
my $_name = $2;
|
||||||
$self->_update_c_position($&, \$line, \$column);
|
$self->_update_c_position($&, \$line, \$column);
|
||||||
|
|
|
@ -31,13 +31,36 @@ sub new {
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# set_find_align_callback
|
||||||
|
#
|
||||||
|
sub set_find_align_callback {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $find_align = \${$self->{FIND_ALIGN}};
|
||||||
|
|
||||||
|
$$find_align = shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# set_find_size_callback
|
||||||
|
#
|
||||||
|
sub set_find_size_callback {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $find_size = \${$self->{FIND_SIZE}};
|
||||||
|
|
||||||
|
$$find_size = shift;
|
||||||
|
}
|
||||||
|
|
||||||
sub kind {
|
sub kind {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $kind = \${$self->{KIND}};
|
my $kind = \${$self->{KIND}};
|
||||||
|
my $dirty = \${$self->{DIRTY}};
|
||||||
|
|
||||||
local $_ = shift;
|
local $_ = shift;
|
||||||
|
|
||||||
if(defined($_)) { $$kind = $_; }
|
if(defined($_)) { $$kind = $_; $$dirty = 1; }
|
||||||
|
|
||||||
return $$kind;
|
return $$kind;
|
||||||
}
|
}
|
||||||
|
@ -45,10 +68,11 @@ sub kind {
|
||||||
sub _name {
|
sub _name {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $_name = \${$self->{_NAME}};
|
my $_name = \${$self->{_NAME}};
|
||||||
|
my $dirty = \${$self->{DIRTY}};
|
||||||
|
|
||||||
local $_ = shift;
|
local $_ = shift;
|
||||||
|
|
||||||
if(defined($_)) { $$_name = $_; }
|
if(defined($_)) { $$_name = $_; $$dirty = 1; }
|
||||||
|
|
||||||
return $$_name;
|
return $$_name;
|
||||||
}
|
}
|
||||||
|
@ -56,10 +80,11 @@ sub _name {
|
||||||
sub name {
|
sub name {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $name = \${$self->{NAME}};
|
my $name = \${$self->{NAME}};
|
||||||
|
my $dirty = \${$self->{DIRTY}};
|
||||||
|
|
||||||
local $_ = shift;
|
local $_ = shift;
|
||||||
|
|
||||||
if(defined($_)) { $$name = $_; }
|
if(defined($_)) { $$name = $_; $$dirty = 1; }
|
||||||
|
|
||||||
if($$name) {
|
if($$name) {
|
||||||
return $$name;
|
return $$name;
|
||||||
|
@ -74,22 +99,27 @@ sub name {
|
||||||
sub pack {
|
sub pack {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $pack = \${$self->{PACK}};
|
my $pack = \${$self->{PACK}};
|
||||||
|
my $dirty = \${$self->{DIRTY}};
|
||||||
|
|
||||||
local $_ = shift;
|
local $_ = shift;
|
||||||
|
|
||||||
if(defined($_)) { $$pack = $_; }
|
if(defined($_)) { $$pack = $_; $$dirty = 1; }
|
||||||
|
|
||||||
return $$pack;
|
return $$pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub fields {
|
sub align {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
my $find_size = shift;
|
my $align = \${$self->{ALIGN}};
|
||||||
|
|
||||||
if (defined($find_size)) {
|
$self->_refresh();
|
||||||
$self->_refresh($find_size);
|
|
||||||
}
|
return $$align;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
my $count = $self->field_count;
|
my $count = $self->field_count;
|
||||||
|
|
||||||
|
@ -101,15 +131,20 @@ sub fields {
|
||||||
return @fields;
|
return @fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub field_base_sizes {
|
||||||
|
my $self = shift;
|
||||||
|
my $field_base_sizes = \${$self->{FIELD_BASE_SIZES}};
|
||||||
|
|
||||||
|
$self->_refresh();
|
||||||
|
|
||||||
|
return $$field_base_sizes;
|
||||||
|
}
|
||||||
|
|
||||||
sub field_aligns {
|
sub field_aligns {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $field_aligns = \${$self->{FIELD_ALIGNS}};
|
my $field_aligns = \${$self->{FIELD_ALIGNS}};
|
||||||
|
|
||||||
my $find_size = shift;
|
$self->_refresh();
|
||||||
|
|
||||||
if (defined($find_size)) {
|
|
||||||
$self->_refresh($find_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $$field_aligns;
|
return $$field_aligns;
|
||||||
}
|
}
|
||||||
|
@ -127,10 +162,11 @@ sub field_count {
|
||||||
sub field_names {
|
sub field_names {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $field_names = \${$self->{FIELD_NAMES}};
|
my $field_names = \${$self->{FIELD_NAMES}};
|
||||||
|
my $dirty = \${$self->{DIRTY}};
|
||||||
|
|
||||||
local $_ = shift;
|
local $_ = shift;
|
||||||
|
|
||||||
if(defined($_)) { $$field_names = $_; }
|
if(defined($_)) { $$field_names = $_; $$dirty = 1; }
|
||||||
|
|
||||||
return $$field_names;
|
return $$field_names;
|
||||||
}
|
}
|
||||||
|
@ -139,11 +175,7 @@ sub field_offsets {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $field_offsets = \${$self->{FIELD_OFFSETS}};
|
my $field_offsets = \${$self->{FIELD_OFFSETS}};
|
||||||
|
|
||||||
my $find_size = shift;
|
$self->_refresh();
|
||||||
|
|
||||||
if (defined($find_size)) {
|
|
||||||
$self->_refresh($find_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $$field_offsets;
|
return $$field_offsets;
|
||||||
}
|
}
|
||||||
|
@ -152,11 +184,7 @@ sub field_sizes {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $field_sizes = \${$self->{FIELD_SIZES}};
|
my $field_sizes = \${$self->{FIELD_SIZES}};
|
||||||
|
|
||||||
my $find_size = shift;
|
$self->_refresh();
|
||||||
|
|
||||||
if (defined($find_size)) {
|
|
||||||
$self->_refresh($find_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $$field_sizes;
|
return $$field_sizes;
|
||||||
}
|
}
|
||||||
|
@ -164,10 +192,11 @@ sub field_sizes {
|
||||||
sub field_type_names {
|
sub field_type_names {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $field_type_names = \${$self->{FIELD_TYPE_NAMES}};
|
my $field_type_names = \${$self->{FIELD_TYPE_NAMES}};
|
||||||
|
my $dirty = \${$self->{DIRTY}};
|
||||||
|
|
||||||
local $_ = shift;
|
local $_ = shift;
|
||||||
|
|
||||||
if(defined($_)) { $$field_type_names = $_; }
|
if(defined($_)) { $$field_type_names = $_; $$dirty = 1; }
|
||||||
|
|
||||||
return $$field_type_names;
|
return $$field_type_names;
|
||||||
}
|
}
|
||||||
|
@ -177,10 +206,7 @@ sub size {
|
||||||
|
|
||||||
my $size = \${$self->{SIZE}};
|
my $size = \${$self->{SIZE}};
|
||||||
|
|
||||||
my $find_size = shift;
|
$self->_refresh();
|
||||||
if (defined($find_size)) {
|
|
||||||
$self->_refresh($find_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $$size;
|
return $$size;
|
||||||
}
|
}
|
||||||
|
@ -188,36 +214,52 @@ sub size {
|
||||||
sub _refresh {
|
sub _refresh {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
|
my $dirty = \${$self->{DIRTY}};
|
||||||
|
|
||||||
|
return if !$$dirty;
|
||||||
|
|
||||||
|
my $find_align = \${$self->{FIND_ALIGN}};
|
||||||
|
my $find_size = \${$self->{FIND_SIZE}};
|
||||||
|
|
||||||
|
my $align = \${$self->{ALIGN}};
|
||||||
|
my $kind = \${$self->{KIND}};
|
||||||
|
my $size = \${$self->{SIZE}};
|
||||||
my $field_aligns = \${$self->{FIELD_ALIGNS}};
|
my $field_aligns = \${$self->{FIELD_ALIGNS}};
|
||||||
|
my $field_base_sizes = \${$self->{FIELD_BASE_SIZES}};
|
||||||
my $field_offsets = \${$self->{FIELD_OFFSETS}};
|
my $field_offsets = \${$self->{FIELD_OFFSETS}};
|
||||||
my $field_sizes = \${$self->{FIELD_SIZES}};
|
my $field_sizes = \${$self->{FIELD_SIZES}};
|
||||||
my $size = \${$self->{SIZE}};
|
|
||||||
|
|
||||||
my $find_size = shift;
|
|
||||||
|
|
||||||
my $pack = $self->pack;
|
my $pack = $self->pack;
|
||||||
|
|
||||||
|
my $max_field_align = 0;
|
||||||
|
|
||||||
my $offset = 0;
|
my $offset = 0;
|
||||||
my $offset_bits = 0;
|
my $offset_bits = 0;
|
||||||
|
|
||||||
my $n = 0;
|
my $n = 0;
|
||||||
foreach my $field ($self->fields) {
|
foreach my $field ($self->fields) {
|
||||||
my $type_name = $field->type_name;
|
my $type_name = $field->type_name;
|
||||||
my $size = &$find_size($type_name);
|
my $size = &$$find_size($type_name);
|
||||||
|
|
||||||
|
|
||||||
my $base_type_name = $type_name;
|
my $base_type_name = $type_name;
|
||||||
if ($base_type_name =~ s/^(.*?)\s*(?:\[\s*(.*?)\s*\]|:(\d+))?$/$1/) {
|
if ($base_type_name =~ s/^(.*?)\s*(?:\[\s*(.*?)\s*\]|:(\d+))?$/$1/) {
|
||||||
my $count = $2;
|
my $count = $2;
|
||||||
my $bits = $3;
|
my $bits = $3;
|
||||||
}
|
}
|
||||||
my $base_size = &$find_size($base_type_name);
|
my $base_size = &$$find_size($base_type_name);
|
||||||
|
my $align = &$$find_align($base_type_name);
|
||||||
|
|
||||||
my $align = 0;
|
if (defined($align)) {
|
||||||
$align = $base_size % 4 if defined($base_size);
|
$align = $pack if $align > $pack;
|
||||||
$align = 4 if !$align;
|
$max_field_align = $align if $align > $max_field_align;
|
||||||
|
|
||||||
|
if ($offset % $align != 0) {
|
||||||
|
$offset = (int($offset / $align) + 1) * $align;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!defined($size)) {
|
if (!defined($size)) {
|
||||||
|
$$align = undef;
|
||||||
$$size = undef;
|
$$size = undef;
|
||||||
return;
|
return;
|
||||||
} elsif ($size >= 0) {
|
} elsif ($size >= 0) {
|
||||||
|
@ -227,12 +269,14 @@ sub _refresh {
|
||||||
}
|
}
|
||||||
|
|
||||||
$$$field_aligns[$n] = $align;
|
$$$field_aligns[$n] = $align;
|
||||||
|
$$$field_base_sizes[$n] = $base_size;
|
||||||
$$$field_offsets[$n] = $offset;
|
$$$field_offsets[$n] = $offset;
|
||||||
$$$field_sizes[$n] = $size;
|
$$$field_sizes[$n] = $size;
|
||||||
|
|
||||||
$offset += $size;
|
$offset += $size;
|
||||||
} else {
|
} else {
|
||||||
$$$field_aligns[$n] = $align;
|
$$$field_aligns[$n] = $align;
|
||||||
|
$$$field_base_sizes[$n] = $base_size;
|
||||||
$$$field_offsets[$n] = $offset;
|
$$$field_offsets[$n] = $offset;
|
||||||
$$$field_sizes[$n] = $size;
|
$$$field_sizes[$n] = $size;
|
||||||
|
|
||||||
|
@ -242,12 +286,17 @@ sub _refresh {
|
||||||
$n++;
|
$n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$$align = $pack;
|
||||||
|
$$align = $max_field_align if $max_field_align < $pack;
|
||||||
|
|
||||||
$$size = $offset;
|
$$size = $offset;
|
||||||
if (1) {
|
if ($$kind =~ /^(?:struct|union)$/) {
|
||||||
if ($$size % $pack != 0) {
|
if ($$size % $$align != 0) {
|
||||||
$$size = (int($$size / $pack) + 1) * $pack;
|
$$size = (int($$size / $$align) + 1) * $$align;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$$dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
package c_type_field;
|
package c_type_field;
|
||||||
|
@ -277,6 +326,16 @@ sub align {
|
||||||
return $$field_aligns[$$number];
|
return $$field_aligns[$$number];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub base_size {
|
||||||
|
my $self = shift;
|
||||||
|
my $type = \${$self->{TYPE}};
|
||||||
|
my $number = \${$self->{NUMBER}};
|
||||||
|
|
||||||
|
my $field_base_sizes = $$type->field_base_sizes;
|
||||||
|
|
||||||
|
return $$field_base_sizes[$$number];
|
||||||
|
}
|
||||||
|
|
||||||
sub name {
|
sub name {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $type = \${$self->{TYPE}};
|
my $type = \${$self->{TYPE}};
|
||||||
|
|
|
@ -1,61 +1,3 @@
|
||||||
%%%dlls/kernel/tests
|
|
||||||
|
|
||||||
%%pack
|
|
||||||
|
|
||||||
%description
|
|
||||||
|
|
||||||
Unit tests for data structure packing
|
|
||||||
|
|
||||||
%include
|
|
||||||
|
|
||||||
basetsd.h
|
|
||||||
winnt.h
|
|
||||||
windef.h
|
|
||||||
winbase.h
|
|
||||||
|
|
||||||
%struct
|
|
||||||
|
|
||||||
BY_HANDLE_FILE_INFORMATION
|
|
||||||
COMMCONFIG
|
|
||||||
COMMPROP
|
|
||||||
COMMTIMEOUTS
|
|
||||||
COMSTAT
|
|
||||||
CREATE_PROCESS_DEBUG_INFO
|
|
||||||
CREATE_THREAD_DEBUG_INFO
|
|
||||||
DCB
|
|
||||||
# DEBUG_EVENT
|
|
||||||
EXCEPTION_DEBUG_INFO
|
|
||||||
EXIT_PROCESS_DEBUG_INFO
|
|
||||||
EXIT_THREAD_DEBUG_INFO
|
|
||||||
# FILETIME
|
|
||||||
HW_PROFILE_INFOA
|
|
||||||
# LDT_ENTRY
|
|
||||||
LOAD_DLL_DEBUG_INFO
|
|
||||||
MEMORYSTATUS
|
|
||||||
OFSTRUCT
|
|
||||||
OSVERSIONINFOA
|
|
||||||
OSVERSIONINFOEXA
|
|
||||||
OSVERSIONINFOEXW
|
|
||||||
OSVERSIONINFOW
|
|
||||||
OUTPUT_DEBUG_STRING_INFO
|
|
||||||
OVERLAPPED
|
|
||||||
# PROCESS_HEAP_ENTRY
|
|
||||||
PROCESS_INFORMATION
|
|
||||||
RIP_INFO
|
|
||||||
SECURITY_ATTRIBUTES
|
|
||||||
STARTUPINFOA
|
|
||||||
STARTUPINFOW
|
|
||||||
SYSLEVEL
|
|
||||||
SYSTEMTIME
|
|
||||||
# SYSTEM_INFO
|
|
||||||
SYSTEM_POWER_STATUS
|
|
||||||
TIME_ZONE_INFORMATION
|
|
||||||
UNLOAD_DLL_DEBUG_INFO
|
|
||||||
WIN32_FILE_ATTRIBUTE_DATA
|
|
||||||
WIN32_FIND_DATAA
|
|
||||||
WIN32_FIND_DATAW
|
|
||||||
WIN32_STREAM_ID
|
|
||||||
|
|
||||||
%%%dlls/gdi/tests
|
%%%dlls/gdi/tests
|
||||||
|
|
||||||
%%pack
|
%%pack
|
||||||
|
@ -102,10 +44,10 @@ EMRARC
|
||||||
EMRBITBLT
|
EMRBITBLT
|
||||||
EMRCREATEBRUSHINDIRECT
|
EMRCREATEBRUSHINDIRECT
|
||||||
EMRCREATECOLORSPACE
|
EMRCREATECOLORSPACE
|
||||||
# EMRCREATECOLORSPACEW
|
EMRCREATECOLORSPACEW
|
||||||
EMRCREATEDIBPATTERNBRUSHPT
|
EMRCREATEDIBPATTERNBRUSHPT
|
||||||
EMRCREATEMONOBRUSH
|
EMRCREATEMONOBRUSH
|
||||||
EMRCREATEPALETTE
|
# EMRCREATEPALETTE
|
||||||
EMRCREATEPEN
|
EMRCREATEPEN
|
||||||
EMRDELETECOLORSPACE
|
EMRDELETECOLORSPACE
|
||||||
EMRDELETEOBJECT
|
EMRDELETEOBJECT
|
||||||
|
@ -115,23 +57,23 @@ EMREXCLUDECLIPRECT
|
||||||
EMREXTCREATEFONTINDIRECTW
|
EMREXTCREATEFONTINDIRECTW
|
||||||
EMREXTCREATEPEN
|
EMREXTCREATEPEN
|
||||||
EMREXTFLOODFILL
|
EMREXTFLOODFILL
|
||||||
# EMREXTSELECTCLIPRGN
|
EMREXTSELECTCLIPRGN
|
||||||
EMREXTTEXTOUTA
|
EMREXTTEXTOUTA
|
||||||
EMRFILLPATH
|
EMRFILLPATH
|
||||||
# EMRFILLRGN
|
EMRFILLRGN
|
||||||
EMRFORMAT
|
EMRFORMAT
|
||||||
# EMRFRAMERGN
|
EMRFRAMERGN
|
||||||
# EMRGDICOMMENT
|
EMRGDICOMMENT
|
||||||
# EMRGLSBOUNDEDRECORD
|
EMRGLSBOUNDEDRECORD
|
||||||
# EMRGLSRECORD
|
EMRGLSRECORD
|
||||||
# EMRINVERTRGN
|
EMRINVERTRGN
|
||||||
EMRLINETO
|
EMRLINETO
|
||||||
EMRMASKBLT
|
EMRMASKBLT
|
||||||
EMRMODIFYWORLDTRANSFORM
|
EMRMODIFYWORLDTRANSFORM
|
||||||
EMROFFSETCLIPRGN
|
EMROFFSETCLIPRGN
|
||||||
EMRPIXELFORMAT
|
EMRPIXELFORMAT
|
||||||
EMRPLGBLT
|
EMRPLGBLT
|
||||||
# EMRPOLYDRAW
|
EMRPOLYDRAW
|
||||||
EMRPOLYLINE
|
EMRPOLYLINE
|
||||||
EMRPOLYPOLYLINE
|
EMRPOLYPOLYLINE
|
||||||
EMRPOLYTEXTOUTA
|
EMRPOLYTEXTOUTA
|
||||||
|
@ -148,7 +90,7 @@ EMRSETCOLORADJUSTMENT
|
||||||
EMRSETDIBITSTODEIVCE
|
EMRSETDIBITSTODEIVCE
|
||||||
EMRSETMAPPERFLAGS
|
EMRSETMAPPERFLAGS
|
||||||
EMRSETMITERLIMIT
|
EMRSETMITERLIMIT
|
||||||
EMRSETPALETTEENTRIES
|
# EMRSETPALETTEENTRIES
|
||||||
EMRSETPIXELV
|
EMRSETPIXELV
|
||||||
EMRSETTEXTJUSTIFICATION
|
EMRSETTEXTJUSTIFICATION
|
||||||
EMRSETVIEWPORTEXTEX
|
EMRSETVIEWPORTEXTEX
|
||||||
|
@ -180,29 +122,29 @@ LOGCOLORSPACEA
|
||||||
LOGCOLORSPACEW
|
LOGCOLORSPACEW
|
||||||
LOGFONTA
|
LOGFONTA
|
||||||
LOGFONTW
|
LOGFONTW
|
||||||
LOGPALETTE
|
# LOGPALETTE
|
||||||
LOGPEN
|
LOGPEN
|
||||||
MAT2
|
MAT2
|
||||||
METAFILEPICT
|
METAFILEPICT
|
||||||
METAHEADER
|
METAHEADER
|
||||||
METARECORD
|
METARECORD
|
||||||
# NEWTEXTMETRICA
|
NEWTEXTMETRICA
|
||||||
NEWTEXTMETRICEXA
|
NEWTEXTMETRICEXA
|
||||||
NEWTEXTMETRICEXW
|
NEWTEXTMETRICEXW
|
||||||
# NEWTEXTMETRICW
|
NEWTEXTMETRICW
|
||||||
# OUTLINETEXTMETRICA
|
OUTLINETEXTMETRICA
|
||||||
# OUTLINETEXTMETRICW
|
OUTLINETEXTMETRICW
|
||||||
PALETTEENTRY
|
# PALETTEENTRY
|
||||||
# PANOSE
|
PANOSE
|
||||||
PELARRAY
|
PELARRAY
|
||||||
PIXELFORMATDESCRIPTOR
|
PIXELFORMATDESCRIPTOR
|
||||||
POINTFX
|
POINTFX
|
||||||
POLYTEXTA
|
POLYTEXTA
|
||||||
POLYTEXTW
|
POLYTEXTW
|
||||||
# RASTERIZER_STATUS
|
RASTERIZER_STATUS
|
||||||
RGBQUAD
|
RGBQUAD
|
||||||
# RGBTRIPLE
|
RGBTRIPLE
|
||||||
# RGNDATA
|
RGNDATA
|
||||||
RGNDATAHEADER
|
RGNDATAHEADER
|
||||||
TEXTMETRICA
|
TEXTMETRICA
|
||||||
TEXTMETRICW
|
TEXTMETRICW
|
||||||
|
@ -211,6 +153,154 @@ TTPOLYCURVE
|
||||||
TTPOLYGONHEADER
|
TTPOLYGONHEADER
|
||||||
XFORM
|
XFORM
|
||||||
|
|
||||||
|
%%%dlls/kernel/tests
|
||||||
|
|
||||||
|
%%pack
|
||||||
|
|
||||||
|
%description
|
||||||
|
|
||||||
|
Unit tests for data structure packing
|
||||||
|
|
||||||
|
%include
|
||||||
|
|
||||||
|
basetsd.h
|
||||||
|
winnt.h
|
||||||
|
windef.h
|
||||||
|
winbase.h
|
||||||
|
|
||||||
|
%struct
|
||||||
|
|
||||||
|
BY_HANDLE_FILE_INFORMATION
|
||||||
|
COMMCONFIG
|
||||||
|
COMMPROP
|
||||||
|
COMMTIMEOUTS
|
||||||
|
COMSTAT
|
||||||
|
CREATE_PROCESS_DEBUG_INFO
|
||||||
|
CREATE_THREAD_DEBUG_INFO
|
||||||
|
DCB
|
||||||
|
DEBUG_EVENT
|
||||||
|
EXCEPTION_DEBUG_INFO
|
||||||
|
EXIT_PROCESS_DEBUG_INFO
|
||||||
|
EXIT_THREAD_DEBUG_INFO
|
||||||
|
# FILETIME
|
||||||
|
HW_PROFILE_INFOA
|
||||||
|
LDT_ENTRY
|
||||||
|
LOAD_DLL_DEBUG_INFO
|
||||||
|
MEMORYSTATUS
|
||||||
|
OFSTRUCT
|
||||||
|
OSVERSIONINFOA
|
||||||
|
OSVERSIONINFOEXA
|
||||||
|
OSVERSIONINFOEXW
|
||||||
|
OSVERSIONINFOW
|
||||||
|
OUTPUT_DEBUG_STRING_INFO
|
||||||
|
OVERLAPPED
|
||||||
|
PROCESS_HEAP_ENTRY
|
||||||
|
PROCESS_INFORMATION
|
||||||
|
RIP_INFO
|
||||||
|
SECURITY_ATTRIBUTES
|
||||||
|
STARTUPINFOA
|
||||||
|
STARTUPINFOW
|
||||||
|
SYSLEVEL
|
||||||
|
SYSTEMTIME
|
||||||
|
# SYSTEM_INFO
|
||||||
|
SYSTEM_POWER_STATUS
|
||||||
|
TIME_ZONE_INFORMATION
|
||||||
|
UNLOAD_DLL_DEBUG_INFO
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA
|
||||||
|
WIN32_FIND_DATAA
|
||||||
|
WIN32_FIND_DATAW
|
||||||
|
WIN32_STREAM_ID
|
||||||
|
|
||||||
|
%%%dlls/ntdll/tests
|
||||||
|
|
||||||
|
%%pack
|
||||||
|
|
||||||
|
%description
|
||||||
|
|
||||||
|
Unit tests for data structure packing
|
||||||
|
|
||||||
|
%include
|
||||||
|
|
||||||
|
basetsd.h
|
||||||
|
winnt.h
|
||||||
|
windef.h
|
||||||
|
|
||||||
|
%struct
|
||||||
|
|
||||||
|
ACCESS_ALLOWED_ACE
|
||||||
|
ACCESS_DENIED_ACE
|
||||||
|
ACE_HEADER
|
||||||
|
ACL
|
||||||
|
CONTEXT86
|
||||||
|
# EXCEPTION_FRAME
|
||||||
|
EXCEPTION_POINTERS
|
||||||
|
EXCEPTION_RECORD
|
||||||
|
FLOATING_SAVE_AREA
|
||||||
|
FPO_DATA
|
||||||
|
GENERIC_MAPPING
|
||||||
|
IMAGE_ARCHIVE_MEMBER_HEADER
|
||||||
|
IMAGE_AUX_SYMBOL
|
||||||
|
IMAGE_BASE_RELOCATION
|
||||||
|
IMAGE_BOUND_FORWARDER_REF
|
||||||
|
IMAGE_BOUND_IMPORT_DESCRIPTOR
|
||||||
|
IMAGE_COFF_SYMBOLS_HEADER
|
||||||
|
IMAGE_DATA_DIRECTORY
|
||||||
|
IMAGE_DEBUG_DIRECTORY
|
||||||
|
IMAGE_DEBUG_MISC
|
||||||
|
IMAGE_DOS_HEADER
|
||||||
|
IMAGE_EXPORT_DIRECTORY
|
||||||
|
IMAGE_FILE_HEADER
|
||||||
|
IMAGE_FUNCTION_ENTRY
|
||||||
|
IMAGE_IMPORT_BY_NAME
|
||||||
|
# IMAGE_IMPORT_DESCRIPTOR
|
||||||
|
# IMAGE_LINENUMBER
|
||||||
|
IMAGE_LOAD_CONFIG_DIRECTORY
|
||||||
|
IMAGE_NT_HEADERS
|
||||||
|
IMAGE_OPTIONAL_HEADER
|
||||||
|
IMAGE_OS2_HEADER
|
||||||
|
# IMAGE_RELOCATION
|
||||||
|
IMAGE_RESOURCE_DATA_ENTRY
|
||||||
|
IMAGE_RESOURCE_DIRECTORY
|
||||||
|
IMAGE_RESOURCE_DIRECTORY_ENTRY
|
||||||
|
IMAGE_RESOURCE_DIRECTORY_STRING
|
||||||
|
IMAGE_RESOURCE_DIR_STRING_U
|
||||||
|
# IMAGE_SECTION_HEADER
|
||||||
|
IMAGE_SEPARATE_DEBUG_HEADER
|
||||||
|
# IMAGE_SYMBOL
|
||||||
|
IMAGE_THUNK_DATA
|
||||||
|
IMAGE_TLS_DIRECTORY
|
||||||
|
IMAGE_VXD_HEADER
|
||||||
|
# LARGE_INTEGER
|
||||||
|
LIST_ENTRY
|
||||||
|
LUID
|
||||||
|
LUID_AND_ATTRIBUTES
|
||||||
|
MEMORY_BASIC_INFORMATION
|
||||||
|
MESSAGE_RESOURCE_BLOCK
|
||||||
|
MESSAGE_RESOURCE_DATA
|
||||||
|
MESSAGE_RESOURCE_ENTRY
|
||||||
|
# NT_TIB
|
||||||
|
PRIVILEGE_SET
|
||||||
|
RTL_CRITICAL_SECTION
|
||||||
|
RTL_CRITICAL_SECTION_DEBUG
|
||||||
|
SECURITY_DESCRIPTOR
|
||||||
|
SECURITY_DESCRIPTOR_RELATIVE
|
||||||
|
# SECURITY_QUALITY_OF_SERVICE
|
||||||
|
SID
|
||||||
|
SID_AND_ATTRIBUTES
|
||||||
|
SID_IDENTIFIER_AUTHORITY
|
||||||
|
SINGLE_LIST_ENTRY
|
||||||
|
SYSTEM_ALARM_ACE
|
||||||
|
SYSTEM_AUDIT_ACE
|
||||||
|
TOKEN_DEFAULT_DACL
|
||||||
|
TOKEN_GROUPS
|
||||||
|
TOKEN_OWNER
|
||||||
|
TOKEN_PRIMARY_GROUP
|
||||||
|
TOKEN_PRIVILEGES
|
||||||
|
TOKEN_SOURCE
|
||||||
|
# TOKEN_STATISTICS
|
||||||
|
TOKEN_USER
|
||||||
|
# ULARGE_INTEGER
|
||||||
|
|
||||||
%%%dlls/user/tests
|
%%%dlls/user/tests
|
||||||
|
|
||||||
%%pack
|
%%pack
|
||||||
|
@ -225,11 +315,12 @@ basetsd.h
|
||||||
winnt.h
|
winnt.h
|
||||||
windef.h
|
windef.h
|
||||||
winbase.h
|
winbase.h
|
||||||
|
wingdi.h
|
||||||
winuser.h
|
winuser.h
|
||||||
|
|
||||||
%struct
|
%struct
|
||||||
|
|
||||||
# ACCEL
|
ACCEL
|
||||||
ACCESSTIMEOUT
|
ACCESSTIMEOUT
|
||||||
ANIMATIONINFO
|
ANIMATIONINFO
|
||||||
CBTACTIVATESTRUCT
|
CBTACTIVATESTRUCT
|
||||||
|
@ -247,7 +338,7 @@ DEBUGHOOKINFO
|
||||||
DELETEITEMSTRUCT
|
DELETEITEMSTRUCT
|
||||||
DLGITEMTEMPLATE
|
DLGITEMTEMPLATE
|
||||||
DLGTEMPLATE
|
DLGTEMPLATE
|
||||||
DRAWITEMSTRUCT
|
# DRAWITEMSTRUCT
|
||||||
DRAWTEXTPARAMS
|
DRAWTEXTPARAMS
|
||||||
EVENTMSG
|
EVENTMSG
|
||||||
FILTERKEYS
|
FILTERKEYS
|
||||||
|
@ -259,9 +350,9 @@ HELPWININFOW
|
||||||
HIGHCONTRASTA
|
HIGHCONTRASTA
|
||||||
HIGHCONTRASTW
|
HIGHCONTRASTW
|
||||||
ICONINFO
|
ICONINFO
|
||||||
# ICONMETRICSA
|
ICONMETRICSA
|
||||||
# ICONMETRICSW
|
ICONMETRICSW
|
||||||
# INPUT
|
INPUT
|
||||||
KBDLLHOOKSTRUCT
|
KBDLLHOOKSTRUCT
|
||||||
KEYBDINPUT
|
KEYBDINPUT
|
||||||
MDICREATESTRUCTA
|
MDICREATESTRUCTA
|
||||||
|
@ -271,13 +362,13 @@ MEASUREITEMSTRUCT
|
||||||
MENUINFO
|
MENUINFO
|
||||||
MENUITEMINFOA
|
MENUITEMINFOA
|
||||||
MENUITEMINFOW
|
MENUITEMINFOW
|
||||||
# MENUITEMTEMPLATE
|
MENUITEMTEMPLATE
|
||||||
MENUITEMTEMPLATEHEADER
|
MENUITEMTEMPLATEHEADER
|
||||||
MINIMIZEDMETRICS
|
MINIMIZEDMETRICS
|
||||||
MINMAXINFO
|
MINMAXINFO
|
||||||
MONITORINFO
|
MONITORINFO
|
||||||
# MONITORINFOEXA
|
MONITORINFOEXA
|
||||||
# MONITORINFOEXW
|
MONITORINFOEXW
|
||||||
MOUSEHOOKSTRUCT
|
MOUSEHOOKSTRUCT
|
||||||
MOUSEINPUT
|
MOUSEINPUT
|
||||||
MOUSEKEYS
|
MOUSEKEYS
|
||||||
|
@ -289,8 +380,8 @@ MULTIKEYHELPA
|
||||||
MULTIKEYHELPW
|
MULTIKEYHELPW
|
||||||
NCCALCSIZE_PARAMS
|
NCCALCSIZE_PARAMS
|
||||||
NMHDR
|
NMHDR
|
||||||
# NONCLIENTMETRICSA
|
NONCLIENTMETRICSA
|
||||||
# NONCLIENTMETRICSW
|
NONCLIENTMETRICSW
|
||||||
PAINTSTRUCT
|
PAINTSTRUCT
|
||||||
SCROLLINFO
|
SCROLLINFO
|
||||||
SERIALKEYSA
|
SERIALKEYSA
|
||||||
|
@ -303,7 +394,7 @@ TOGGLEKEYS
|
||||||
TPMPARAMS
|
TPMPARAMS
|
||||||
TRACKMOUSEEVENT
|
TRACKMOUSEEVENT
|
||||||
WINDOWINFO
|
WINDOWINFO
|
||||||
WINDOWPLACEMENT
|
# WINDOWPLACEMENT
|
||||||
WINDOWPOS
|
WINDOWPOS
|
||||||
WNDCLASSA
|
WNDCLASSA
|
||||||
WNDCLASSEXA
|
WNDCLASSEXA
|
||||||
|
|
|
@ -331,7 +331,7 @@ foreach my $file (@h_files, @c_files) {
|
||||||
my $field_type_name = $field->type_name;
|
my $field_type_name = $field->type_name;
|
||||||
my $field_name = $field->name;
|
my $field_name = $field->name;
|
||||||
|
|
||||||
if ($options->struct) {
|
if ($options->struct && $kind =~ /^(?:struct|union)$/) {
|
||||||
if ($name) {
|
if ($name) {
|
||||||
$output->write("$name:$field_type_name:$field_name\n");
|
$output->write("$name:$field_type_name:$field_name\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -104,8 +104,70 @@ my %defines = (
|
||||||
"SIZE_OF_80387_REGISTERS" => 80,
|
"SIZE_OF_80387_REGISTERS" => 80,
|
||||||
);
|
);
|
||||||
|
|
||||||
my %kludge_reported = ("FILETIME" => 1, "LARGE_INTEGER" => 1);
|
my %align_kludge_reported = ("FILETIME" => 1, "LARGE_INTEGER" => 1);
|
||||||
my %parse_reported;
|
|
||||||
|
sub find_align {
|
||||||
|
my $type_name = shift;
|
||||||
|
|
||||||
|
local $_ = $type_name;
|
||||||
|
|
||||||
|
# Remove "count" and "bits"
|
||||||
|
s/^(.*?)\s*(?:\[\s*(.*?)\s*\]|:(\d+))?$/$1/;
|
||||||
|
|
||||||
|
my $align;
|
||||||
|
if (0) {
|
||||||
|
# Nothing
|
||||||
|
} elsif (/\*+$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif(/^(?:(?:signed\s+|unsigned\s+)?char)$/) {
|
||||||
|
$align = 1;
|
||||||
|
} elsif (/^(?:(?:signed\s+|unsigned\s+)?short)$/) {
|
||||||
|
$align = 2;
|
||||||
|
} elsif (/^(?:wchar_t)$/) {
|
||||||
|
$align = 2;
|
||||||
|
} elsif (/^(?:(?:signed\s+|unsigned\s+)?(?:__int32|int|long(?:\s+int)?)|unsigned|signed)$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif (/^(?:float)$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif (/^(?:signed\s+|unsigned\s+)?__int64$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif (/^(?:double)$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif (/^(?:long\s+double)$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif (/^H(?:DC|BITMAP|BRUSH|ICON|INSTANCE|MENU|METAFILE|WND)$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif (/^LP(?:CSTR|CWSTR|DWORD|STR|VOID|THREAD_START_ROUTINE|WSTR)$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif (/^(?:(?:MSGBOX)CALLBACK[AW]?|(?:FAR|WND)PROC[AW]?)$/) {
|
||||||
|
$align = 4;
|
||||||
|
} elsif (/^(?:FILETIME|LARGE_INTEGER|LONGLONG)$/) {
|
||||||
|
$align = 4;
|
||||||
|
} else {
|
||||||
|
$align = undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $align2;
|
||||||
|
if (defined(my $type = $type_name2type{$_})) {
|
||||||
|
$align2 = $type->align;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!defined($align)) {
|
||||||
|
$align = $align2;
|
||||||
|
} elsif (defined($align2) && !$align_kludge_reported{$_}) {
|
||||||
|
$align_kludge_reported{$_} = 1;
|
||||||
|
$output->write("$type_name: type needn't be kludged\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!defined($align)) {
|
||||||
|
# $output->write("$type_name: can't find type\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $align;
|
||||||
|
}
|
||||||
|
|
||||||
|
my %size_kludge_reported = ("FILETIME" => 1, "LARGE_INTEGER" => 1);
|
||||||
|
my %size_parse_reported;
|
||||||
|
|
||||||
sub find_size {
|
sub find_size {
|
||||||
my $type_name = shift;
|
my $type_name = shift;
|
||||||
|
@ -148,12 +210,10 @@ sub find_size {
|
||||||
$size = 4;
|
$size = 4;
|
||||||
} elsif (/^(?:FILETIME|LARGE_INTEGER|LONGLONG)$/) {
|
} elsif (/^(?:FILETIME|LARGE_INTEGER|LONGLONG)$/) {
|
||||||
$size = 8;
|
$size = 8;
|
||||||
} elsif (/^(?:CRITICAL_SECTION)$/) {
|
|
||||||
$size = 24;
|
|
||||||
} elsif (/^(?:struct|union)$/) {
|
} elsif (/^(?:struct|union)$/) {
|
||||||
if (!$parse_reported{$_}) {
|
if (!$size_parse_reported{$_}) {
|
||||||
$output->write("$type_name: can't parse type\n");
|
$output->write("$type_name: can't parse type\n");
|
||||||
$parse_reported{$_} = 1;
|
$size_parse_reported{$_} = 1;
|
||||||
}
|
}
|
||||||
$size = undef;
|
$size = undef;
|
||||||
} else {
|
} else {
|
||||||
|
@ -167,8 +227,8 @@ sub find_size {
|
||||||
|
|
||||||
if (!defined($size)) {
|
if (!defined($size)) {
|
||||||
$size = $size2;
|
$size = $size2;
|
||||||
} elsif (defined($size2) && !$kludge_reported{$_}) {
|
} elsif (defined($size2) && !$size_kludge_reported{$_}) {
|
||||||
$kludge_reported{$_} = 1;
|
$size_kludge_reported{$_} = 1;
|
||||||
$output->write("$type_name: type needn't be kludged\n");
|
$output->write("$type_name: type needn't be kludged\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +306,7 @@ foreach my $file (@files) {
|
||||||
if (/^\#\s*include\s+\"pshpack(\d+)\.h\"$/) {
|
if (/^\#\s*include\s+\"pshpack(\d+)\.h\"$/) {
|
||||||
push @packs, $1;
|
push @packs, $1;
|
||||||
} elsif(/^\#\s*include\s+\"poppack\.h\"$/) {
|
} elsif(/^\#\s*include\s+\"poppack\.h\"$/) {
|
||||||
unshift @packs;
|
pop @packs;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -258,23 +318,29 @@ foreach my $file (@files) {
|
||||||
|
|
||||||
&$update_output();
|
&$update_output();
|
||||||
|
|
||||||
if (!defined($type->pack)) {
|
|
||||||
my $pack = $packs[$#packs];
|
|
||||||
$type->pack($pack);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $name = $type->name;
|
my $name = $type->name;
|
||||||
$file2types{$file}{$name} = $type;
|
$file2types{$file}{$name} = $type;
|
||||||
|
|
||||||
my $size = $type->size(\&find_size);
|
$type->set_find_align_callback(\&find_align);
|
||||||
|
$type->set_find_size_callback(\&find_size);
|
||||||
|
|
||||||
|
my $pack = $packs[$#packs];
|
||||||
|
if (!defined($type->pack)) {
|
||||||
|
$type->pack($pack);
|
||||||
|
}
|
||||||
|
my $size = $type->size();
|
||||||
if (defined($size)) {
|
if (defined($size)) {
|
||||||
foreach my $field ($type->fields(\&find_size)) {
|
my $max_field_base_size = 0;
|
||||||
|
|
||||||
|
foreach my $field ($type->fields()) {
|
||||||
my $field_type_name = $field->type_name;
|
my $field_type_name = $field->type_name;
|
||||||
my $field_name = $field->name;
|
my $field_name = $field->name;
|
||||||
my $field_size = $field->size;
|
my $field_size = $field->size;
|
||||||
|
my $field_base_size = $field->base_size;
|
||||||
my $field_offset = $field->offset;
|
my $field_offset = $field->offset;
|
||||||
|
my $field_align = $field->align;
|
||||||
|
|
||||||
# $output->write("$name: $field_type_name: $field_name: $field_offset: $field_size\n");
|
# $output->write("$name: $field_type_name: $field_name: $field_offset: $field_size($field_base_size): $field_align\n");
|
||||||
}
|
}
|
||||||
# $output->write("$name: $size\n");
|
# $output->write("$name: $size\n");
|
||||||
|
|
||||||
|
@ -324,6 +390,7 @@ sub output_header {
|
||||||
print OUT "#include <stdio.h>\n";
|
print OUT "#include <stdio.h>\n";
|
||||||
print OUT "\n";
|
print OUT "\n";
|
||||||
print OUT "#include \"wine/test.h\"\n";
|
print OUT "#include \"wine/test.h\"\n";
|
||||||
|
print OUT "#include \"wine/test_generated.h\"\n";
|
||||||
foreach my $test (@tests) {
|
foreach my $test (@tests) {
|
||||||
my @includes = $tests->get_section($test_dir, $test, "include");
|
my @includes = $tests->get_section($test_dir, $test, "include");
|
||||||
foreach my $include (@includes) {
|
foreach my $include (@includes) {
|
||||||
|
@ -377,12 +444,17 @@ sub output_test_pack {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$type_name_not_used{$type_name} = 0;
|
$type_name_not_used{$type_name} = 0;
|
||||||
|
|
||||||
my $pack = $type->pack;
|
|
||||||
|
|
||||||
print OUT " /* $type_name */\n";
|
my $type_align = $type->align;
|
||||||
|
my $type_pack = $type->pack;
|
||||||
|
my $type_size = $type->size;
|
||||||
|
|
||||||
foreach my $field ($type->fields(\&find_size)) {
|
print OUT " /* $type_name (pack $type_pack) */\n";
|
||||||
|
if (defined($type_align) && defined($type_size)) {
|
||||||
|
print OUT " TEST_TYPE($type_name, $type_size, $type_align);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $field ($type->fields()) {
|
||||||
my $field_type_name = $field->type_name;
|
my $field_type_name = $field->type_name;
|
||||||
my $field_name = $field->name;
|
my $field_name = $field->name;
|
||||||
my $field_size = $field->size;
|
my $field_size = $field->size;
|
||||||
|
@ -392,30 +464,12 @@ sub output_test_pack {
|
||||||
next if $field_name eq "" || (defined($field_size) && $field_size < 0);
|
next if $field_name eq "" || (defined($field_size) && $field_size < 0);
|
||||||
|
|
||||||
if (defined($field_size) && defined($field_offset)) {
|
if (defined($field_size) && defined($field_offset)) {
|
||||||
print OUT " ok(FIELD_OFFSET($type_name, $field_name) == $field_offset,\n";
|
print OUT " TEST_FIELD($type_name, $field_type_name, $field_name, $field_offset, $field_size, $field_align);\n";
|
||||||
print OUT " \"FIELD_OFFSET($type_name, $field_name) == %ld (expected $field_offset)\",\n";
|
|
||||||
print OUT " FIELD_OFFSET($type_name, $field_name)); /* $field_type_name */\n";
|
|
||||||
|
|
||||||
if (0) {
|
|
||||||
print OUT " ok(TYPE_ALIGNMENT($field_type_name) == $field_align,\n";
|
|
||||||
print OUT " \"TYPE_ALIGNMENT($field_type_name) == %d (expected $field_align)\",\n";
|
|
||||||
print OUT " TYPE_ALIGNMENT($field_type_name)); /* $field_name */\n";
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$output->write("$type_name: $field_type_name: $field_name: test not generated (offset not defined)\n");
|
$output->write("$type_name: $field_type_name: $field_name: test not generated (offset not defined)\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
print OUT "\n";
|
||||||
my $type_size = $type->size;
|
|
||||||
|
|
||||||
if (defined($type_size)) {
|
|
||||||
print OUT " ok(sizeof($type_name) == $type_size, ";
|
|
||||||
print OUT "\"sizeof($type_name) == %d (expected $type_size)\", ";
|
|
||||||
print OUT "sizeof($type_name));\n";
|
|
||||||
print OUT "\n";
|
|
||||||
} else {
|
|
||||||
$output->write("$type_name: test not generated (size not defined)\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue