winapi_test update

Patrik Stridvall ps at leissner.se
Mon Oct 7 13:37:56 CDT 2002


*** winapi_test

* tools/winapi/c_parser.pm,
  tools/winapi/c_type.pm,
  tools/winapi/tests.dat,
  tools/winapi/winapi_extract,
  tools/winapi/winapi_test:
Reorganized the code for better
support of data structures parsing. 

Index: wine/tools/winapi/c_parser.pm
===================================================================
RCS file: /home/wine/wine/tools/winapi/c_parser.pm,v
retrieving revision 1.7
diff -u -u -r1.7 c_parser.pm
--- wine/tools/winapi/c_parser.pm	1 Oct 2002 18:10:54 -0000	1.7
+++ wine/tools/winapi/c_parser.pm	7 Oct 2002 18:32:39 -0000
@@ -1112,8 +1112,8 @@
 
     my $match;
 
while($self->_parse_c('(?:const|inline|extern(?:\s+\"C\")?|EXTERN_C|static|v
olatile|' .
-
'signed(?=\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b)|' .
-
'unsigned(?=\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b)|' .
+
'signed(?=\s+__int64\b|\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b)|
' .
+
'unsigned(?=\s+__int64\b|\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b
)|' .
 			  'long(?=\s+double\b|\s+int\b|\s+long\b))(?=\b)',
 			  \$_, \$line, \$column, \$match))
     {
@@ -1654,22 +1654,22 @@
 
 	if ($kind =~ /^struct|union$/) {
 	    my $name = "";
-	    my @field_types = ();
+	    my @field_type_names = ();
 	    my @field_names = ();
 
 	    my $match;
-	    while ($self->_parse_c_on_same_level_until_one_of(';', \$_,
\$line, \$column, \$match))
+	    while ($_ && $self->_parse_c_on_same_level_until_one_of(';',
\$_, \$line, \$column, \$match))
 	    {
 		my $field_linkage;
-		my $field_type;
+		my $field_type_name;
 		my $field_name;
 
-		if ($self->parse_c_variable(\$match, \$line, \$column,
\$field_linkage, \$field_type, \$field_name)) {
-		    $field_type =~ s/\s+/ /g;
+		if ($self->parse_c_variable(\$match, \$line, \$column,
\$field_linkage, \$field_type_name, \$field_name)) {
+		    $field_type_name =~ s/\s+/ /g;
 		    
-		    push @field_types, $field_type;
+		    push @field_type_names, $field_type_name;
 		    push @field_names, $field_name;
-		    #
$output->write("$kind:$_name:$field_type:$field_name\n");
+		    #
$output->write("$kind:$_name:$field_type_name:$field_name\n");
 		} elsif ($match) {
 		    $self->_parse_c_error($_, $line, $column, "typedef
$kind: '$match'");
 		}
@@ -1708,7 +1708,7 @@
 	    $type->kind($kind);
 	    $type->_name($_name);
 	    $type->name($name);
-	    $type->field_types([@field_types]);
+	    $type->field_type_names([@field_type_names]);
 	    $type->field_names([@field_names]);
 
 	    &$$found_type($type);
@@ -1759,9 +1759,43 @@
 	    # FIXME: Not correct
 	    # $output->write("typedef:$name:$_name\n");
 	}
-
     } elsif ($self->_parse_c("typedef", \$_, \$line, \$column)) {
-	# Nothing
+	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();
+		
+		if (length($name) == 0) {
+		    $self->_parse_c_error($_, $line, $column, "typedef");
+		}
+
+		$type->kind("");
+		$type->name($name);
+		$type->pack(1);
+		$type->field_type_names([$type_name]);
+		$type->field_names([""]);
+
+		&$$found_type($type);
+	    }
+
+	    if (0 && $_ && !/^,/) {
+		$self->_parse_c_error($_, $line, $column, "typedef");
+	    }   
+	} else {
+	    $self->_parse_c_error($_, $line, $column, "typedef");
+	}
+    } 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);
+
     } else {
 	return 0;
     }
