2007-01-09 18:50:36 +03:00
#!/usr/bin/perl
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
# Published under the GNU General Public License
use strict ;
use warnings ;
2008-01-13 02:05:24 +03:00
use Test::More tests = > 40 ;
2007-01-09 18:50:36 +03:00
use FindBin qw( $RealBin ) ;
use lib "$RealBin" ;
use Util ;
use Parse::Pidl::Util qw( MyDumper ) ;
2007-09-14 22:06:51 +04:00
use Parse::Pidl::NDR qw( GetElementLevelTable ParseElement align_type mapToScalar ParseType can_contain_deferred ) ;
2007-01-09 18:50:36 +03:00
# Case 1
my $ e = {
'FILE' = > 'foo.idl' ,
'NAME' = > 'v' ,
'PROPERTIES' = > { } ,
'POINTERS' = > 0 ,
'TYPE' = > 'uint8' ,
2007-01-09 18:54:36 +03:00
'PARENT' = > { TYPE = > 'STRUCT' } ,
2007-01-09 18:50:36 +03:00
'LINE' = > 42 } ;
is_deeply ( GetElementLevelTable ( $ e ) , [
{
'IS_DEFERRED' = > 0 ,
'LEVEL_INDEX' = > 0 ,
'DATA_TYPE' = > 'uint8' ,
'CONTAINS_DEFERRED' = > 0 ,
'TYPE' = > 'DATA' ,
'IS_SURROUNDING' = > 0 ,
}
] ) ;
2007-02-20 01:10:23 +03:00
my $ ne = ParseElement ( $ e , undef ) ;
2007-01-09 18:50:36 +03:00
is ( $ ne - > { ORIGINAL } , $ e ) ;
is ( $ ne - > { NAME } , "v" ) ;
is ( $ ne - > { ALIGN } , 1 ) ;
is ( $ ne - > { TYPE } , "uint8" ) ;
is_deeply ( $ ne - > { LEVELS } , [
{
'IS_DEFERRED' = > 0 ,
'LEVEL_INDEX' = > 0 ,
'DATA_TYPE' = > 'uint8' ,
'CONTAINS_DEFERRED' = > 0 ,
'TYPE' = > 'DATA' ,
'IS_SURROUNDING' = > 0 ,
}
] ) ;
# Case 2 : pointers
#
$ e = {
'FILE' = > 'foo.idl' ,
'NAME' = > 'v' ,
2007-01-09 18:54:36 +03:00
'PROPERTIES' = > { "unique" = > 1 } ,
2007-01-09 18:50:36 +03:00
'POINTERS' = > 1 ,
2007-01-09 18:54:36 +03:00
'PARENT' = > { TYPE = > 'STRUCT' } ,
2007-01-09 18:50:36 +03:00
'TYPE' = > 'uint8' ,
'LINE' = > 42 } ;
is_deeply ( GetElementLevelTable ( $ e ) , [
{
LEVEL_INDEX = > 0 ,
IS_DEFERRED = > 0 ,
TYPE = > 'POINTER' ,
2007-01-09 18:54:36 +03:00
POINTER_TYPE = > "unique" ,
2007-01-09 18:50:36 +03:00
POINTER_INDEX = > 0 ,
LEVEL = > 'EMBEDDED'
} ,
{
'IS_DEFERRED' = > 1 ,
'LEVEL_INDEX' = > 1 ,
'DATA_TYPE' = > 'uint8' ,
'CONTAINS_DEFERRED' = > 0 ,
'TYPE' = > 'DATA' ,
'IS_SURROUNDING' = > 0 ,
}
] ) ;
# Case 3 : double pointers
#
$ e = {
'FILE' = > 'foo.idl' ,
'NAME' = > 'v' ,
2007-01-09 18:54:36 +03:00
'PROPERTIES' = > { "unique" = > 1 } ,
2007-01-09 18:50:36 +03:00
'POINTERS' = > 2 ,
'TYPE' = > 'uint8' ,
2007-01-09 18:54:36 +03:00
'PARENT' = > { TYPE = > 'STRUCT' } ,
2007-01-09 18:50:36 +03:00
'LINE' = > 42 } ;
is_deeply ( GetElementLevelTable ( $ e ) , [
{
LEVEL_INDEX = > 0 ,
IS_DEFERRED = > 0 ,
TYPE = > 'POINTER' ,
2007-01-09 18:54:36 +03:00
POINTER_TYPE = > "unique" ,
2007-01-09 18:50:36 +03:00
POINTER_INDEX = > 0 ,
LEVEL = > 'EMBEDDED'
} ,
{
LEVEL_INDEX = > 1 ,
IS_DEFERRED = > 1 ,
TYPE = > 'POINTER' ,
2007-01-09 18:54:36 +03:00
POINTER_TYPE = > "unique" ,
2007-01-09 18:50:36 +03:00
POINTER_INDEX = > 1 ,
LEVEL = > 'EMBEDDED'
} ,
{
'IS_DEFERRED' = > 1 ,
'LEVEL_INDEX' = > 2 ,
'DATA_TYPE' = > 'uint8' ,
'CONTAINS_DEFERRED' = > 0 ,
'TYPE' = > 'DATA' ,
'IS_SURROUNDING' = > 0 ,
}
] ) ;
2007-01-09 18:54:36 +03:00
# Case 3 : ref pointers
2007-01-09 18:50:36 +03:00
#
$ e = {
'FILE' = > 'foo.idl' ,
'NAME' = > 'v' ,
'PROPERTIES' = > { "ref" = > 1 } ,
'POINTERS' = > 1 ,
'TYPE' = > 'uint8' ,
2007-01-09 18:54:36 +03:00
'PARENT' = > { TYPE = > 'STRUCT' } ,
2007-01-09 18:50:36 +03:00
'LINE' = > 42 } ;
is_deeply ( GetElementLevelTable ( $ e ) , [
{
LEVEL_INDEX = > 0 ,
IS_DEFERRED = > 0 ,
TYPE = > 'POINTER' ,
POINTER_TYPE = > "ref" ,
POINTER_INDEX = > 0 ,
LEVEL = > 'EMBEDDED'
} ,
{
'IS_DEFERRED' = > 1 ,
'LEVEL_INDEX' = > 1 ,
'DATA_TYPE' = > 'uint8' ,
'CONTAINS_DEFERRED' = > 0 ,
'TYPE' = > 'DATA' ,
'IS_SURROUNDING' = > 0 ,
}
] ) ;
2007-01-09 18:54:36 +03:00
# Case 4 : top-level ref pointers
#
$ e = {
'FILE' = > 'foo.idl' ,
'NAME' = > 'v' ,
'PROPERTIES' = > { "ref" = > 1 } ,
'POINTERS' = > 1 ,
'TYPE' = > 'uint8' ,
'PARENT' = > { TYPE = > 'FUNCTION' } ,
'LINE' = > 42 } ;
is_deeply ( GetElementLevelTable ( $ e ) , [
{
LEVEL_INDEX = > 0 ,
IS_DEFERRED = > 0 ,
TYPE = > 'POINTER' ,
POINTER_TYPE = > "ref" ,
POINTER_INDEX = > 0 ,
LEVEL = > 'TOP'
} ,
{
'IS_DEFERRED' = > 0 ,
'LEVEL_INDEX' = > 1 ,
'DATA_TYPE' = > 'uint8' ,
'CONTAINS_DEFERRED' = > 0 ,
'TYPE' = > 'DATA' ,
'IS_SURROUNDING' = > 0 ,
}
] ) ;
2007-02-18 16:44:01 +03:00
# representation_type
$ e = {
'FILE' = > 'foo.idl' ,
'NAME' = > 'v' ,
'PROPERTIES' = > { represent_as = > "bar" } ,
'POINTERS' = > 0 ,
'TYPE' = > 'uint8' ,
'PARENT' = > { TYPE = > 'STRUCT' } ,
'LINE' = > 42 } ;
2007-02-20 01:10:23 +03:00
$ ne = ParseElement ( $ e , undef ) ;
2007-02-18 16:44:01 +03:00
is ( $ ne - > { REPRESENTATION_TYPE } , "bar" ) ;
# representation_type
$ e = {
'FILE' = > 'foo.idl' ,
'NAME' = > 'v' ,
'PROPERTIES' = > { } ,
'POINTERS' = > 0 ,
'TYPE' = > 'uint8' ,
'PARENT' = > { TYPE = > 'STRUCT' } ,
'LINE' = > 42 } ;
2007-02-20 01:10:23 +03:00
$ ne = ParseElement ( $ e , undef ) ;
2007-02-18 16:44:01 +03:00
is ( $ ne - > { REPRESENTATION_TYPE } , "uint8" ) ;
2007-02-28 02:47:07 +03:00
2007-02-28 03:28:14 +03:00
is ( align_type ( "hyper" ) , 8 ) ;
2007-02-28 02:47:07 +03:00
is ( align_type ( "uint32" ) , 4 ) ;
is ( align_type ( "uint16" ) , 2 ) ;
is ( align_type ( "uint8" ) , 1 ) ;
is ( align_type ( { TYPE = > "STRUCT" , "NAME" = > "bla" ,
ELEMENTS = > [ { TYPE = > "uint16" } ] } ) , 4 ) ;
2007-02-28 03:28:14 +03:00
is ( align_type ( { TYPE = > "STRUCT" ,
ELEMENTS = > [ { TYPE = > "hyper" } ] } ) , 8 ) ;
2008-01-12 23:21:14 +03:00
is ( align_type ( { TYPE = > "TYPEDEF" , DATA = > {
2007-02-28 03:28:14 +03:00
TYPE = > "STRUCT" ,
ELEMENTS = > [ { TYPE = > "hyper" } ] } } ) , 8 ) ;
2008-01-12 23:21:14 +03:00
# typedef of struct without body
is ( align_type ( { TYPE = > "TYPEDEF" , DATA = > {
TYPE = > "STRUCT" , ELEMENTS = > undef } } ) , 4 ) ;
# struct without body
is ( align_type ( { TYPE = > "STRUCT" , ELEMENTS = > undef } ) , 4 ) ;
# empty struct
is ( align_type ( { TYPE = > "STRUCT" , ELEMENTS = > [] } ) , 1 ) ;
2007-02-28 02:47:07 +03:00
is ( align_type ( { TYPE = > "STRUCT" , "NAME" = > "bla" ,
ELEMENTS = > [ { TYPE = > "uint8" } ] } ) , 4 ) ;
2007-02-28 03:19:57 +03:00
is ( mapToScalar ( "someverymuchnotexistingtype" ) , undef ) ;
is ( mapToScalar ( "uint32" ) , "uint32" ) ;
is ( mapToScalar ( { TYPE = > "ENUM" , PARENT = > { PROPERTIES = > { enum8bit = > 1 } } } ) , "uint8" ) ;
is ( mapToScalar ( { TYPE = > "BITMAP" , PROPERTIES = > { bitmap64bit = > 1 } } ) ,
"hyper" ) ;
is ( mapToScalar ( { TYPE = > "TYPEDEF" , DATA = > { TYPE = > "ENUM" , PARENT = > { PROPERTIES = > { enum8bit = > 1 } } } } ) , "uint8" ) ;
2007-02-28 16:25:53 +03:00
2007-08-16 18:42:22 +04:00
my $ t ;
$ t = {
TYPE = > "STRUCT" ,
NAME = > "foo" ,
SURROUNDING_ELEMENT = > undef ,
ELEMENTS = > undef ,
PROPERTIES = > undef ,
ORIGINAL = > {
TYPE = > "STRUCT" ,
NAME = > "foo"
} ,
ALIGN = > undef
} ;
is_deeply ( ParseType ( $ t - > { ORIGINAL } , "ref" ) , $ t ) ;
$ t = {
TYPE = > "UNION" ,
NAME = > "foo" ,
SWITCH_TYPE = > "uint32" ,
ELEMENTS = > undef ,
PROPERTIES = > undef ,
HAS_DEFAULT = > 0 ,
ORIGINAL = > {
TYPE = > "UNION" ,
NAME = > "foo"
}
} ;
is_deeply ( ParseType ( $ t - > { ORIGINAL } , "ref" ) , $ t ) ;
2007-09-14 22:06:51 +04:00
ok ( not can_contain_deferred ( "uint32" ) ) ;
ok ( can_contain_deferred ( "some_unknown_type" ) ) ;
ok ( can_contain_deferred ( { TYPE = > "STRUCT" ,
ELEMENTS = > [ { TYPE = > "uint32" , POINTERS = > 40 } ] } ) ) ;
ok ( can_contain_deferred ( { TYPE = > "TYPEDEF" ,
DATA = > { TYPE = > "STRUCT" ,
ELEMENTS = > [ { TYPE = > "uint32" , POINTERS = > 40 } ] } } ) ) ;
ok ( not can_contain_deferred ( { TYPE = > "STRUCT" ,
ELEMENTS = > [ { TYPE = > "uint32" } ] } ) ) ;
ok ( not can_contain_deferred ( { TYPE = > "TYPEDEF" ,
DATA = > { TYPE = > "STRUCT" ,
ELEMENTS = > [ { TYPE = > "uint32" } ] } } ) ) ;
2007-09-16 03:03:34 +04:00
ok ( can_contain_deferred ( { TYPE = > "STRUCT" ,
ELEMENTS = > [ { TYPE = > "someunknowntype" } ] } ) ) ;
2008-01-13 01:10:28 +03:00
# Make sure the elements for a enum without body aren't filled in
ok ( not defined ( ParseType ( { TYPE = > "ENUM" , NAME = > "foo" } , "ref" ) - > { ELEMENTS } ) ) ;
# Make sure the elements for a bitmap without body aren't filled in
ok ( not defined ( ParseType ( { TYPE = > "BITMAP" , NAME = > "foo" } , "ref" ) - > { ELEMENTS } ) ) ;
2008-01-13 02:05:24 +03:00
# Make sure the elements for a union without body aren't filled in
ok ( not defined ( ParseType ( { TYPE = > "UNION" , NAME = > "foo" } , "ref" ) - > { ELEMENTS } ) ) ;