2007-02-09 02:54:31 +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 20:15:12 +03:00
use Test::More tests = > 27 ;
2007-02-09 02:54:31 +03:00
use FindBin qw( $RealBin ) ;
use lib "$RealBin" ;
use Util ;
use Parse::Pidl::Util qw( MyDumper ) ;
2008-01-13 20:15:12 +03:00
use Parse::Pidl::Samba4::Header qw(
GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv
EnvSubstituteValue ) ;
2007-02-09 02:54:31 +03:00
use Parse::Pidl::IDL qw( parse_string ) ;
2007-08-16 17:41:48 +04:00
use Parse::Pidl::NDR ;
2007-02-09 02:54:31 +03:00
sub parse_idl ($)
{
my $ text = shift ;
my $ idl = Parse::Pidl::IDL:: parse_string ( $ text , "nofile" ) ;
2007-08-16 17:41:48 +04:00
my $ ndr = Parse::Pidl::NDR:: Parse ( $ idl ) ;
return Parse::Pidl::Samba4::Header:: Parse ( $ ndr ) ;
2007-02-09 02:54:31 +03:00
}
2007-02-09 12:44:11 +03:00
like ( parse_idl ( "" ) , qr/\/ \ * header auto - generated by pidl \ * \ /\n/sm , "includes work" ) ;
2007-02-09 03:18:06 +03:00
like ( parse_idl ( "interface x {}" ) , qr/\/ \ * header auto - generated by pidl \ * \ /\n/sm , "simple empty interface doesn't cause overhead" ) ;
2007-02-09 02:54:31 +03:00
like ( parse_idl ( "interface p { typedef struct { int y; } x; };" ) ,
qr/.*#ifndef _HEADER_p\n#define _HEADER_p\n.+\n#endif \/ \ * _HEADER_p \ * \ /.*/ms , "ifdefs are created" ) ;
like ( parse_idl ( "interface p { typedef struct { int y; } x; };" ) ,
qr/struct x.*{.*int32_t y;.*}.*;/ sm , "interface member generated properly" ) ;
like ( parse_idl ( "interface x { void foo (void); };" ) ,
qr/struct foo.*{\s+int _dummy_element;\s+};/ sm , "void fn contains dummy element" ) ;
like ( parse_idl ( "interface x { void foo ([in] uint32 x); };" ) ,
qr/struct foo.*{\s+struct\s+{\s+uint32_t x;\s+} in;\s+};/ sm , "fn in arg works" ) ;
like ( parse_idl ( "interface x { void foo ([out] uint32 x); };" ) ,
qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} out;.*};/ sm , "fn out arg works" ) ;
like ( parse_idl ( "interface x { void foo ([in,out] uint32 x); };" ) ,
qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} in;\s+struct\s+{\s+uint32_t x;\s+} out;.*};/ sm , "fn in,out arg works" ) ;
like ( parse_idl ( "interface x { void foo (uint32 x); };" ) , qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} in;\s+struct\s+{\s+uint32_t x;\s+} out;.*};/ sm , "fn with no props implies in,out" ) ;
2007-02-18 19:21:28 +03:00
like ( parse_idl ( "interface p { struct x { int y; }; };" ) ,
qr/struct x.*{.*int32_t y;.*}.*;/ sm , "interface member generated properly" ) ;
2007-02-28 16:25:53 +03:00
like ( parse_idl ( "interface p { struct x { struct y z; }; };" ) ,
qr/struct x.*{.*struct y z;.*}.*;/ sm , "tagged type struct member" ) ;
like ( parse_idl ( "interface p { struct x { union y z; }; };" ) ,
qr/struct x.*{.*union y z;.*}.*;/ sm , "tagged type union member" ) ;
2007-03-04 17:16:52 +03:00
like ( parse_idl ( "interface p { struct x { }; };" ) ,
qr/struct x.*{.*char _empty_;.*}.*;/ sm , "empty struct" ) ;
like ( parse_idl ( "interface p { struct x; };" ) ,
qr/struct x;/ sm , "struct declaration" ) ;
2007-03-05 03:03:44 +03:00
like ( parse_idl ( "interface p { typedef struct x { int p; } x; };" ) ,
qr/struct x.*{.*int32_t p;.*};/ sm , "double struct declaration" ) ;
2007-08-31 04:03:54 +04:00
like ( parse_idl ( "cpp_quote(\"some-foo\")" ) ,
qr/some-foo/ sm , "cpp quote" ) ;
2008-01-13 20:15:12 +03:00
# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
my $ fn = { ELEMENTS = > [ { DIRECTION = > [ "in" ] , NAME = > "foo" } ] } ;
is_deeply ( { "foo" = > "r->in.foo" } , GenerateFunctionInEnv ( $ fn ) ) ;
$ fn = { ELEMENTS = > [ { DIRECTION = > [ "out" ] , NAME = > "foo" } ] } ;
is_deeply ( { "foo" = > "r->out.foo" } , GenerateFunctionOutEnv ( $ fn ) ) ;
$ fn = { ELEMENTS = > [ { DIRECTION = > [ "out" , "in" ] , NAME = > "foo" } ] } ;
is_deeply ( { "foo" = > "r->in.foo" } , GenerateFunctionInEnv ( $ fn ) ) ;
$ fn = { ELEMENTS = > [ { DIRECTION = > [ "out" , "in" ] , NAME = > "foo" } ] } ;
is_deeply ( { "foo" = > "r->out.foo" } , GenerateFunctionOutEnv ( $ fn ) ) ;
$ fn = { ELEMENTS = > [ { DIRECTION = > [ "in" ] , NAME = > "foo" } ] } ;
is_deeply ( { "foo" = > "r->in.foo" } , GenerateFunctionOutEnv ( $ fn ) ) ;
$ fn = { ELEMENTS = > [ { DIRECTION = > [ "out" ] , NAME = > "foo" } ] } ;
is_deeply ( { } , GenerateFunctionInEnv ( $ fn ) ) ;
$ fn = { ELEMENTS = > [ { NAME = > "foo" } , { NAME = > "bar" } ] } ;
is_deeply ( { foo = > "r->foo" , bar = > "r->bar" , this = > "r" } ,
GenerateStructEnv ( $ fn , "r" ) ) ;
$ fn = { ELEMENTS = > [ { NAME = > "foo" } , { NAME = > "bar" } ] } ;
is_deeply ( { foo = > "some->complex.variable->foo" ,
bar = > "some->complex.variable->bar" ,
this = > "some->complex.variable" } ,
GenerateStructEnv ( $ fn , "some->complex.variable" ) ) ;
$ fn = { ELEMENTS = > [ { NAME = > "foo" , PROPERTIES = > { value = > 3 } } ] } ;
my $ env = GenerateStructEnv ( $ fn , "r" ) ;
EnvSubstituteValue ( $ env , $ fn ) ;
is_deeply ( $ env , { foo = > 3 , this = > "r" } ) ;
$ fn = { ELEMENTS = > [ { NAME = > "foo" } , { NAME = > "bar" } ] } ;
$ env = GenerateStructEnv ( $ fn , "r" ) ;
EnvSubstituteValue ( $ env , $ fn ) ;
is_deeply ( $ env , { foo = > 'r->foo' , bar = > 'r->bar' , this = > "r" } ) ;
$ fn = { ELEMENTS = > [ { NAME = > "foo" , PROPERTIES = > { value = > 0 } } ] } ;
$ env = GenerateStructEnv ( $ fn , "r" ) ;
EnvSubstituteValue ( $ env , $ fn ) ;
is_deeply ( $ env , { foo = > 0 , this = > "r" } ) ;