@@ -1808,8 +1842,8 @@
 
     my $match;
 
while($self->_parse_c('(?:const|inline|extern(?:\s+\"C\")?|EXTERN_C|static|v
olatile|' .
-
'signed(?=\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b)|' .
-
'unsigned(?=\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b)|' .
+
'signed(?=\s+__int64\b|\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b)|
' .
+
'unsigned(?=\s+__int64\b|\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b
)|' .
 			  'long(?=\s+double\b|\s+int\b|\s+long\b))(?=\b)',
 			  \$_, \$line, \$column, \$match))
     {
@@ -1824,6 +1858,8 @@
 
     if($finished) {
 	# Nothing
+    } elsif(/^$/) {
+	return 0;
     } elsif(s/^(enum|struct|union)(?:\s+(\w+))?\s*\{//s) {
 	my $kind = $1;
 	my $_name = $2;
@@ -1865,6 +1901,8 @@
 	$name = $2;
 
 	$finished = 1;
+    } else {
+	$self->_parse_c_warning($_, $line, $column, "variable", "'$_'");
     }
 
     if($finished) {
Index: wine/tools/winapi/c_type.pm
===================================================================
RCS file: /home/wine/wine/tools/winapi/c_type.pm,v
retrieving revision 1.3
diff -u -u -r1.3 c_type.pm
--- wine/tools/winapi/c_type.pm	2 Oct 2002 19:54:14 -0000	1.3
+++ wine/tools/winapi/c_type.pm	7 Oct 2002 18:32:40 -0000
@@ -20,6 +20,8 @@
 
 use strict;
 
+use output qw($output);
+
 sub new {
     my $proto = shift;
     my $class = ref($proto) || $proto;
@@ -83,18 +85,45 @@
 sub fields {
     my $self = shift;
 
-    my @field_types = @{$self->field_types};
-    my @field_names = @{$self->field_names};
+    my $find_size = shift;
+
+    if (defined($find_size)) {
+	$self->_refresh($find_size);
+    }
+
+    my $count = $self->field_count;
 
-    my $count = scalar(@field_types);
-    
     my @fields = ();
     for (my $n = 0; $n < $count; $n++) {
-	push @fields, [$field_types[$n], $field_names[$n]];
+	my $field = 'c_type_field'->new($self, $n);
+	push @fields, $field;
     }
     return @fields;
 }
 
+sub field_aligns {
+    my $self = shift;
+    my $field_aligns = \${$self->{FIELD_ALIGNS}};
+
+    my $find_size = shift;
+
+    if (defined($find_size)) {
+	$self->_refresh($find_size);
+    }
+
+    return $$field_aligns;
+}
+
+sub field_count {
+    my $self = shift;
+    my $field_type_names = \${$self->{FIELD_TYPE_NAMES}};
+
+    my @field_type_names = @{$$field_type_names}; 
+    my $count = scalar(@field_type_names);
+
+    return $count;
+}
+
 sub field_names {
     my $self = shift;
     my $field_names = \${$self->{FIELD_NAMES}};
@@ -106,15 +135,186 @@
     return $$field_names;
 }
 
-sub field_types {
+sub field_offsets {
     my $self = shift;
-    my $field_types = \${$self->{FIELD_TYPES}};
+    my $field_offsets = \${$self->{FIELD_OFFSETS}};
+
+    my $find_size = shift;
+
+    if (defined($find_size)) {
+	$self->_refresh($find_size);
+    }
+
+    return $$field_offsets;
+}
+
+sub field_sizes {
+    my $self = shift;
+    my $field_sizes = \${$self->{FIELD_SIZES}};
+
+    my $find_size = shift;
+
+    if (defined($find_size)) {
+	$self->_refresh($find_size);
+    }
+
+    return $$field_sizes;
+}
+
+sub field_type_names {
+    my $self = shift;
+    my $field_type_names = \${$self->{FIELD_TYPE_NAMES}};
 
     local $_ = shift;
 
-    if(defined($_)) { $$field_types = $_; }
+    if(defined($_)) { $$field_type_names = $_; }
+
+    return $$field_type_names;
+}
+
+sub size {
+    my $self = shift;
+
+    my $size = \${$self->{SIZE}};
+
+    my $find_size = shift;
+    if (defined($find_size)) {
+	$self->_refresh($find_size);
+    }
+
+    return $$size;
+}
+
+sub _refresh {
+    my $self = shift;
+
+    my $field_aligns = \${$self->{FIELD_ALIGNS}};
+    my $field_offsets = \${$self->{FIELD_OFFSETS}};
+    my $field_sizes = \${$self->{FIELD_SIZES}};
+    my $size = \${$self->{SIZE}};
+
+    my $find_size = shift;
+
+    my $pack = $self->pack;
+
+    my $offset = 0;
+    my $offset_bits = 0;
+
+    my $n = 0;
+    foreach my $field ($self->fields) {
+	my $type_name = $field->type_name;
+	my $size = &$find_size($type_name);
+
+
+	my $base_type_name = $type_name;
+	if ($base_type_name =~ s/^(.*?)\s*(?:\[\s*(.*?)\s*\]|:(\d+))?$/$1/)
{
+	    my $count = $2;
+	    my $bits = $3;
+	}
+	my $base_size = &$find_size($base_type_name);
+
+	my $align = 0;
+	$align = $base_size % 4 if defined($base_size);
+	$align = 4 if !$align;
+
+	if (!defined($size)) {
+	    $$size = undef;
+	    return;
+	} elsif ($size >= 0) {
+	    if ($offset_bits) {
+		$offset += $pack * int(($offset_bits + 8 * $pack - 1 ) / (8
* $pack));
+		$offset_bits = 0;
+	    }
+
+	    $$$field_aligns[$n] = $align;
+	    $$$field_offsets[$n] = $offset;
+	    $$$field_sizes[$n] = $size;
+
+	    $offset += $size;
+	} else {
+	    $$$field_aligns[$n] = $align;
+	    $$$field_offsets[$n] = $offset;
+	    $$$field_sizes[$n] = $size;
+
+	    $offset_bits += -$size;
+	}
+
+	$n++;
+    }
+
+    $$size = $offset;
+    if (1) {
+	if ($$size % $pack != 0) {
+	    $$size = (int($$size / $pack) + 1) * $pack;
+	}
+    }
+}
+
+package c_type_field;
+
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my $self  = {};
+    bless ($self, $class);
+
+    my $type = \${$self->{TYPE}};
+    my $number = \${$self->{NUMBER}};
+
+    $$type = shift;
+    $$number = shift;
+
+    return $self;
+}
+
+sub align {
+    my $self = shift;
+    my $type = \${$self->{TYPE}};
+    my $number = \${$self->{NUMBER}};
+
+    my $field_aligns = $$type->field_aligns;
+
+    return $$field_aligns[$$number];
+}
+
+sub name {
+    my $self = shift;
+    my $type = \${$self->{TYPE}};
+    my $number = \${$self->{NUMBER}};
+
+    my $field_names = $$type->field_names;
+
+    return $$field_names[$$number];
+}
+
+sub offset {
+    my $self = shift;
+    my $type = \${$self->{TYPE}};
+    my $number = \${$self->{NUMBER}};
+
+    my $field_offsets = $$type->field_offsets;
+
+    return $$field_offsets[$$number];
+}
+
+sub size {
+    my $self = shift;
+    my $type = \${$self->{TYPE}};
+    my $number = \${$self->{NUMBER}};
+
+    my $field_sizes = $$type->field_sizes;
+
+    return $$field_sizes[$$number];
+}
+
+sub type_name {
+    my $self = shift;
+    my $type = \${$self->{TYPE}};
+    my $number = \${$self->{NUMBER}};
+
+    my $field_type_names = $$type->field_type_names;
 
-    return $$field_types;
+    return $$field_type_names[$$number];
 }
 
 1;
Index: wine/tools/winapi/tests.dat
===================================================================
RCS file: /home/wine/wine/tools/winapi/tests.dat,v
retrieving revision 1.2
diff -u -u -r1.2 tests.dat
--- wine/tools/winapi/tests.dat	2 Oct 2002 19:54:14 -0000	1.2
+++ wine/tools/winapi/tests.dat	7 Oct 2002 18:32:40 -0000
@@ -8,6 +8,9 @@
 
 %include
 
+basetsd.h
+winnt.h
+windef.h
 winbase.h
 
 %struct
@@ -25,11 +28,11 @@
 EXIT_PROCESS_DEBUG_INFO
 EXIT_THREAD_DEBUG_INFO
 # FILETIME
-# HW_PROFILE_INFOA
-LDT_ENTRY
+HW_PROFILE_INFOA
+# LDT_ENTRY
 LOAD_DLL_DEBUG_INFO
 MEMORYSTATUS
-# OFSTRUCT
+OFSTRUCT
 OSVERSIONINFOA
 OSVERSIONINFOEXA
 OSVERSIONINFOEXW
@@ -44,7 +47,7 @@
 STARTUPINFOW
 SYSLEVEL
 SYSTEMTIME
-SYSTEM_INFO
+# SYSTEM_INFO
 SYSTEM_POWER_STATUS
 TIME_ZONE_INFORMATION
 UNLOAD_DLL_DEBUG_INFO
@@ -63,6 +66,9 @@
 
 %include
 
+basetsd.h
+winnt.h
+windef.h
 wingdi.h
 
 %struct
@@ -71,20 +77,20 @@
 ABCFLOAT
 BITMAP
 BITMAPCOREHEADER
-# BITMAPCOREINFO
+BITMAPCOREINFO
 BITMAPFILEHEADER
-# BITMAPINFO
+BITMAPINFO
 BITMAPINFOHEADER
-# BITMAPV4HEADER
-# BITMAPV5HEADER
+BITMAPV4HEADER
+BITMAPV5HEADER
 BLENDFUNCTION
-# CHARSETINFO
+CHARSETINFO
 CIEXYZ
-# CIEXYZTRIPLE
-# COLORADJUSTMENT
+CIEXYZTRIPLE
+COLORADJUSTMENT
 # DEVMODEA
 # DEVMODEW
-# DIBSECTION
+DIBSECTION
 DISPLAY_DEVICEA
 DISPLAY_DEVICEW
 DOCINFOA
@@ -94,23 +100,23 @@
 EMRANGLEARC
 EMRARC
 EMRBITBLT
-# EMRCREATEBRUSHINDIRECT
-# EMRCREATECOLORSPACE
+EMRCREATEBRUSHINDIRECT
+EMRCREATECOLORSPACE
 # EMRCREATECOLORSPACEW
 EMRCREATEDIBPATTERNBRUSHPT
 EMRCREATEMONOBRUSH
-# EMRCREATEPALETTE
-# EMRCREATEPEN
+EMRCREATEPALETTE
+EMRCREATEPEN
 EMRDELETECOLORSPACE
 EMRDELETEOBJECT
 EMRELLIPSE
 EMREOF
 EMREXCLUDECLIPRECT
-# EMREXTCREATEFONTINDIRECTW
-# EMREXTCREATEPEN
+EMREXTCREATEFONTINDIRECTW
+EMREXTCREATEPEN
 EMREXTFLOODFILL
 # EMREXTSELECTCLIPRGN
-# EMREXTTEXTOUTA
+EMREXTTEXTOUTA
 EMRFILLPATH
 # EMRFILLRGN
 EMRFORMAT
@@ -123,12 +129,12 @@
 EMRMASKBLT
 EMRMODIFYWORLDTRANSFORM
 EMROFFSETCLIPRGN
-# EMRPIXELFORMAT
+EMRPIXELFORMAT
 EMRPLGBLT
 # EMRPOLYDRAW
 EMRPOLYLINE
 EMRPOLYPOLYLINE
-# EMRPOLYTEXTOUTA
+EMRPOLYTEXTOUTA
 EMRRESIZEPALETTE
 EMRRESTOREDC
 EMRROUNDRECT
@@ -138,7 +144,7 @@
 EMRSETARCDIRECTION
 EMRSETBKCOLOR
 EMRSETBRUSHORGEX
-# EMRSETCOLORADJUSTMENT
+EMRSETCOLORADJUSTMENT
 EMRSETDIBITSTODEIVCE
 EMRSETMAPPERFLAGS
 EMRSETMITERLIMIT
@@ -150,30 +156,30 @@
 EMRSTRETCHBLT
 EMRSTRETCHDIBITS
 EMRTEXT
-# ENHMETAHEADER
+ENHMETAHEADER
 ENHMETARECORD
-# ENUMLOGFONTA
-# ENUMLOGFONTEXA
-# ENUMLOGFONTEXW
-# ENUMLOGFONTW
-# EXTLOGFONTA
-# EXTLOGFONTW
+ENUMLOGFONTA
+ENUMLOGFONTEXA
+ENUMLOGFONTEXW
+ENUMLOGFONTW
+EXTLOGFONTA
+EXTLOGFONTW
 EXTLOGPEN
-# FIXED
+FIXED
 FONTSIGNATURE
 GCP_RESULTSA
 GCP_RESULTSW
-# GLYPHMETRICS
+GLYPHMETRICS
 GRADIENT_RECT
 GRADIENT_TRIANGLE
 HANDLETABLE
 KERNINGPAIR
 LOCALESIGNATURE
 LOGBRUSH
-# LOGCOLORSPACEA
-# LOGCOLORSPACEW
-# LOGFONTA
-# LOGFONTW
+LOGCOLORSPACEA
+LOGCOLORSPACEW
+LOGFONTA
+LOGFONTW
 LOGPALETTE
 LOGPEN
 MAT2
@@ -181,8 +187,8 @@
 METAHEADER
 METARECORD
 # NEWTEXTMETRICA
-# NEWTEXTMETRICEXA
-# NEWTEXTMETRICEXW
+NEWTEXTMETRICEXA
+NEWTEXTMETRICEXW
 # NEWTEXTMETRICW
 # OUTLINETEXTMETRICA
 # OUTLINETEXTMETRICW
@@ -191,18 +197,18 @@
 PELARRAY
 PIXELFORMATDESCRIPTOR
 POINTFX
-# POLYTEXTA
-# POLYTEXTW
+POLYTEXTA
+POLYTEXTW
 # RASTERIZER_STATUS
 RGBQUAD
 # RGBTRIPLE
 # RGNDATA
-# RGNDATAHEADER
+RGNDATAHEADER
 TEXTMETRICA
 TEXTMETRICW
-# TRIVERTEX
-# TTPOLYCURVE
-# TTPOLYGONHEADER
+TRIVERTEX
+TTPOLYCURVE
+TTPOLYGONHEADER
 XFORM
 
 %%%dlls/user/tests
@@ -215,6 +221,9 @@
 
 %include
 
+basetsd.h
+winnt.h
+windef.h
 winbase.h
 winuser.h
 
Index: wine/tools/winapi/winapi_extract
===================================================================
RCS file: /home/wine/wine/tools/winapi/winapi_extract,v
retrieving revision 1.18
diff -u -u -r1.18 winapi_extract
--- wine/tools/winapi/winapi_extract	1 Oct 2002 18:10:54 -0000	1.18
+++ wine/tools/winapi/winapi_extract	7 Oct 2002 18:32:40 -0000
@@ -328,13 +328,14 @@
 	my $name = $type->name;
 	
 	foreach my $field ($type->fields) {
-	    (my $field_type, my $field_name) = @$field;
+	    my $field_type_name = $field->type_name;
+	    my $field_name = $field->name;
 
 	    if ($options->struct) {
 		if ($name) {
-		    $output->write("$name:$field_type:$field_name\n");
+		    $output->write("$name:$field_type_name:$field_name\n");
 		} else {
-		    $output->write("$kind
$_name:$field_type:$field_name\n");
+		    $output->write("$kind
$_name:$field_type_name:$field_name\n");
 		}
 	    }
 	}
Index: wine/tools/winapi/winapi_test
===================================================================
RCS file: /home/wine/wine/tools/winapi/winapi_test,v
retrieving revision 1.2
diff -u -u -r1.2 winapi_test
--- wine/tools/winapi/winapi_test	2 Oct 2002 19:54:14 -0000	1.2
+++ wine/tools/winapi/winapi_test	7 Oct 2002 18:32:40 -0000
@@ -49,7 +49,7 @@
 
 my @files = ();
 {
-    my %files;    
+    my %files;
 
     my %test_dirs;
     foreach my $test (@tests) {
@@ -57,11 +57,23 @@
 	foreach my $test_dir (@test_dirs) {
 	    my @includes = $tests->get_section($test_dir, $test, "include");
 	    foreach my $include (@includes) {
-		$files{"include/$include"}++;
+		$files{"include/$include"} = 1;
+	    }
+	}
+    }
+
+    foreach my $test (@tests) {
+	my @test_dirs = $tests->get_test_dirs($test);
+	foreach my $test_dir (@test_dirs) {
+	    my @includes = $tests->get_section($test_dir, $test, "include");
+	    foreach my $include (@includes) {
+		if($files{"include/$include"}) {
+		    push @files, "include/$include";
+		    $files{"include/$include"} = 0;
+		}
 	    }
 	}
     }
-    @files = sort(keys(%files));
 }
 
 my %file2types;
@@ -70,6 +82,114 @@
 my $progress_current = 0;
 my $progress_max = scalar(@files);
 
+########################################################################
+# find_type
+
+my %type_name2type;
+
+my %defines = (
+    "ANYSIZE_ARRAY" => 1,
+    "CCHDEVICENAME" => 32,
+    "ELF_VENDOR_SIZE" => 4,
+    "EXCEPTION_MAXIMUM_PARAMETERS" => 15,
+    "HW_PROFILE_GUIDLEN" => 39,
+    "IMAGE_NUMBEROF_DIRECTORY_ENTRIES" => 16,
+    "IMAGE_SIZEOF_SHORT_NAME" => 8,
+    "LF_FACESIZE" => 32,
+    "LF_FULLFACESIZE" => 64,
+    "MAXIMUM_SUPPORTED_EXTENSION" => 512,
+    "MAX_PATH" => 260,
+    "MAX_PROFILE_LEN" => 80, 
+    "OFS_MAXPATHNAME" => 128,
+    "SIZE_OF_80387_REGISTERS" => 80,
+);
+
+my %kludge_reported = ("FILETIME" => 1, "LARGE_INTEGER" => 1);
+my %parse_reported;
+
+sub find_size {
+    my $type_name = shift;
+
+    local $_ = $type_name;
+
+    my $count;
+    my $bits;
+    if (s/^(.*?)\s*(?:\[\s*(.*?)\s*\]|:(\d+))?$/$1/) {
+	$count = $2;
+	$bits = $3;
+    }
+
+    my $size;
+    if (0) {
+	# Nothing
+    } elsif (/\*+$/) {
+	$size = 4;
+    } elsif(/^(?:(?:signed\s+|unsigned\s+)?char)$/) {
+	$size = 1;
+    } elsif (/^(?:(?:signed\s+|unsigned\s+)?short)$/) {
+	$size = 2;
+    } elsif (/^(?:wchar_t)$/) {
+	$size = 2;
+    } elsif
(/^(?:(?:signed\s+|unsigned\s+)?(?:__int32|int|long(?:\s+int)?)|unsigned|sig
ned)$/) {
+	$size = 4;
+    } elsif (/^(?:float)$/) {
+	$size = 4;
+    } elsif (/^(?:signed\s+|unsigned\s+)?__int64$/) {
+	$size = 8;
+    } elsif (/^(?:double)$/) {
+	$size = 8;
+    } elsif (/^(?:long\s+double)$/) {
+	$size = 10; # ???
+    } elsif (/^H(?:DC|BITMAP|BRUSH|ICON|INSTANCE|MENU|METAFILE|WND)$/) {
+	$size = 4;
+    } elsif (/^LP(?:CSTR|CWSTR|DWORD|STR|VOID|THREAD_START_ROUTINE|WSTR)$/)
{
+	$size = 4;
+    } elsif (/^(?:(?:MSGBOX)CALLBACK[AW]?|(?:FAR|WND)PROC[AW]?)$/) {
+	$size = 4;
+    } elsif (/^(?:FILETIME|LARGE_INTEGER|LONGLONG)$/) {
+	$size = 8;
+    } elsif (/^(?:CRITICAL_SECTION)$/) {
+	$size = 24;
+    } elsif (/^(?:struct|union)$/) {
+	if (!$parse_reported{$_}) {
+	    $output->write("$type_name: can't parse type\n");
+	    $parse_reported{$_} = 1;
+	}
+	$size = undef;
+    } else {
+	$size = undef;
+    }
+
+    my $size2;
+    if (defined(my $type = $type_name2type{$_})) {
+	$size2 = $type->size;
+    }
+
+    if (!defined($size)) {
+	$size = $size2;
+    } elsif (defined($size2) && !$kludge_reported{$_}) {
+	$kludge_reported{$_} = 1;
+	$output->write("$type_name: type needn't be kludged\n");
+    }
+
+    if (!defined($size)) {
+	# $output->write("$type_name: can't find type\n");
+    } elsif (defined($count)) {
+	if ($count =~ /^\d+$/) {
+	    $size *= int($count);
+	} elsif (defined($count = $defines{$count})) {
+	    $size *= int($count);
+	} else {
+	    $output->write("$type_name: can't parse type\n");
+	    $size = undef;
+	}
+    } elsif (defined($bits)) {
+	$size = -$bits;
+    }
+
+    return $size;
+}
+
 foreach my $file (@files) {
     $progress_current++;
 
@@ -136,13 +256,32 @@
     my $found_type = sub {
 	$type = shift;
 
-	my $pack = $packs[$#packs];
-	$type->pack($pack);
+	&$update_output();
+
+	if (!defined($type->pack)) {
+	    my $pack = $packs[$#packs];
+	    $type->pack($pack);
+	}
 
 	my $name = $type->name;
 	$file2types{$file}{$name} = $type;
 
-	&$update_output();
+	my $size = $type->size(\&find_size);
+	if (defined($size)) {
+	    foreach my $field ($type->fields(\&find_size)) {
+		my $field_type_name = $field->type_name;
+		my $field_name = $field->name;
+		my $field_size = $field->size;
+		my $field_offset = $field->offset;
+
+		# $output->write("$name: $field_type_name: $field_name:
$field_offset: $field_size\n");
+	    }
+	    # $output->write("$name: $size\n");
+
+	    $type_name2type{$name} = $type;
+	} else {
+	    # $output->write("$name: can't find size\n");
+	}
 
 	return 1;
     };
@@ -212,67 +351,6 @@
 }
 
 ########################################################################
-# output_field_size
-
-my %type_name2size;
-
-sub field_size {
-    my $name = shift;
-    my $field_type = shift;
-    my $field_name = shift;
-
-    local $_ = $field_type;
-
-    my $count;
-    my $bits;
-    if (s/^(.*?)\s*(?:\[\s*(.*?)\s*\]|:(\d+))?$/$1/) {
-	$count = $2;
-	$bits = $3;
-    }
-
-    my $size;
-    if (defined($size = $type_name2size{$field_type})) {
-	# Nothing
-    } elsif(/^(?:(?:signed\s+|unsigned\s+)?char|CHAR|BYTE|UCHAR)$/) {
-	$size = 1;
-    } elsif (/^(?:(?:signed\s+|unsigned\s+)?short|ATOM|UWORD|WCHAR|WORD)$/)
{
-	$size = 2;
-    } elsif (/^(?:FILETIME|LARGE_INTEGER|LONGLONG|ULONGLONG)$/) {
-	$size = 8;
-    } elsif (/^(?:EMR|POINTL?|SIZEL)$/) {
-	$size = 8;
-    } elsif (/^(?:RECTL?|SYSTEMTIME)$/) {
-	$size = 16;
-    } elsif (/^(?:CRITICAL_SECTION|XFORM)$/) {
-	$size = 24;
-    } elsif (/^(?:DCB)$/) {
-	$size = 28;
-    } elsif (/^(?:EXCEPTION_RECORD)$/) {
-	$size = 80;
-    } elsif (/^(?:struct|union)$/) {
-	$output->write("$name:$field_name: can't parse type
'$field_type'\n");
-	$size = 4;
-    } else {
-	$size = 4;
-    }
-
-    if (defined($count)) {
-	if ($count =~ /^\d+$/) {
-	    return $size * int($count);
-	} elsif ($count =~ /^ANYSIZE_ARRAY$/) {
-	    return $size;
-	} else {
-	    $output->write("$name:$field_name: can't parse type
'$field_type'\n");
-	    return $size; # Not correct.
-	}
-    } elsif (defined($bits)) {
-	return -$bits;
-    } else {
-	return $size;
-    }
-}
-
-########################################################################
 # output_test_pack
 
 sub output_test_pack {
@@ -290,57 +368,54 @@
 	$type_name_not_used{$type_name} = 1;
     }
 
-    # FIXME: Topological sort of @type_names
-
     foreach my $include (@includes) {
 	my $types = $file2types{"include/$include"};
 	
-	foreach my $type_name (@type_names) {	    
+	foreach my $type_name (@type_names) {
 	    my $type = $$types{$type_name};
 	    if (!defined($type)) {
 		next;
 	    }
 	    $type_name_not_used{$type_name} = 0;
-
+	    
 	    my $pack = $type->pack;
 
-	    my $offset = 0;
-	    my $offset_bits = 0;
-	    
 	    print OUT "    /* $type_name */\n";
-	    foreach my $field ($type->fields) {
-		(my $field_type, my $field_name) = @$field;
-		
-		my $field_size = field_size($type_name, $field_type,
$field_name);
-		if ($field_size >= 0) {
-		    if ($offset_bits) {
-			$offset += $pack * int(($offset_bits + 8 * $pack - 1
) / (8 * $pack));
-			$offset_bits = 0;
-		    }
-		    
-		    my $field_offset = $offset;
-		    if ($field_name ne "") {
-			print OUT "    ok(FIELD_OFFSET($type_name,
$field_name) == $field_offset,\n";
-			print OUT "       \"FIELD_OFFSET($type_name,
$field_name) == %ld (expected $field_offset)\",\n";
-			print OUT "       FIELD_OFFSET($type_name,
$field_name)); /* $field_type */\n";
+
+	    foreach my $field ($type->fields(\&find_size)) {
+		my $field_type_name = $field->type_name;
+		my $field_name = $field->name;
+		my $field_size = $field->size;
+		my $field_offset = $field->offset;
+		my $field_align = $field->align;
+
+		next if $field_name eq "" || (defined($field_size) &&
$field_size < 0);
+
+		if (defined($field_size) && defined($field_offset)) {
+		    print OUT "    ok(FIELD_OFFSET($type_name, $field_name)
== $field_offset,\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";
 		    }
-		    
-		    $offset += $field_size;
 		} else {
-		    $offset_bits += -$field_size;
+		    $output->write("$type_name: $field_type_name:
$field_name: test not generated (offset not defined)\n");
 		}
 	    }
-	    
-	    my $type_size = $offset;
-	    if ($type_size % $pack != 0) {
-		$type_size = (int($type_size / $pack) + 1) * $pack;
-	    }
-	    $type_name2size{$type_name} = $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";
+	    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");
+	    }
 	}
     }
 



More information about the wine-patches mailing list