s3:idmap_ad: add support for ADS_AUTH_SASL_{STARTTLS,LDAPS}
[Samba.git] / pidl / tests / header.pl
blobdc8bbd7a2938ae3ab644df913344708fc52bcd62
1 #!/usr/bin/perl
2 # (C) 2007 Jelmer Vernooij <jelmer@samba.org>
3 # Published under the GNU General Public License
4 use strict;
5 use warnings;
7 use Test::More tests => 30;
8 use FindBin qw($RealBin);
9 use lib "$RealBin";
10 use Util;
11 use Parse::Pidl::Util qw(MyDumper);
12 use Parse::Pidl::Samba4::Header qw(
13 GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv
14 EnvSubstituteValue);
15 use Parse::Pidl::IDL qw(parse_string);
16 use Parse::Pidl::NDR;
18 sub parse_idl($)
20 my $text = shift;
21 my $idl = Parse::Pidl::IDL::parse_string($text, "nofile");
22 my $ndr = Parse::Pidl::NDR::Parse($idl);
23 return Parse::Pidl::Samba4::Header::Parse($ndr);
26 sub load_and_parse_idl($)
28 my $text = shift;
29 my $ndr;
30 my $idl = Parse::Pidl::IDL::parse_string($text, "nofile");
31 Parse::Pidl::Typelist::LoadIdl($idl, "noname");
32 $ndr = Parse::Pidl::NDR::Parse($idl);
33 return Parse::Pidl::Samba4::Header::Parse($ndr);
36 like(parse_idl(""), qr/\/\* header auto-generated by pidl \*\/\n/sm, "includes work");
37 like(parse_idl("interface x {}"), qr/\/\* header auto-generated by pidl \*\/\n/sm, "simple empty interface doesn't cause overhead");
38 like(parse_idl("interface p { typedef struct { int y; } x; };"),
39 qr/.*#ifndef _HEADER_p\n#define _HEADER_p\n.+\n#endif \/\* _HEADER_p \*\/.*/ms, "ifdefs are created");
40 like(parse_idl("interface p { typedef struct { int y; } x; };"),
41 qr/struct x.*{.*int32_t y;.*}.*;/sm, "interface member generated properly");
42 like(parse_idl("interface x { void foo (void); };"),
43 qr/struct foo.*{\s+int _dummy_element;\s+};/sm, "void fn contains dummy element");
44 like(parse_idl("interface x { void foo ([in] uint32 x); };"),
45 qr/struct foo.*{\s+struct\s+{\s+uint32_t x;\s+} in;\s+};/sm, "fn in arg works");
46 like(parse_idl("interface x { void foo ([out] uint32 x); };"),
47 qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} out;.*};/sm, "fn out arg works");
48 like(parse_idl("interface x { void foo ([in,out] uint32 x); };"),
49 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");
50 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");
51 like(parse_idl("interface p { struct x { int y; }; };"),
52 qr/struct x.*{.*int32_t y;.*}.*;/sm, "interface member generated properly");
54 like(parse_idl("interface p { struct x { struct y z; }; };"),
55 qr/struct x.*{.*struct y z;.*}.*;/sm, "tagged type struct member");
57 like(parse_idl("interface p { struct x { union y z; }; };"),
58 qr/struct x.*{.*union y z;.*}.*;/sm, "tagged type union member");
60 like(parse_idl("interface p { struct x { }; };"),
61 qr/struct x.*{.*char _empty_;.*}.*;/sm, "empty struct");
63 like(parse_idl("interface p { struct x; };"),
64 qr/struct x;/sm, "struct declaration");
66 like(parse_idl("interface p { typedef struct x { int p; } x; };"),
67 qr/struct x.*{.*int32_t p;.*};/sm, "double struct declaration");
69 like(parse_idl("cpp_quote(\"some-foo\")"),
70 qr/some-foo/sm, "cpp quote");
72 like(load_and_parse_idl("interface hang {typedef [public] struct { wsp_cbasestoragevariant a[SINGLE]; } foo; typedef [public,nodiscriminant,switch_type(uint16)] union { [case(VT_I1)] int8 vt_i1; [case(VT_VARIANT)] foo b; } variant_types; typedef [public] struct { [switch_is(vtype)] variant_types vvalue; } bar;};"),
73 qr/struct foo.*{.*struct wsp_cbasestoragevariant \*a.*struct bar \{.*union variant_types vvalue.*;/sm,"test for hang with nested struct with union");
75 like(load_and_parse_idl("interface hang { typedef struct { uint32 count; bar a[count];} foo ; typedef struct { foo b; } bar; };"),
76 qr/struct foo.*{.*struct bar \*a;/sm,"test for hang with nested struct");
78 like(load_and_parse_idl("interface hang { typedef struct { bar a; } foo ; typedef struct { foo b; } bar; };"),
79 qr/struct foo.*{.*struct bar a;/sm,"test for hang with uncompilable nested struct");
81 # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
82 my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] };
83 is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn));
85 $fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] };
86 is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn));
88 $fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] };
89 is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn));
91 $fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] };
92 is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn));
94 $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] };
95 is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionOutEnv($fn));
97 $fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] };
98 is_deeply({ }, GenerateFunctionInEnv($fn));
100 $fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] };
101 is_deeply({ foo => "r->foo", bar => "r->bar", this => "r" },
102 GenerateStructEnv($fn, "r"));
104 $fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] };
105 is_deeply({ foo => "some->complex.variable->foo",
106 bar => "some->complex.variable->bar",
107 this => "some->complex.variable" },
108 GenerateStructEnv($fn, "some->complex.variable"));
110 $fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 3 }} ] };
112 my $env = GenerateStructEnv($fn, "r");
113 EnvSubstituteValue($env, $fn);
114 is_deeply($env, { foo => 3, this => "r" });
116 $fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] };
117 $env = GenerateStructEnv($fn, "r");
118 EnvSubstituteValue($env, $fn);
119 is_deeply($env, { foo => 'r->foo', bar => 'r->bar', this => "r" });
121 $fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 0 }} ] };
123 $env = GenerateStructEnv($fn, "r");
124 EnvSubstituteValue($env, $fn);
125 is_deeply($env, { foo => 0, this => "r" });