diff --git a/tools/winapi/c_parser.pm b/tools/winapi/c_parser.pm index 1e736ab0f09..24c2aaee78d 100644 --- a/tools/winapi/c_parser.pm +++ b/tools/winapi/c_parser.pm @@ -1186,8 +1186,8 @@ sub parse_c_function { my $match; while($self->_parse_c('(?:const|inline|extern(?:\s+\"C\")?|EXTERN_C|static|volatile|' . - '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)|' . + 'signed(?=\s+__int(?:8|16|32|64)\b|\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b)|' . + 'unsigned(?=\s+__int(?:8|16|32|64)\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)) { @@ -1933,6 +1933,7 @@ sub parse_c_variable { my $begin_column = $column + 1; my $linkage = ""; + my $sign = ""; my $type = ""; my $name = ""; @@ -1940,14 +1941,22 @@ sub parse_c_variable { my $match; while($self->_parse_c('(?:const|inline|extern(?:\s+\"C\")?|EXTERN_C|static|volatile|' . - '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)|' . + 'signed(?=\s+__int(?:8|16|32|64)\b|\s+char\b|\s+int\b|\s+long(?:\s+long)?\b|\s+short\b)|' . + 'unsigned(?=\s+__int(?:8|16|32|64)\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)) { - if($match =~ /^extern|static$/) { - if(!$linkage) { + if ($match =~ /^extern|static$/) { + if (!$linkage) { $linkage = $match; + } else { + $self->_parse_c_warning($_, $line, $column, "repeated linkage (ignored): $match"); + } + } elsif ($match =~ /^signed|unsigned$/) { + if (!$sign) { + $sign = "$match "; + } else { + $self->_parse_c_warning($_, $line, $column, "repeated sign (ignored): $match"); } } } @@ -1970,8 +1979,8 @@ sub parse_c_variable { } $finished = 1; - } elsif(s/^((?:enum\s+|struct\s+|union\s+)?\w+(?:\s*\*)*)\s*(\w+)\s*(\[.*?\]$|:\s*(\d+)$|\{)?//s) { - $type = $1; + } elsif(s/^((?:enum\s+|struct\s+|union\s+)?\w+\b(?:\s*\*)*)\s*(\w+)\s*(\[.*?\]$|:\s*(\d+)$|\{)?//s) { + $type = "$sign$1"; $name = $2; if (defined($3)) { @@ -1989,13 +1998,8 @@ sub parse_c_variable { $type = $self->_format_c_type($type); $finished = 1; - } elsif(s/^((?:enum\s+|struct\s+|union\s+)?\w+(?:\s*\*)*\s*\(\s*(?:\*\s*)*)(\w+)\s*(\)\(.*?\))$//s) { - $type = $self->_format_c_type("$1$3"); - $name = $2; - - $finished = 1; - - $type = $self->_format_c_type("$1$3"); + } elsif(s/^((?:enum\s+|struct\s+|union\s+)?\w+\b(?:\s*\*)*\s*\((?:\s*CALLBACK|\s*NTAPI|\s*WINAPI)?(?:\s*\*)*)\s*(\w+)\s*(\)\s*\(.*?\))$//s) { + $type = $self->_format_c_type("$sign$1$3"); $name = $2; $finished = 1; diff --git a/tools/winapi/c_type.pm b/tools/winapi/c_type.pm index ec49819e0de..ec789637e32 100644 --- a/tools/winapi/c_type.pm +++ b/tools/winapi/c_type.pm @@ -42,6 +42,17 @@ sub set_find_align_callback { $$find_align = shift; } +######################################################################## +# set_find_kind_callback +# +sub set_find_kind_callback { + my $self = shift; + + my $find_kind = \${$self->{FIND_KIND}}; + + $$find_kind = shift; +} + ######################################################################## # set_find_size_callback # @@ -62,6 +73,10 @@ sub kind { if(defined($_)) { $$kind = $_; $$dirty = 1; } + if (!defined($$kind)) { + $self->_refresh(); + } + return $$kind; } @@ -219,6 +234,7 @@ sub _refresh { return if !$$dirty; my $find_align = \${$self->{FIND_ALIGN}}; + my $find_kind = \${$self->{FIND_KIND}}; my $find_size = \${$self->{FIND_SIZE}}; my $align = \${$self->{ALIGN}}; @@ -230,6 +246,7 @@ sub _refresh { my $field_sizes = \${$self->{FIELD_SIZES}}; my $pack = $self->pack; + $pack = 4 if !defined($pack); my $max_field_align = 0; @@ -258,6 +275,10 @@ sub _refresh { } } + if ($$kind !~ /^(?:struct|union)$/) { + $$kind = &$$find_kind($type_name) || ""; + } + if (!defined($size)) { $$align = undef; $$size = undef; diff --git a/tools/winapi/tests.dat b/tools/winapi/tests.dat index cd43541d473..4d5484c1acb 100644 --- a/tools/winapi/tests.dat +++ b/tools/winapi/tests.dat @@ -17,10 +17,11 @@ wingdi.h windows.h -%struct +%type -ABC +ABC ABCFLOAT +ABORTPROC BITMAP BITMAPCOREHEADER BITMAPCOREINFO @@ -33,9 +34,10 @@ BLENDFUNCTION CHARSETINFO CIEXYZ CIEXYZTRIPLE +COLOR16 COLORADJUSTMENT -# DEVMODEA -# DEVMODEW +!DEVMODEA +!DEVMODEW DIBSECTION DISPLAY_DEVICEA: !DeviceID !DeviceKey DISPLAY_DEVICEW: !DeviceID !DeviceKey @@ -47,11 +49,11 @@ EMRANGLEARC EMRARC EMRBITBLT EMRCREATEBRUSHINDIRECT -# EMRCREATECOLORSPACE -# EMRCREATECOLORSPACEW +!EMRCREATECOLORSPACE +!EMRCREATECOLORSPACEW EMRCREATEDIBPATTERNBRUSHPT EMRCREATEMONOBRUSH -# EMRCREATEPALETTE +!EMRCREATEPALETTE EMRCREATEPEN EMRDELETECOLORSPACE EMRDELETEOBJECT @@ -94,9 +96,9 @@ EMRSETCOLORADJUSTMENT EMRSETDIBITSTODEVICE EMRSETMAPPERFLAGS EMRSETMITERLIMIT -# EMRSETPALETTEENTRIES +!EMRSETPALETTEENTRIES EMRSETPIXELV -# EMRSETTEXTJUSTIFICATION +!EMRSETTEXTJUSTIFICATION EMRSETVIEWPORTEXTEX EMRSETWORLDTRANSFORM EMRSTRETCHBLT @@ -104,6 +106,7 @@ EMRSTRETCHDIBITS EMRTEXT ENHMETAHEADER: !szlMicrometers ENHMETARECORD +ENHMFENUMPROC ENUMLOGFONTA ENUMLOGFONTEXA ENUMLOGFONTEXW @@ -112,39 +115,275 @@ EXTLOGFONTA EXTLOGFONTW EXTLOGPEN FIXED +FONTENUMPROCA +FONTENUMPROCEXA +FONTENUMPROCEXW +FONTENUMPROCW FONTSIGNATURE +FXPT16DOT16 +FXPT2DOT30 GCP_RESULTSA GCP_RESULTSW GLYPHMETRICS +GOBJENUMPROC GRADIENT_RECT GRADIENT_TRIANGLE HANDLETABLE KERNINGPAIR +LCSCSTYPE +LCSGAMUTMATCH +LINEDDAPROC LOCALESIGNATURE LOGBRUSH LOGCOLORSPACEA LOGCOLORSPACEW LOGFONTA LOGFONTW -# LOGPALETTE +!LOGPALETTE LOGPEN +LPABC +LPABCFLOAT +LPBITMAP +LPBITMAPCOREHEADER +LPBITMAPCOREINFO +LPBITMAPFILEHEADER +LPBITMAPINFO +LPBITMAPINFOHEADER +LPBITMAPV5HEADER +LPCHARSETINFO +LPCIEXYZ +LPCIEXYZTRIPLE +LPCOLORADJUSTMENT +LPDEVMODEA +LPDEVMODEW +LPDIBSECTION +LPDISPLAY_DEVICEA +LPDISPLAY_DEVICEW +LPDOCINFOA +LPDOCINFOW +LPENHMETAHEADER +LPENHMETARECORD +LPENUMLOGFONTA +LPENUMLOGFONTEXA +LPENUMLOGFONTEXW +LPENUMLOGFONTW +LPEXTLOGFONTA +LPEXTLOGFONTW +LPEXTLOGPEN +LPFONTSIGNATURE +LPGCP_RESULTSA +LPGCP_RESULTSW +LPGLYPHMETRICS +LPGRADIENT_RECT +LPGRADIENT_TRIANGLE +LPHANDLETABLE +LPKERNINGPAIR +LPLOCALESIGNATUREE +LPLOGBRUSH +LPLOGCOLORSPACEA +LPLOGCOLORSPACEW +LPLOGFONTA +LPLOGFONTW +!LPLOGPALETTE +LPLOGPEN +LPMAT2 +LPMETAFILEPICT +LPMETAHEADER +LPMETARECORD +LPNEWTEXTMETRICA +LPNEWTEXTMETRICEXA +LPNEWTEXTMETRICEXW +LPNEWTEXTMETRICW +LPOUTLINETEXTMETRICA +LPOUTLINETEXTMETRICW +!LPPALETTEENTRY +LPPANOSE +LPPELARRAY +LPPIXELFORMATDESCRIPTOR +LPPOINTFX +LPPOLYTEXTA +LPPOLYTEXTW +LPRASTERIZER_STATUS +LPRGBQUAD +LPRGNDATA +LPTEXTMETRICA +LPTEXTMETRICW +LPTRIVERTEX +LPTTPOLYCURVE +LPTTPOLYGONHEADER +LPXFORM MAT2 METAFILEPICT METAHEADER METARECORD +MFENUMPROC NEWTEXTMETRICA NEWTEXTMETRICEXA NEWTEXTMETRICEXW NEWTEXTMETRICW +NPEXTLOGPEN +!NPLOGPALETTE +OLDFONTENUMPROCA +OLDFONTENUMPROCW OUTLINETEXTMETRICA OUTLINETEXTMETRICW -# PALETTEENTRY +PABC +PABCFLOAT +!PALETTEENTRY PANOSE +PATTERN +PBITMAP +PBITMAPCOREHEADER +PBITMAPCOREINFO +PBITMAPFILEHEADER +PBITMAPINFO +PBITMAPINFOHEADER +PBITMAPV4HEADER +PBITMAPV5HEADER +PBLENDFUNCTION +PCHARSETINFO +PCOLORADJUSTMENT +PDEVMODEA +PDEVMODEW +PDIBSECTION +PDISPLAY_DEVICEA +PDISPLAY_DEVICEW PELARRAY +PEMR +PEMRABORTPATH +PEMRANGLEARC +PEMRARC +PEMRARCTO +PEMRBEGINPATH +PEMRBITBLT +PEMRCHORD +PEMRCLOSEFIGURE +PEMRCREATEBRUSHINDIRECT +!PEMRCREATECOLORSPACE +!PEMRCREATECOLORSPACEW +PEMRCREATEDIBPATTERNBRUSHPT +PEMRCREATEMONOBRUSH +PEMRCREATEPALETTE +PEMRCREATEPEN +PEMRDELETECOLORSPACE +PEMRDELETEOBJECT +PEMRELLIPSE +PEMRENDPATH +PEMREOF +PEMREXCLUDECLIPRECT +PEMREXTCREATEFONTINDIRECTW +PEMREXTCREATEPEN +PEMREXTFLOODFILL +PEMREXTSELECTCLIPRGN +PEMREXTTEXTOUTA +PEMREXTTEXTOUTW +PEMRFILLPATH +PEMRFILLRGN +PEMRFLATTENPATH +PEMRFORMAT +PEMRFRAMERGN +PEMRGDICOMMENT +PEMRGLSBOUNDEDRECORD +PEMRGLSRECORD +PEMRINTERSECTCLIPRECT +PEMRINVERTRGN +PEMRLINETO +PEMRMASKBLT +PEMRMODIFYWORLDTRANSFORM +PEMRMOVETOEX +PEMROFFSETCLIPRGN +PEMRPAINTRGN +PEMRPIE +PEMRPIXELFORMAT +PEMRPLGBLT +PEMRPOLYBEZIER +PEMRPOLYBEZIERTO +PEMRPOLYDRAW +PEMRPOLYGON +PEMRPOLYLINE +PEMRPOLYLINETO +PEMRPOLYPOLYGON +PEMRPOLYPOLYLINE +PEMRPOLYTEXTOUTA +PEMRPOLYTEXTOUTW +PEMRREALIZEPALETTE +PEMRRECTANGLE +PEMRRESIZEPALETTE +PEMRRESTOREDC +PEMRROUNDRECT +PEMRSAVEDC +PEMRSCALEVIEWPORTEXTEX +PEMRSCALEWINDOWEXTEX +PEMRSELECTCLIPPATH +PEMRSELECTCOLORSPACE +PEMRSELECTOBJECT +PEMRSELECTPALETTE +PEMRSETARCDIRECTION +PEMRSETBKCOLOR +PEMRSETBKMODE +PEMRSETBRUSHORGEX +PEMRSETCOLORADJUSTMENT +!PEMRSETCOLORSPACE +PEMRSETDIBITSTODEVICE +!PEMRSETLAYOUT +PEMRSETMAPMODE +PEMRSETMAPPERFLAGS +PEMRSETMETARGN +PEMRSETMITERLIMIT +PEMRSETPALETTEENTRIES +PEMRSETPIXELV +PEMRSETPOLYFILLMODE +PEMRSETROP2 +PEMRSETSTRETCHBLTMODE +PEMRSETTEXTALIGN +PEMRSETTEXTCOLOR +!PEMRSETTEXTJUSTIFICATION # Can't find in any SDK. However #define EMR_SETTEXTJUSTIFICATION exixts +PEMRSETVIEWPORTEXTEX +PEMRSETVIEWPORTORGEX +PEMRSETWINDOWEXTEX +PEMRSETWINDOWORGEX +PEMRSETWORLDTRANSFORM +PEMRSTRETCHBLT +PEMRSTRETCHDIBITS +PEMRSTROKEANDFILLPATH +PEMRSTROKEPATH +PEMRTEXT +PEMRWIDENPATH +PENHMETAHEADER +PERMSETICMMODE +PEXTLOGFONTA +PEXTLOGFONTW +PEXTLOGPEN +PFONTSIGNATURE +PGRADIENT_RECT +PGRADIENT_TRIANGLE +PHANDLETABLE PIXELFORMATDESCRIPTOR +PLOCALESIGNATUR +PLOGBRUSH +PLOGFONTA +PLOGFONTW +!PLOGPALETTE +PMETAHEADER +PMETARECORD +PNEWTEXTMETRICA +PNEWTEXTMETRICW POINTFX POLYTEXTA POLYTEXTW +POUTLINETEXTMETRICA +POUTLINETEXTMETRICW +!PPALETTEENTRY +PPELARRAY +PPIXELFORMATDESCRIPTOR +PPOLYTEXTA +PPOLYTEXTW +PRGNDATA +PRGNDATAHEADER +PTEXTMETRICA +PTEXTMETRICW +PTRIVERTEX +PXFORM RASTERIZER_STATUS RGBQUAD RGBTRIPLE @@ -176,7 +415,7 @@ winbase.h windows.h -%struct +%type BY_HANDLE_FILE_INFORMATION COMMCONFIG @@ -185,15 +424,63 @@ COMMTIMEOUTS COMSTAT CREATE_PROCESS_DEBUG_INFO CREATE_THREAD_DEBUG_INFO +CRITICAL_SECTION +CRITICAL_SECTION_DEBUG DCB DEBUG_EVENT +ENUMRESLANGPROCA +ENUMRESLANGPROCW +ENUMRESNAMEPROCA +ENUMRESNAMEPROCW +ENUMRESTYPEPROCA +ENUMRESTYPEPROCW EXCEPTION_DEBUG_INFO EXIT_PROCESS_DEBUG_INFO EXIT_THREAD_DEBUG_INFO -# FILETIME +!FILETIME HW_PROFILE_INFOA LDT_ENTRY LOAD_DLL_DEBUG_INFO +LPBY_HANDLE_FILE_INFORMATION +LPCOMMCONFIG +LPCOMMPROP +LPCOMMTIMEOUTS +LPCOMSTAT +LPCONTEXT +LPCRITICAL_SECTION +LPCRITICAL_SECTION_DEBUG +LPDCB +LPDEBUG_EVENT +LPEXCEPTION_POINTERS +LPEXCEPTION_RECORD +LPFIBER_START_ROUTINE +!LPFILETIME +LPHW_PROFILE_INFOA +LPHW_PROFILE_INFOW +LPLDT_ENTRY +LPMEMORYSTATUS +LPOFSTRUCT +LPOSVERSIONINFOA +LPOSVERSIONINFOEXA +LPOSVERSIONINFOEXW +LPOSVERSIONINFOW +LPOVERLAPPED +LPOVERLAPPED_COMPLETION_ROUTINE +LPPROCESS_HEAP_ENTRY +LPPROCESS_INFORMATION +LPPROGRESS_ROUTINE +LPSECURITY_ATTRIBUTES +LPSTARTUPINFOA +LPSTARTUPINFOW +LPSYSTEMTIME +LPSYSTEM_INFO +LPSYSTEM_POWER_STATUS +LPTHREAD_START_ROUTINE +LPTIME_ZONE_INFORMATION +LPWIN32_FILE_ATTRIBUTE_DATA +LPWIN32_FIND_DATAA +LPWIN32_FIND_DATAW +LPWIN32_STREAM_ID MEMORYSTATUS OFSTRUCT OSVERSIONINFOA @@ -202,22 +489,42 @@ OSVERSIONINFOEXW: !wSuiteMask !wProductType !wReserved OSVERSIONINFOW OUTPUT_DEBUG_STRING_INFO OVERLAPPED +PAPCFUNC +PBY_HANDLE_FILE_INFORMATION +PCRITICAL_SECTION +PCRITICAL_SECTION_DEBUG +PFIBER_START_ROUTINE +!PFILETIME +POFSTRUCT +POSVERSIONINFOA +POSVERSIONINFOEXA +POSVERSIONINFOEXW +POSVERSIONINFOW +PPROCESS_HEAP_ENTRY +PPROCESS_INFORMATION PROCESS_HEAP_ENTRY PROCESS_INFORMATION +PSECURITY_ATTRIBUTES +PSYSTEMTIME +PTIMERAPCROUTINE +PTIME_ZONE_INFORMATION +PWIN32_FIND_DATAA +PWIN32_FIND_DATAW RIP_INFO SECURITY_ATTRIBUTES STARTUPINFOA STARTUPINFOW -# SYSLEVEL +!SYSLEVEL SYSTEMTIME -# SYSTEM_INFO +!SYSTEM_INFO SYSTEM_POWER_STATUS TIME_ZONE_INFORMATION UNLOAD_DLL_DEBUG_INFO +WAITORTIMERCALLBACK WIN32_FILE_ATTRIBUTE_DATA WIN32_FIND_DATAA WIN32_FIND_DATAW -WIN32_STREAM_ID +!WIN32_STREAM_ID %%%dlls/ntdll/tests @@ -237,18 +544,46 @@ windef.h windows.h -%struct +%type ACCESS_ALLOWED_ACE ACCESS_DENIED_ACE +ACCESS_MASK ACE_HEADER ACL -# EXCEPTION_FRAME +ATOM +BOOL +BOOLEAN +BYTE +!CATCHBUF +CCHAR +CHAR +COLORREF +!CONTEXT +!DATE +!DOUBLE +DWORD +!DWORD64 +!DWORDLONG +DWORD_PTR +!EXCEPTION_FRAME EXCEPTION_POINTERS EXCEPTION_RECORD +EXECUTION_STATE +FARPROC +FLOAT FLOATING_SAVE_AREA FPO_DATA GENERIC_MAPPING +GLOBALHANDLE +HANDLE +HCURSOR +HFILE +HGDIOBJ +HGLOBAL +HLOCAL +HMODULE +HRESULT IMAGE_ARCHIVE_MEMBER_HEADER IMAGE_AUX_SYMBOL IMAGE_BASE_RELOCATION @@ -263,54 +598,193 @@ IMAGE_EXPORT_DIRECTORY IMAGE_FILE_HEADER IMAGE_FUNCTION_ENTRY IMAGE_IMPORT_BY_NAME -# IMAGE_IMPORT_DESCRIPTOR -# IMAGE_LINENUMBER +!IMAGE_IMPORT_DESCRIPTOR +!IMAGE_LINENUMBER IMAGE_LOAD_CONFIG_DIRECTORY IMAGE_NT_HEADERS IMAGE_OPTIONAL_HEADER IMAGE_OS2_HEADER -# IMAGE_RELOCATION +!IMAGE_RELOCATION IMAGE_RESOURCE_DATA_ENTRY: !ResourceHandle IMAGE_RESOURCE_DIRECTORY IMAGE_RESOURCE_DIRECTORY_ENTRY IMAGE_RESOURCE_DIRECTORY_STRING IMAGE_RESOURCE_DIR_STRING_U -# IMAGE_SECTION_HEADER +!IMAGE_SECTION_HEADER IMAGE_SEPARATE_DEBUG_HEADER -# IMAGE_SYMBOL +!IMAGE_SYMBOL IMAGE_THUNK_DATA IMAGE_TLS_DIRECTORY IMAGE_VXD_HEADER -# LARGE_INTEGER +INT +!INT64 +INT_PTR +LANGID +!LARGE_INTEGER +LCID LIST_ENTRY +LOCALHANDLE +LONG +!LONG64 +!LONGLONG +LONG_PTR +LPARAM +!LPCATCHBUF +LPCRECT +LPCRECTL +LPCVOID +LPLARGE_INTEGER +LPMEMORY_BASIC_INFORMATION +LPPOINT +LPPOINTS +LPRECT +LPRECTL +LPSID_IDENTIFIER_AUTHORITY +LPSIZE +LPTOP_LEVEL_EXCEPTION_FILTER +LPULARGE_INTEGER +LRESULT LUID LUID_AND_ATTRIBUTES MEMORY_BASIC_INFORMATION MESSAGE_RESOURCE_BLOCK MESSAGE_RESOURCE_DATA MESSAGE_RESOURCE_ENTRY -# NT_TIB +!NT_TIB +PACCESS_ALLOWED_ACE +PACCESS_DENIED_ACE +PACCESS_TOKEN +PACE_HEADER +PACL +PCCH +PCH +!PCONTEXT +PCSTR +!PCTSTR +PCWCH +PCWSTR +!PEXCEPTION_FRAME +PEXCEPTION_HANDLER +PEXCEPTION_POINTERS +PEXCEPTION_RECORD +PFLOATING_SAVE_AREA +PFPO_DATA +PGENERIC_MAPPING +PHANDLE +PIMAGE_ARCHIVE_MEMBER_HEADER +PIMAGE_AUX_SYMBOL +PIMAGE_BASE_RELOCATION +PIMAGE_BOUND_FORWARDER_REF +PIMAGE_BOUND_IMPORT_DESCRIPTOR +PIMAGE_COFF_SYMBOLS_HEADER +PIMAGE_DATA_DIRECTORY +PIMAGE_DEBUG_DIRECTORY +PIMAGE_DEBUG_MISC +PIMAGE_DOS_HEADER +PIMAGE_EXPORT_DIRECTORY +PIMAGE_FILE_HEADER +PIMAGE_FUNCTION_ENTRY +PIMAGE_IMPORT_BY_NAME +PIMAGE_IMPORT_DESCRIPTOR +PIMAGE_LINENUMBER +PIMAGE_LOAD_CONFIG_DIRECTORY +PIMAGE_NT_HEADERS +PIMAGE_OPTIONAL_HEADER +PIMAGE_OS2_HEADER +PIMAGE_RELOCATION +PIMAGE_RESOURCE_DATA_ENTRY +PIMAGE_RESOURCE_DIRECTORY +PIMAGE_RESOURCE_DIRECTORY_ENTRY +PIMAGE_RESOURCE_DIRECTORY_STRING +PIMAGE_RESOURCE_DIR_STRING_U +PIMAGE_SECTION_HEADER +PIMAGE_SEPARATE_DEBUG_HEADER +PIMAGE_SYMBOL +PIMAGE_THUNK_DATA +PIMAGE_TLS_CALLBACK +PIMAGE_TLS_DIRECTORY +PIMAGE_VXD_HEADER +PISECURITY_DESCRIPTOR_RELATIVE +PLARGE_INTEGER +PLIST_ENTRY +PLUID +PMEMORY_BASIC_INFORMATION +PMESSAGE_RESOURCE_BLOCK +PMESSAGE_RESOURCE_DATA +PMESSAGE_RESOURCE_ENTRY +PNT_TIB +PPOINT +PPOINTS +PPRIVILEGE_SET +PRECT +PRECTL PRIVILEGE_SET +PRLIST_ENTRY +PROC +PRTL_CRITICAL_SECTION +PRTL_CRITICAL_SECTION_DEBUG +PRTL_RESOURCE_DEBUG +!PSECURITY_DESCRIPTOR: void +PSECURITY_QUALITY_OF_SERVICE +!PSID: void +PSID_IDENTIFIER_AUTHORITY +PSINGLE_LIST_ENTRY +PSIZE +!PSTACK_FRAME_HEADER +PSTR +PSYSTEM_ALARM_ACE +PSYSTEM_AUDIT_ACE +PTOKEN_PRIVILEGES +PTOP_LEVEL_EXCEPTION_FILTER +PTSTR +PULARGE_INTEGER +PVOID +PWCH +PWSTR RTL_CRITICAL_SECTION RTL_CRITICAL_SECTION_DEBUG +SECURITY_CONTEXT_TRACKING_MODE SECURITY_DESCRIPTOR +SECURITY_DESCRIPTOR_CONTROL SECURITY_DESCRIPTOR_RELATIVE -# SECURITY_QUALITY_OF_SERVICE +SECURITY_INFORMATION +!SECURITY_QUALITY_OF_SERVICE +SHORT SID SID_AND_ATTRIBUTES SID_IDENTIFIER_AUTHORITY SINGLE_LIST_ENTRY +SIZEL +SIZE_T +SSIZE_T SYSTEM_ALARM_ACE SYSTEM_AUDIT_ACE +TCHAR TOKEN_DEFAULT_DACL TOKEN_GROUPS TOKEN_OWNER TOKEN_PRIMARY_GROUP TOKEN_PRIVILEGES TOKEN_SOURCE -# TOKEN_STATISTICS +!TOKEN_STATISTICS TOKEN_USER -# ULARGE_INTEGER +UCHAR +UINT +!UINT64 +UINT_PTR +!ULARGE_INTEGER +ULONG +!ULONG64 +!ULONGLONG +ULONG_PTR +USHORT +WAITORTIMERCALLBACKFUNC +WCHAR +WORD +WPARAM +__int16 +__int32 +__int8 %%%dlls/user/tests @@ -333,9 +807,9 @@ winuser.h windows.h -%struct +%type -ACCEL +ACCEL ACCESSTIMEOUT ANIMATIONINFO CBTACTIVATESTRUCT @@ -351,25 +825,128 @@ CWPRETSTRUCT CWPSTRUCT DEBUGHOOKINFO DELETEITEMSTRUCT +DESKTOPENUMPROCA +DESKTOPENUMPROCW DLGITEMTEMPLATE +DLGPROC +DLGPROC DLGTEMPLATE -# DRAWITEMSTRUCT +!DRAWITEMSTRUCT +DRAWSTATEPROC +DRAWSTATEPROC DRAWTEXTPARAMS +EDITWORDBREAKPROCA +EDITWORDBREAKPROCA +EDITWORDBREAKPROCW +EDITWORDBREAKPROCW EVENTMSG FILTERKEYS +GRAYSTRINGPROC +GRAYSTRINGPROC HARDWAREHOOKSTRUCT HARDWAREINPUT +HDEVNOTIFY +HDWP HELPINFO HELPWININFOA HELPWININFOW HIGHCONTRASTA HIGHCONTRASTW +HOOKPROC +HOOKPROC ICONINFO ICONMETRICSA ICONMETRICSW INPUT KBDLLHOOKSTRUCT KEYBDINPUT +LPACCEL +LPACCESSTIMEOUT +LPANIMATIONINFO +LPCBTACTIVATESTRUCT +LPCBT_CREATEWNDA +LPCBT_CREATEWNDW +LPCDLGTEMPLATEA +LPCDLGTEMPLATEW +LPCLIENTCREATESTRUCT +LPCMENUINFO +LPCMENUITEMINFOA +LPCMENUITEMINFOW +LPCOMBOBOXINFO +LPCOMPAREITEMSTRUCT +LPCREATESTRUCTA +LPCREATESTRUCTW +LPCSCROLLINFO +LPCURSORINFO +LPCWPRETSTRUCT +LPCWPSTRUCT +LPDEBUGHOOKINFO +LPDELETEITEMSTRUCT +LPDLGITEMTEMPLATEA +LPDLGITEMTEMPLATEW +LPDLGTEMPLATEA +LPDLGTEMPLATEW +LPDRAWITEMSTRUCT +LPDRAWTEXTPARAMS +LPEVENTMSG +LPFILTERKEYS +!LPGUITHREADINFO +LPHARDWAREHOOKSTRUCT +LPHARDWAREINPUT +LPHELPINFO +LPHELPWININFOA +LPHELPWININFOW +LPHIGHCONTRASTA +LPHIGHCONTRASTW +LPICONMETRICSA +LPICONMETRICSW +LPINPUT +LPKBDLLHOOKSTRUCT +LPKEYBDINPUT +LPMDICREATESTRUCTA +LPMDICREATESTRUCTW +LPMDINEXTMENU +LPMEASUREITEMSTRUCT +LPMENUINFO +LPMENUITEMINFOA +LPMENUITEMINFOW +LPMENUTEMPLATE +LPMINIMIZEDMETRICS +LPMINMAXINFO +LPMONITORINFO +LPMONITORINFOEXA +LPMONITORINFOEXW +LPMOUSEHOOKSTRUCT +LPMOUSEINPUT +LPMOUSEKEYS +LPMSG +LPMSGBOXPARAMSA +LPMSGBOXPARAMSW +LPMSLLHOOKSTRUCT +LPMULTIKEYHELPA +LPMULTIKEYHELPW +LPNCCALCSIZE_PARAMS +LPNMHDR +LPNONCLIENTMETRICSA +LPNONCLIENTMETRICSW +LPPAINTSTRUCT +LPSCROLLINFO +LPSERIALKEYSA +LPSERIALKEYSW +LPSOUNDSENTRYA +LPSOUNDSENTRYW +LPSTICKYKEYS +LPSTYLESTRUCT +LPTOGGLEKEYS +LPTPMPARAMS +LPTRACKMOUSEEVENT +LPWINDOWINFO +LPWINDOWPLACEMENT +LPWINDOWPOS +LPWNDCLASSA +LPWNDCLASSEXA +LPWNDCLASSEXW +LPWNDCLASSW MDICREATESTRUCTA MDICREATESTRUCTW MDINEXTMENU @@ -379,8 +956,10 @@ MENUITEMINFOA MENUITEMINFOW MENUITEMTEMPLATE MENUITEMTEMPLATEHEADER +MENUTEMPLATE MINIMIZEDMETRICS MINMAXINFO +MONITORENUMPROC MONITORINFO MONITORINFOEXA MONITORINFOEXW @@ -388,30 +967,102 @@ MOUSEHOOKSTRUCT MOUSEINPUT MOUSEKEYS MSG +MSGBOXCALLBACK MSGBOXPARAMSA MSGBOXPARAMSW MSLLHOOKSTRUCT MULTIKEYHELPA MULTIKEYHELPW +NAMEENUMPROCA +NAMEENUMPROCA +NAMEENUMPROCW +NAMEENUMPROCW NCCALCSIZE_PARAMS NMHDR NONCLIENTMETRICSA NONCLIENTMETRICSW PAINTSTRUCT +PCOMBOBOXINFO +PCOMPAREITEMSTRUCT +PCOPYDATASTRUCT +PCURSORINFO +PCWPRETSTRUCT +PCWPSTRUCT +PDEBUGHOOKINFO +PDELETEITEMSTRUCT +PDLGITEMTEMPLATEA +PDLGITEMTEMPLATEW +PDRAWITEMSTRUCT +PEVENTMSG +PGUITHREADINFO +PHARDWAREHOOKSTRUCT +PHARDWAREINPUT +PHDEVNOTIFY +PHELPWININFOA +PHELPWININFOW +PICONINFO +PICONMETRICSA +PICONMETRICSW +PINPUT +PKBDLLHOOKSTRUCT +PKEYBDINPUT +PMDINEXTMENU +PMEASUREITEMSTRUCT +PMENUITEMTEMPLATE +PMENUITEMTEMPLATEHEADER +PMINIMIZEDMETRICS +PMINMAXINFO +PMOUSEHOOKSTRUCT +PMOUSEINPUT +PMSG +PMSGBOXPARAMSA +PMSGBOXPARAMSW +PMSLLHOOKSTRUCT +PMULTIKEYHELPA +PMULTIKEYHELPW +PNONCLIENTMETRICSA +PNONCLIENTMETRICSW +PPAINTSTRUCT +PROPENUMPROCA +PROPENUMPROCA +PROPENUMPROCEXA +PROPENUMPROCEXA +PROPENUMPROCEXW +PROPENUMPROCEXW +PROPENUMPROCW +PROPENUMPROCW +PWINDOWINFO +PWINDOWPLACEMENT +PWINDOWPOS +PWNDCLASSA +PWNDCLASSEXA +PWNDCLASSEXW +PWNDCLASSW SCROLLINFO +SENDASYNCPROC +SENDASYNCPROC SERIALKEYSA SERIALKEYSW SOUNDSENTRYA SOUNDSENTRYW STICKYKEYS STYLESTRUCT +TIMERPROC +TIMERPROC TOGGLEKEYS TPMPARAMS TRACKMOUSEEVENT WINDOWINFO: !dwWindowStatus -# WINDOWPLACEMENT +!WINDOWPLACEMENT WINDOWPOS +WINEVENTPROC +WINEVENTPROC +WINSTAENUMPROCA +WINSTAENUMPROCW WNDCLASSA WNDCLASSEXA WNDCLASSEXW WNDCLASSW +WNDENUMPROC +WNDENUMPROC +WNDPROC diff --git a/tools/winapi/tests.pm b/tools/winapi/tests.pm index e745d791ccd..d9679a8aa5a 100644 --- a/tools/winapi/tests.pm +++ b/tools/winapi/tests.pm @@ -135,6 +135,46 @@ sub get_test_dirs { return sort(keys(%test_dirs)); } +sub get_sections { + my $self = shift; + + my $tests = \%{$self->{TESTS}}; + + my $test_dir = shift; + my $test = shift; + + my %sections = (); + if (defined($test_dir)) { + if (defined($test)) { + foreach my $section (sort(keys(%{$$tests{$test_dir}{$test}}))) { + $sections{$section}++; + } + } else { + foreach my $test (sort(keys(%{$$tests{$test_dir}}))) { + foreach my $section (sort(keys(%{$$tests{$test_dir}{$test}}))) { + $sections{$section}++; + } + } + } + } elsif (defined($test)) { + foreach my $test_dir (sort(keys(%$tests))) { + foreach my $section (sort(keys(%{$$tests{$test_dir}{$test}}))) { + $sections{$section}++; + } + } + } else { + foreach my $test_dir (sort(keys(%$tests))) { + foreach my $test (sort(keys(%{$$tests{$test_dir}}))) { + foreach my $section (sort(keys(%{$$tests{$test_dir}{$test}}))) { + $sections{$section}++; + } + } + } + } + + return sort(keys(%sections)); +} + sub get_section { my $self = shift; @@ -144,7 +184,12 @@ sub get_section { my $test = shift; my $section = shift; - return @{$$tests{$test_dir}{$test}{$section}}; + my $array = $$tests{$test_dir}{$test}{$section}; + if (defined($array)) { + return @$array; + } else { + return (); + } } 1; diff --git a/tools/winapi/winapi_test b/tools/winapi/winapi_test index c2c7f66caff..b2402b1f88a 100755 --- a/tools/winapi/winapi_test +++ b/tools/winapi/winapi_test @@ -76,6 +76,65 @@ my @files = (); } } +if (0) { + my $file = "tests.dat"; + + $file .= "2"; # FIXME: For tests + + open(OUT, "> $winapi_dir/$file") || die "$winapi_dir/$file: $!\n"; + + my $x = 0; + my @test_dirs = $tests->get_test_dirs(); + foreach my $test_dir (@test_dirs) { + print OUT "\n" if $x++; + print OUT "%%%$test_dir\n"; + print OUT "\n"; + + my $y = 0; + my @tests = $tests->get_tests($test_dir); + foreach my $test (@tests) { + print OUT "\n" if $y++; + print OUT "%%$test\n"; + print OUT "\n"; + + my @types; + + my $z = 0; + my @sections = $tests->get_sections($test_dir, $test); + foreach my $section (@sections) { + my @lines = $tests->get_section($test_dir, $test, $section); + + if ($section =~ /^(?:struct|type)$/) { + foreach my $line (@lines) { + push @types, $line; + } + next; + } + + print OUT "\n" if $z++; + print OUT "%$section\n"; + print OUT "\n"; + foreach my $line (@lines) { + print OUT "$line\n"; + } + } + + @types = sort { $x = $a; $y = $b; $x =~ s/^!//; $y =~ s/^!//; $x cmp $y } @types; + + print OUT "\n" if $z++; + print OUT "%type\n"; + print OUT "\n"; + foreach my $type (@types) { + print OUT "$type\n"; + } + } + } + + close(OUT); + exit(0); +} + + my %file2types; my $progress_output; @@ -106,46 +165,89 @@ my %defines = ( ); my %align_kludge_reported = ("FILETIME" => 1, "LARGE_INTEGER" => 1); +my %size_kludge_reported = ("FILETIME" => 1, "LARGE_INTEGER" => 1); +my %size_parse_reported; -sub find_align { +sub _find_align_kind_size { my $type_name = shift; local $_ = $type_name; - # Remove "count" and "bits" - s/^(.*?)\s*(?:\[\s*(.*?)\s*\]|:(\d+))?$/$1/; + my $count; + my $bits; + if (s/^(.*?)\s*(?:\[\s*(.*?)\s*\]|:(\d+))?$/$1/) { + $count = $2; + $bits = $3; + } my $align; + my $kind; + my $size; if (0) { # Nothing } elsif (/\*+$/) { $align = 4; - } elsif(/^(?:(?:signed\s+|unsigned\s+)?char)$/) { + $kind = "pointer"; + $size = 4; + } elsif(/^(?:(signed|unsigned)\s+)?(?:__int8|char)$/) { $align = 1; - } elsif (/^(?:(?:signed\s+|unsigned\s+)?short)$/) { + $kind = defined($1) ? $1 : "signed"; + $size = 1; + } elsif (/^(?:(signed|unsigned)\s+)?(?:__int16|short(?:\s+int)?)$/) { $align = 2; + $kind = defined($1) ? $1 : "signed"; + $size = 2; } elsif (/^(?:wchar_t)$/) { $align = 2; - } elsif (/^(?:(?:signed\s+|unsigned\s+)?(?:__int32|int|long(?:\s+int)?)|unsigned|signed)$/) { + $kind = "signed"; + $size = 2; + } elsif (!/^$/ && /^(?:(signed|unsigned)\s+)?(?:__int32|int|long(?:\s+int)?)?$/) { $align = 4; + $kind = defined($1) ? $1 : "signed"; + $size = 4; } elsif (/^(?:float)$/) { $align = 4; - } elsif (/^(?:signed\s+|unsigned\s+)?__int64$/) { - $align = 4; + $kind = "float"; + $size = 4; + } elsif (/^(?:(signed|unsigned)\s+)?__int64$/) { + $align = 8; + $kind = defined($1) ? $1 : "signed"; + $size = 8; } elsif (/^(?:double)$/) { $align = 4; + $kind = "float"; + $size = 8; } elsif (/^(?:long\s+double)$/) { $align = 4; + $kind = "float"; + $size = 10; # ??? } elsif (/^H(?:DC|BITMAP|BRUSH|ICON|INSTANCE|MENU|METAFILE|WND)$/) { $align = 4; + $kind = "unsigned"; + $size = 4; } elsif (/^LP(?:CSTR|CWSTR|DWORD|STR|VOID|THREAD_START_ROUTINE|WSTR)$/) { $align = 4; + $kind = "pointer"; + $size = 4; } elsif (/^(?:(?:MSGBOX)CALLBACK[AW]?|(?:FAR|WND)PROC[AW]?)$/) { $align = 4; - } elsif (/^(?:FILETIME|LARGE_INTEGER|LONGLONG)$/) { + $kind = "pointer"; + $size = 4; + } elsif (/^(?:FILETIME)$/) { $align = 4; - } else { - $align = undef; + $kind = "struct"; + $size = 8; + } elsif (/^(?:LARGE_INTEGER|LONGLONG)$/) { + $align = 4; + $kind = "signed"; + $size = 8; + } elsif (/^(struct|union)$/) { + $kind = $1; + if (!$size_parse_reported{$_}) { + $output->write("$type_name: can't parse type\n"); + $size_parse_reported{$_} = 1; + } + } my $align2; @@ -164,63 +266,6 @@ sub find_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 { - 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|signed)$/) { - $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 (/^(?:struct|union)$/) { - if (!$size_parse_reported{$_}) { - $output->write("$type_name: can't parse type\n"); - $size_parse_reported{$_} = 1; - } - $size = undef; - } else { - $size = undef; - } - my $size2; if (defined(my $type = $type_name2type{$_})) { $size2 = $type->size; @@ -248,6 +293,25 @@ sub find_size { $size = -$bits; } + return ($align, $kind, $size); +} + +sub find_align { + my $type_name = shift; + (my $align, my $kind, my $size) = _find_align_kind_size($type_name); + return $align; +} + +sub find_kind { + my $type_name = shift; + (my $align, my $kind, my $size) = _find_align_kind_size($type_name); + + return $kind; +} + +sub find_size { + my $type_name = shift; + (my $align, my $kind, my $size) = _find_align_kind_size($type_name); return $size; } @@ -323,10 +387,11 @@ foreach my $file (@files) { $file2types{$file}{$name} = $type; $type->set_find_align_callback(\&find_align); + $type->set_find_kind_callback(\&find_kind); $type->set_find_size_callback(\&find_size); my $pack = $packs[$#packs]; - if (!defined($type->pack)) { + if (!defined($type->pack) && $type->kind =~ /^(?:struct|union)$/) { $type->pack($pack); } my $size = $type->size(); @@ -424,6 +489,23 @@ sub output_header { print OUT "/* FIXME: Not sure if is possible to do without compiler extension */\n"; print OUT "#endif\n"; print OUT "\n"; + print OUT "#if (_MSC_VER >= 1300) && defined(__cplusplus)\n"; + print OUT "# define _TYPE_ALIGNMENT(type) __alignof(type)\n"; + print OUT "#elif defined(__GNUC__)\n"; + print OUT "# define _TYPE_ALIGNMENT(type) __alignof__(type)\n"; + print OUT "#else\n"; + print OUT "/*\n"; + print OUT " * FIXME: Not sure if is possible to do without compiler extension\n"; + print OUT " * (if type is not just a name that is, if so the normal)\n"; + print OUT " * TYPE_ALIGNMENT can be used)\n"; + print OUT " */\n"; + print OUT "#endif\n"; + print OUT "\n"; + print OUT "#if !defined(TYPE_ALIGNMENT) && defined(_TYPE_ALIGNMENT)\n"; + print OUT "# define TYPE_ALIGNMENT _TYPE_ALIGNMENT\n"; + print OUT "#endif\n"; + print OUT "\n"; + print OUT "/***********************************************************************\n"; print OUT " * Test helper macros\n"; print OUT " */\n"; @@ -442,8 +524,19 @@ sub output_header { print OUT " \"FIELD_OFFSET(\" #type \", \" #field \") == %ld (expected \" #offset \")\", \\\n"; print OUT " FIELD_OFFSET(type, field))\n"; print OUT "\n"; + print OUT "#ifdef _TYPE_ALIGNMENT\n"; + print OUT "#define TEST__TYPE_ALIGNMENT(type, align) \\\n"; + print OUT " ok(_TYPE_ALIGNMENT(type) == align, \"TYPE_ALIGNMENT(\" #type \") == %d (expected \" #align \")\", _TYPE_ALIGNMENT(type))\n"; + print OUT "#else\n"; + print OUT "# define TEST__TYPE_ALIGNMENT(type, align) do { } while (0)\n"; + print OUT "#endif\n"; + print OUT "\n"; + print OUT "#ifdef TYPE_ALIGNMENT\n"; print OUT "#define TEST_TYPE_ALIGNMENT(type, align) \\\n"; print OUT " ok(TYPE_ALIGNMENT(type) == align, \"TYPE_ALIGNMENT(\" #type \") == %d (expected \" #align \")\", TYPE_ALIGNMENT(type))\n"; + print OUT "#else\n"; + print OUT "# define TEST_TYPE_ALIGNMENT(type, align) do { } while (0)\n"; + print OUT "#endif\n"; print OUT "\n"; print OUT "#define TEST_TYPE_SIZE(type, size) \\\n"; print OUT " ok(sizeof(type) == size, \"sizeof(\" #type \") == %d (expected \" #size \")\", sizeof(type))\n"; @@ -461,6 +554,16 @@ sub output_header { print OUT " TEST_TYPE_ALIGNMENT(type, align); \\\n"; print OUT " TEST_TYPE_SIZE(type, size)\n"; print OUT "\n"; + print OUT "#define TEST_TYPE_POINTER(type, size, align) \\\n"; + print OUT " TEST__TYPE_ALIGNMENT(*(type)0, align); \\\n"; + print OUT " TEST_TYPE_SIZE(*(type)0, size)\n"; + print OUT "\n"; + print OUT "#define TEST_TYPE_SIGNED(type) \\\n"; + print OUT " ok((type) -1 < 0, \"(\" #type \") -1 < 0\");\n"; + print OUT "\n"; + print OUT "#define TEST_TYPE_UNSIGNED(type) \\\n"; + print OUT " ok((type) -1 > 0, \"(\" #type \") -1 > 0\");\n"; + print OUT "\n"; } ######################################################################## @@ -486,28 +589,91 @@ sub output_footer { sub output_test_pack_type { local *OUT = shift; - my $types = shift; + my $type_name2type = shift; + my $type_name2optional = shift; + my $type_name2optional_fields = shift; my $type_name = shift; my $type = shift; + my $optional_fields = $$type_name2optional_fields{$type_name}; + my $type_align = $type->align; my $type_pack = $type->pack; my $type_size = $type->size; - - print OUT " /* $type_name (pack $type_pack) */\n"; - if (defined($type_align) && defined($type_size)) { + my $type_kind = $type->kind; + + if (defined($type_pack)) { + print OUT " /* $type_name (pack $type_pack) */\n"; + } else { + print OUT " /* $type_name */\n"; + } + + if (!scalar(keys(%$optional_fields)) && defined($type_align) && defined($type_size)) { print OUT " TEST_TYPE($type_name, $type_size, $type_align);\n"; } + + if ($type_kind eq "float") { + # Nothing + } elsif ($type_kind eq "pointer") { + my $dereference_type; + $dereference_type = sub { + my $type = shift; + + my @fields = $type->fields; + my $type_name2 =$fields[0]->type_name; + + if ($type_name2 =~ s/\s*\*$//) { + my $type2 = $$type_name2type{$type_name2}; + if (defined($type2)) { + return $type2; + } else { + $output->write("$type_name2: type not found (ignored)\n"); + return undef; + } + } else { + my $type2 = $$type_name2type{$type_name2}; + if (defined($type2)) { + return &$dereference_type($type2); + } else { + $output->write("$type_name2: type not found (ignored)\n"); + return undef; + } + } + }; + + my $type2 = &$dereference_type($type); + if (defined($type2)) { + my $type_name2 = $type2->name; + my $type_align2 = $type2->align; + my $type_size2 = $type2->size; + + my $optional = $$type_name2optional{$type_name}; + my $optional_fields2 = $$type_name2optional_fields{$type_name2}; + + if (!$optional && !scalar(keys(%$optional_fields2)) && defined($type_align2) && defined($type_size2)) { + print OUT " TEST_TYPE_POINTER($type_name, $type_size2, $type_align2);\n"; + } else { + $output->write("$type_name: type size not found (ignored)\n"); + } + } + } elsif ($type_kind eq "signed") { + print OUT " TEST_TYPE_SIGNED($type_name);\n"; + } elsif ($type_kind eq "unsigned") { + print OUT " TEST_TYPE_UNSIGNED($type_name);\n"; + } } sub output_test_pack_fields { local *OUT = shift; - my $types = shift; + my $type_name2type = shift; + my $type_name2optional = shift; + my $type_name2optional_fields = shift; my $type_name = shift; my $type = shift; my $offset = shift; - my $optional_field = shift; + + my $optional_fields = $$type_name2optional_fields{$type_name}; foreach my $field ($type->fields()) { my $field_type_name = $field->type_name; @@ -518,7 +684,7 @@ sub output_test_pack_fields { next if $field_name eq "" || (defined($field_size) && $field_size < 0); - if ($$optional_field{$field_name}) { + if ($$optional_fields{$field_name}) { # Nothing } elsif (defined($field_size) && defined($field_offset)) { $field_offset += $offset; @@ -527,14 +693,15 @@ sub output_test_pack_fields { print OUT " TEST_FIELD($type_name, $field_type_name, $field_name, "; print OUT "$field_offset, $field_size, $field_align);\n"; print OUT "#else\n"; - output_test_pack_fields(\*OUT, $types, $type_name, $$types{$field_type_name}, $field_offset, $optional_field); + output_test_pack_fields(\*OUT, $type_name2type, $type_name2optional, $type_name2optional_fields, + $type_name, $$type_name2type{$field_type_name}, $field_offset); print OUT "#endif\n"; } else { print OUT " TEST_FIELD($type_name, $field_type_name, $field_name, "; print OUT "$field_offset, $field_size, $field_align);\n"; } } 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"); } } } @@ -548,55 +715,65 @@ sub output_test_pack { my $test_dir = shift; my $test = shift; + $output->prefix("$test_dir: $test: "); + my @headers = $tests->get_section($test_dir, $test, "header"); - my @type_names = $tests->get_section($test_dir, $test, "struct"); + my @type_names = $tests->get_section($test_dir, $test, "type"); my %type_name_not_used; + my %type_name2optional; + my %type_name2optional_fields; foreach my $_type_name (@type_names) { my $type_name = $_type_name; - $type_name =~ s/:.*?$//; + if ($type_name =~ s/^!//) { + $type_name2optional{$type_name}++; + } + + my $optional_fields = {}; + if ($type_name =~ s/:\s*(.*?)$//) { + my @fields = split /\s+/, $1; + foreach my $field (@fields) { + if ($field =~ s/^!//) { + $$optional_fields{$field}++; + } + } + } + + $type_name2optional_fields{$type_name} = $optional_fields; $type_name_not_used{$type_name} = 1; } foreach my $header (@headers) { - my $types = $file2types{"include/$header"}; + my $type_name2type = $file2types{"include/$header"}; foreach my $_type_name (@type_names) { my $type_name = $_type_name; - my %optional_field = (); - if ($type_name =~ s/:\s*(.*?)$//) { - my @fields = split /\s+/, $1; - foreach my $field (@fields) { - if ($field =~ s/^!//) { - $optional_field{$field}++; - } - } - } + next if $type_name =~ /^!/; + $type_name =~ s/:.*?$//; - my $type = $$types{$type_name}; + my $type = $$type_name2type{$type_name}; if (!defined($type)) { next; } $type_name_not_used{$type_name} = 0; - - if (!scalar(keys(%optional_field))) { - output_test_pack_type(\*OUT, $types, $type_name, $type); - } else { - print OUT " /* $type_name */\n"; - } - output_test_pack_fields(\*OUT, $types, $type_name, $type, 0, \%optional_field); + + output_test_pack_type(\*OUT, $type_name2type, \%type_name2optional, \%type_name2optional_fields, $type_name, $type); + output_test_pack_fields(\*OUT, $type_name2type, \%type_name2optional, \%type_name2optional_fields, $type_name, $type, 0); print OUT "\n"; } } foreach my $_type_name (@type_names) { my $type_name = $_type_name; + + next if $type_name =~ /^!/; $type_name =~ s/:.*?$//; + if ($type_name_not_used{$type_name}) { - # $output->write("$test_dir: $test: $type_name: type not found (ignored)\n"); + # $output->write("$type_name: type not found (ignored)\n"); } } } @@ -616,7 +793,7 @@ sub output_file { foreach my $test (@tests) { print OUT "void test_$test(void)\n"; print OUT "{\n"; - + if ($test eq "pack") { output_test_pack(\*OUT, $test_dir, $test); } else {