summaryrefslogtreecommitdiff
path: root/pidl
diff options
context:
space:
mode:
authorbubulle <bubulle@alioth.debian.org>2011-11-12 13:00:54 +0000
committerbubulle <bubulle@alioth.debian.org>2011-11-12 13:00:54 +0000
commit6fba685eec3a1165ec0b82d72d3ae71e946a1404 (patch)
treef3c0543c8f9df4a22ed62e3bd99d9d7bc1054c14 /pidl
parent77a7925c0509068d5cd2affd94a3996d0a86035a (diff)
downloadsamba-6fba685eec3a1165ec0b82d72d3ae71e946a1404.tar.gz
Merge upstream 3.6.1 source
git-svn-id: svn://svn.debian.org/svn/pkg-samba/trunk/samba@3972 fc4039ab-9d04-0410-8cac-899223bdd6b0
Diffstat (limited to 'pidl')
-rw-r--r--pidl/config.m49
-rw-r--r--pidl/config.mk34
-rw-r--r--pidl/idl.yp43
-rw-r--r--pidl/lib/Parse/Pidl/Compat.pm6
-rw-r--r--pidl/lib/Parse/Pidl/Expr.pm72
-rw-r--r--pidl/lib/Parse/Pidl/IDL.pm511
-rw-r--r--pidl/lib/Parse/Pidl/NDR.pm273
-rw-r--r--pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm216
-rw-r--r--pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm98
-rw-r--r--pidl/lib/Parse/Pidl/Samba4.pm9
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm2
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/Header.pm43
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm886
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm340
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm2
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/Python.pm400
-rw-r--r--pidl/lib/Parse/Pidl/Typelist.pm52
-rw-r--r--pidl/lib/Parse/Pidl/Wireshark/Conformance.pm12
-rw-r--r--pidl/lib/Parse/Pidl/Wireshark/NDR.pm26
-rw-r--r--pidl/lib/wscript_build4
-rwxr-xr-xpidl/pidl25
-rw-r--r--pidl/tests/Util.pm1
-rwxr-xr-xpidl/tests/ndr.pl42
-rwxr-xr-xpidl/tests/ndr_string.pl18
-rwxr-xr-xpidl/tests/parse_idl.pl4
-rwxr-xr-xpidl/tests/samba-ndr.pl2
-rwxr-xr-xpidl/tests/samba3-cli.pl176
-rw-r--r--pidl/wscript85
28 files changed, 2345 insertions, 1046 deletions
diff --git a/pidl/config.m4 b/pidl/config.m4
deleted file mode 100644
index 8b8bc5acf0..0000000000
--- a/pidl/config.m4
+++ /dev/null
@@ -1,9 +0,0 @@
-# Check whether ExtUtils::ExtMaker is available
-
-if perl -e "use ExtUtils::MakeMaker" 2>/dev/null; then
- HAVE_PERL_EXTUTILS_MAKEMAKER=1
-else
- HAVE_PERL_EXTUTILS_MAKEMAKER=0
-fi
-
-AC_SUBST(HAVE_PERL_EXTUTILS_MAKEMAKER)
diff --git a/pidl/config.mk b/pidl/config.mk
deleted file mode 100644
index d7a84e3fcc..0000000000
--- a/pidl/config.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-PIDL = $(PERL) $(pidldir)/pidl
-
-$(pidldir)/Makefile: $(pidldir)/Makefile.PL
- @cd $(pidldir) && $(PERL) Makefile.PL PREFIX=$(prefix)
-
-pidl-testcov: $(pidldir)/Makefile
- cd $(pidldir) && cover -test
-
-installpidl:: $(pidldir)/Makefile
- @$(MAKE) -C $(pidldir) install_vendor VENDORPREFIX=$(prefix) \
- INSTALLVENDORLIB=$(datarootdir)/perl5 \
- INSTALLVENDORBIN=$(bindir) \
- INSTALLVENDORSCRIPT=$(bindir) \
- INSTALLVENDORMAN1DIR=$(mandir)/man1 \
- INSTALLVENDORMAN3DIR=$(mandir)/man3
-
-ifeq ($(HAVE_PERL_EXTUTILS_MAKEMAKER),1)
-install:: installpidl
-endif
-
-$(pidldir)/lib/Parse/Pidl/IDL.pm: $(pidldir)/idl.yp
- -$(YAPP) -m 'Parse::Pidl::IDL' -o $(pidldir)/lib/Parse/Pidl/IDL.pm $(pidldir)/idl.yp ||\
- touch $(pidldir)/lib/Parse/Pidl/IDL.pm
-
-$(pidldir)/lib/Parse/Pidl/Expr.pm: $(pidldir)/idl.yp
- -$(YAPP) -m 'Parse::Pidl::Expr' -o $(pidldir)/lib/Parse/Pidl/Expr.pm $(pidldir)/expr.yp ||\
- touch $(pidldir)/lib/Parse/Pidl/Expr.pm
-
-testcov-html:: pidl-testcov
-
-pidl-clean:
- /bin/rm -f $(pidldir)/Makefile
-
-clean:: pidl-clean
diff --git a/pidl/idl.yp b/pidl/idl.yp
index dc8e293f76..b5c5185fbe 100644
--- a/pidl/idl.yp
+++ b/pidl/idl.yp
@@ -169,13 +169,14 @@ function:
;
typedef:
- property_list 'typedef' type identifier array_len ';'
+ property_list 'typedef' type pointers identifier array_len ';'
{{
"TYPE" => "TYPEDEF",
"PROPERTIES" => $_[1],
- "NAME" => $_[4],
+ "NAME" => $_[5],
"DATA" => $_[3],
- "ARRAY_LEN" => $_[5],
+ "POINTERS" => $_[4],
+ "ARRAY_LEN" => $_[6],
"FILE" => $_[0]->YYData->{FILE},
"LINE" => $_[0]->YYData->{LINE},
}}
@@ -386,7 +387,31 @@ pipe:
{{
"TYPE" => "PIPE",
"PROPERTIES" => $_[1],
- "DATA" => $_[3],
+ "NAME" => undef,
+ "DATA" => {
+ "TYPE" => "STRUCT",
+ "PROPERTIES" => $_[1],
+ "NAME" => undef,
+ "ELEMENTS" => [{
+ "NAME" => "count",
+ "PROPERTIES" => $_[1],
+ "POINTERS" => 0,
+ "ARRAY_LEN" => [],
+ "TYPE" => "uint3264",
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ },{
+ "NAME" => "array",
+ "PROPERTIES" => $_[1],
+ "POINTERS" => 0,
+ "ARRAY_LEN" => [ "count" ],
+ "TYPE" => $_[3],
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ }],
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ },
"FILE" => $_[0]->YYData->{FILE},
"LINE" => $_[0]->YYData->{LINE},
}}
@@ -652,11 +677,17 @@ sub parse_file($$)
my $saved_delim = $/;
undef $/;
my $cpp = $ENV{CPP};
+ my $options = "";
if (! defined $cpp) {
- $cpp = "cpp";
+ if (defined $ENV{CC}) {
+ $cpp = "$ENV{CC}";
+ $options = "-E";
+ } else {
+ $cpp = "cpp";
+ }
}
my $includes = join('',map { " -I$_" } @$incdirs);
- my $data = `$cpp -D__PIDL__$includes -xc $filename`;
+ my $data = `$cpp $options -D__PIDL__$includes -xc "$filename"`;
$/ = $saved_delim;
return parse_string($data, $filename);
diff --git a/pidl/lib/Parse/Pidl/Compat.pm b/pidl/lib/Parse/Pidl/Compat.pm
index 1b49c439c4..b8abcb8819 100644
--- a/pidl/lib/Parse/Pidl/Compat.pm
+++ b/pidl/lib/Parse/Pidl/Compat.pm
@@ -19,6 +19,7 @@ my %supported_properties = (
"uuid" => ["INTERFACE"],
"endpoint" => ["INTERFACE"],
"pointer_default" => ["INTERFACE"],
+ "no_srv_register" => ["INTERFACE"],
# dcom
"object" => ["INTERFACE"],
@@ -44,6 +45,7 @@ my %supported_properties = (
"nopush" => ["FUNCTION", "TYPEDEF"],
"nopull" => ["FUNCTION", "TYPEDEF"],
"noprint" => ["FUNCTION", "TYPEDEF"],
+ "nopython" => ["FUNCTION", "TYPEDEF"],
# union
"switch_is" => ["ELEMENT"],
@@ -125,6 +127,10 @@ sub CheckElement($)
warning($e, "relative() pointer property not supported");
}
+ if (has_property($e, "relative_short")) {
+ warning($e, "relative_short() pointer property not supported");
+ }
+
if (has_property($e, "flag")) {
warning($e, "ignoring flag() property");
}
diff --git a/pidl/lib/Parse/Pidl/Expr.pm b/pidl/lib/Parse/Pidl/Expr.pm
index 1230a71a2b..24581d29f4 100644
--- a/pidl/lib/Parse/Pidl/Expr.pm
+++ b/pidl/lib/Parse/Pidl/Expr.pm
@@ -1127,7 +1127,7 @@ sub new {
[#Rule 2
'exp', 1,
sub
-#line 24 "./../pidl/expr.yp"
+#line 24 "expr.yp"
{ "\"$_[1]\"" }
],
[#Rule 3
@@ -1139,199 +1139,199 @@ sub
[#Rule 5
'exp', 2,
sub
-#line 30 "./../pidl/expr.yp"
+#line 30 "expr.yp"
{ "~$_[2]" }
],
[#Rule 6
'exp', 3,
sub
-#line 32 "./../pidl/expr.yp"
+#line 32 "expr.yp"
{ "$_[1] + $_[3]" }
],
[#Rule 7
'exp', 3,
sub
-#line 34 "./../pidl/expr.yp"
+#line 34 "expr.yp"
{ "$_[1] - $_[3]" }
],
[#Rule 8
'exp', 3,
sub
-#line 36 "./../pidl/expr.yp"
+#line 36 "expr.yp"
{ "$_[1] * $_[3]" }
],
[#Rule 9
'exp', 3,
sub
-#line 38 "./../pidl/expr.yp"
+#line 38 "expr.yp"
{ "$_[1] % $_[3]" }
],
[#Rule 10
'exp', 3,
sub
-#line 40 "./../pidl/expr.yp"
+#line 40 "expr.yp"
{ "$_[1] < $_[3]" }
],
[#Rule 11
'exp', 3,
sub
-#line 42 "./../pidl/expr.yp"
+#line 42 "expr.yp"
{ "$_[1] > $_[3]" }
],
[#Rule 12
'exp', 3,
sub
-#line 44 "./../pidl/expr.yp"
+#line 44 "expr.yp"
{ "$_[1] | $_[3]" }
],
[#Rule 13
'exp', 3,
sub
-#line 46 "./../pidl/expr.yp"
+#line 46 "expr.yp"
{ "$_[1] == $_[3]" }
],
[#Rule 14
'exp', 3,
sub
-#line 48 "./../pidl/expr.yp"
+#line 48 "expr.yp"
{ "$_[1] <= $_[3]" }
],
[#Rule 15
'exp', 3,
sub
-#line 50 "./../pidl/expr.yp"
+#line 50 "expr.yp"
{ "$_[1] => $_[3]" }
],
[#Rule 16
'exp', 3,
sub
-#line 52 "./../pidl/expr.yp"
+#line 52 "expr.yp"
{ "$_[1] << $_[3]" }
],
[#Rule 17
'exp', 3,
sub
-#line 54 "./../pidl/expr.yp"
+#line 54 "expr.yp"
{ "$_[1] >> $_[3]" }
],
[#Rule 18
'exp', 3,
sub
-#line 56 "./../pidl/expr.yp"
+#line 56 "expr.yp"
{ "$_[1] != $_[3]" }
],
[#Rule 19
'exp', 3,
sub
-#line 58 "./../pidl/expr.yp"
+#line 58 "expr.yp"
{ "$_[1] || $_[3]" }
],
[#Rule 20
'exp', 3,
sub
-#line 60 "./../pidl/expr.yp"
+#line 60 "expr.yp"
{ "$_[1] && $_[3]" }
],
[#Rule 21
'exp', 3,
sub
-#line 62 "./../pidl/expr.yp"
+#line 62 "expr.yp"
{ "$_[1] & $_[3]" }
],
[#Rule 22
'exp', 5,
sub
-#line 64 "./../pidl/expr.yp"
+#line 64 "expr.yp"
{ "$_[1]?$_[3]:$_[5]" }
],
[#Rule 23
'exp', 2,
sub
-#line 66 "./../pidl/expr.yp"
+#line 66 "expr.yp"
{ "~$_[1]" }
],
[#Rule 24
'exp', 2,
sub
-#line 68 "./../pidl/expr.yp"
+#line 68 "expr.yp"
{ "not $_[1]" }
],
[#Rule 25
'exp', 3,
sub
-#line 70 "./../pidl/expr.yp"
+#line 70 "expr.yp"
{ "$_[1] / $_[3]" }
],
[#Rule 26
'exp', 2,
sub
-#line 72 "./../pidl/expr.yp"
+#line 72 "expr.yp"
{ "-$_[2]" }
],
[#Rule 27
'exp', 2,
sub
-#line 74 "./../pidl/expr.yp"
+#line 74 "expr.yp"
{ "&$_[2]" }
],
[#Rule 28
'exp', 3,
sub
-#line 76 "./../pidl/expr.yp"
+#line 76 "expr.yp"
{ "$_[1]^$_[3]" }
],
[#Rule 29
'exp', 3,
sub
-#line 78 "./../pidl/expr.yp"
+#line 78 "expr.yp"
{ "($_[2])" }
],
[#Rule 30
'possible_pointer', 1,
sub
-#line 82 "./../pidl/expr.yp"
+#line 82 "expr.yp"
{ $_[0]->_Lookup($_[1]) }
],
[#Rule 31
'possible_pointer', 2,
sub
-#line 84 "./../pidl/expr.yp"
+#line 84 "expr.yp"
{ $_[0]->_Dereference($_[2]); "*$_[2]" }
],
[#Rule 32
'var', 1,
sub
-#line 88 "./../pidl/expr.yp"
+#line 88 "expr.yp"
{ $_[0]->_Use($_[1]) }
],
[#Rule 33
'var', 3,
sub
-#line 90 "./../pidl/expr.yp"
+#line 90 "expr.yp"
{ $_[0]->_Use("$_[1].$_[3]") }
],
[#Rule 34
'var', 3,
sub
-#line 92 "./../pidl/expr.yp"
+#line 92 "expr.yp"
{ "($_[2])" }
],
[#Rule 35
'var', 3,
sub
-#line 94 "./../pidl/expr.yp"
+#line 94 "expr.yp"
{ $_[0]->_Use("*$_[1]"); $_[1]."->".$_[3] }
],
[#Rule 36
'func', 4,
sub
-#line 99 "./../pidl/expr.yp"
+#line 99 "expr.yp"
{ "$_[1]($_[3])" }
],
[#Rule 37
'opt_args', 0,
sub
-#line 104 "./../pidl/expr.yp"
+#line 104 "expr.yp"
{ "" }
],
[#Rule 38
@@ -1349,7 +1349,7 @@ sub
[#Rule 42
'args', 3,
sub
-#line 118 "./../pidl/expr.yp"
+#line 118 "expr.yp"
{ "$_[1], $_[3]" }
]
],
@@ -1357,7 +1357,7 @@ sub
bless($self,$class);
}
-#line 121 "./../pidl/expr.yp"
+#line 121 "expr.yp"
package Parse::Pidl::Expr;
diff --git a/pidl/lib/Parse/Pidl/IDL.pm b/pidl/lib/Parse/Pidl/IDL.pm
index 1a3c59d35c..d4820ffe92 100644
--- a/pidl/lib/Parse/Pidl/IDL.pm
+++ b/pidl/lib/Parse/Pidl/IDL.pm
@@ -1065,11 +1065,9 @@ sub new {
DEFAULT => -16
},
{#State 125
- ACTIONS => {
- 'IDENTIFIER' => 26
- },
+ DEFAULT => -75,
GOTOS => {
- 'identifier' => 137
+ 'pointers' => 137
}
},
{#State 126
@@ -1165,11 +1163,11 @@ sub new {
},
{#State 137
ACTIONS => {
- "[" => 155
+ 'IDENTIFIER' => 26,
+ "*" => 152
},
- DEFAULT => -86,
GOTOS => {
- 'array_len' => 156
+ 'identifier' => 155
}
},
{#State 138
@@ -1178,7 +1176,7 @@ sub new {
{#State 139
DEFAULT => -68,
GOTOS => {
- 'union_elements' => 157
+ 'union_elements' => 156
}
},
{#State 140
@@ -1190,7 +1188,7 @@ sub new {
{#State 142
DEFAULT => -78,
GOTOS => {
- 'element_list1' => 158
+ 'element_list1' => 157
}
},
{#State 143
@@ -1201,9 +1199,9 @@ sub new {
'IDENTIFIER' => 26
},
GOTOS => {
- 'identifier' => 159,
- 'enum_element' => 160,
- 'enum_elements' => 161
+ 'identifier' => 158,
+ 'enum_element' => 159,
+ 'enum_elements' => 160
}
},
{#State 145
@@ -1221,10 +1219,10 @@ sub new {
},
DEFAULT => -57,
GOTOS => {
- 'identifier' => 164,
- 'bitmap_element' => 163,
- 'bitmap_elements' => 162,
- 'opt_bitmap_elements' => 165
+ 'identifier' => 163,
+ 'bitmap_element' => 162,
+ 'bitmap_elements' => 161,
+ 'opt_bitmap_elements' => 164
}
},
{#State 149
@@ -1233,19 +1231,19 @@ sub new {
{#State 150
ACTIONS => {
"," => -82,
- "void" => 169,
- "const" => 167,
+ "void" => 168,
+ "const" => 166,
")" => -82
},
DEFAULT => -80,
GOTOS => {
- 'optional_const' => 166,
- 'element_list2' => 168
+ 'optional_const' => 165,
+ 'element_list2' => 167
}
},
{#State 151
ACTIONS => {
- "[" => 155,
+ "[" => 169,
"=" => 171
},
GOTOS => {
@@ -1288,97 +1286,101 @@ sub new {
},
{#State 155
ACTIONS => {
- 'CONSTANT' => 48,
- 'TEXT' => 16,
- "]" => 172,
- 'IDENTIFIER' => 26
+ "[" => 169
},
- DEFAULT => -97,
+ DEFAULT => -86,
GOTOS => {
- 'identifier' => 50,
- 'anytext' => 173,
- 'text' => 51,
- 'constant' => 47
+ 'array_len' => 172
}
},
{#State 156
ACTIONS => {
- ";" => 174
- }
- },
- {#State 157
- ACTIONS => {
- "}" => 175
+ "}" => 173
},
DEFAULT => -89,
GOTOS => {
- 'optional_base_element' => 177,
- 'property_list' => 176
+ 'optional_base_element' => 175,
+ 'property_list' => 174
}
},
- {#State 158
+ {#State 157
ACTIONS => {
- "}" => 178
+ "}" => 176
},
DEFAULT => -89,
GOTOS => {
- 'base_element' => 179,
- 'property_list' => 180
+ 'base_element' => 177,
+ 'property_list' => 178
}
},
- {#State 159
+ {#State 158
ACTIONS => {
- "=" => 181
+ "=" => 179
},
DEFAULT => -49
},
- {#State 160
+ {#State 159
DEFAULT => -47
},
- {#State 161
+ {#State 160
ACTIONS => {
- "}" => 182,
- "," => 183
+ "}" => 180,
+ "," => 181
}
},
- {#State 162
+ {#State 161
ACTIONS => {
- "," => 184
+ "," => 182
},
DEFAULT => -58
},
- {#State 163
+ {#State 162
DEFAULT => -55
},
- {#State 164
+ {#State 163
ACTIONS => {
- "=" => 185
+ "=" => 183
}
},
- {#State 165
+ {#State 164
ACTIONS => {
- "}" => 186
+ "}" => 184
}
},
- {#State 166
+ {#State 165
DEFAULT => -89,
GOTOS => {
- 'base_element' => 187,
- 'property_list' => 180
+ 'base_element' => 185,
+ 'property_list' => 178
}
},
- {#State 167
+ {#State 166
DEFAULT => -81
},
- {#State 168
+ {#State 167
ACTIONS => {
- "," => 188,
- ")" => 189
+ "," => 186,
+ ")" => 187
}
},
- {#State 169
+ {#State 168
DEFAULT => -83
},
+ {#State 169
+ ACTIONS => {
+ 'CONSTANT' => 48,
+ 'TEXT' => 16,
+ "]" => 188,
+ 'IDENTIFIER' => 26
+ },
+ DEFAULT => -97,
+ GOTOS => {
+ 'identifier' => 50,
+ 'anytext' => 189,
+ 'text' => 51,
+ 'constant' => 47
+ }
+ },
{#State 170
ACTIONS => {
"=" => 190
@@ -1400,63 +1402,36 @@ sub new {
},
{#State 172
ACTIONS => {
- "[" => 155
- },
- DEFAULT => -86,
- GOTOS => {
- 'array_len' => 192
+ ";" => 192
}
},
{#State 173
- ACTIONS => {
- "-" => 69,
- ":" => 68,
- "?" => 70,
- "<" => 71,
- "+" => 73,
- "~" => 72,
- "&" => 75,
- "{" => 74,
- "/" => 76,
- "=" => 77,
- "|" => 79,
- "(" => 78,
- "*" => 80,
- "." => 81,
- "]" => 193,
- ">" => 82
- }
- },
- {#State 174
- DEFAULT => -29
- },
- {#State 175
DEFAULT => -70
},
- {#State 176
+ {#State 174
ACTIONS => {
"[" => 20
},
DEFAULT => -89,
GOTOS => {
- 'base_or_empty' => 194,
- 'base_element' => 195,
- 'empty_element' => 196,
- 'property_list' => 197
+ 'base_or_empty' => 193,
+ 'base_element' => 194,
+ 'empty_element' => 195,
+ 'property_list' => 196
}
},
- {#State 177
+ {#State 175
DEFAULT => -69
},
- {#State 178
+ {#State 176
DEFAULT => -60
},
- {#State 179
+ {#State 177
ACTIONS => {
- ";" => 198
+ ";" => 197
}
},
- {#State 180
+ {#State 178
ACTIONS => {
'IDENTIFIER' => 26,
"signed" => 100,
@@ -1474,12 +1449,12 @@ sub new {
'identifier' => 96,
'struct' => 62,
'enum' => 65,
- 'type' => 199,
+ 'type' => 198,
'union' => 67,
'sign' => 97
}
},
- {#State 181
+ {#State 179
ACTIONS => {
'CONSTANT' => 48,
'TEXT' => 16,
@@ -1488,33 +1463,33 @@ sub new {
DEFAULT => -97,
GOTOS => {
'identifier' => 50,
- 'anytext' => 200,
+ 'anytext' => 199,
'text' => 51,
'constant' => 47
}
},
- {#State 182
+ {#State 180
DEFAULT => -43
},
- {#State 183
+ {#State 181
ACTIONS => {
'IDENTIFIER' => 26
},
GOTOS => {
- 'identifier' => 159,
- 'enum_element' => 201
+ 'identifier' => 158,
+ 'enum_element' => 200
}
},
- {#State 184
+ {#State 182
ACTIONS => {
'IDENTIFIER' => 26
},
GOTOS => {
- 'identifier' => 164,
- 'bitmap_element' => 202
+ 'identifier' => 163,
+ 'bitmap_element' => 201
}
},
- {#State 185
+ {#State 183
ACTIONS => {
'CONSTANT' => 48,
'TEXT' => 16,
@@ -1523,29 +1498,58 @@ sub new {
DEFAULT => -97,
GOTOS => {
'identifier' => 50,
- 'anytext' => 203,
+ 'anytext' => 202,
'text' => 51,
'constant' => 47
}
},
- {#State 186
+ {#State 184
DEFAULT => -51
},
- {#State 187
+ {#State 185
DEFAULT => -84
},
- {#State 188
+ {#State 186
ACTIONS => {
- "const" => 167
+ "const" => 166
},
DEFAULT => -80,
GOTOS => {
- 'optional_const' => 204
+ 'optional_const' => 203
+ }
+ },
+ {#State 187
+ ACTIONS => {
+ ";" => 204
+ }
+ },
+ {#State 188
+ ACTIONS => {
+ "[" => 169
+ },
+ DEFAULT => -86,
+ GOTOS => {
+ 'array_len' => 205
}
},
{#State 189
ACTIONS => {
- ";" => 205
+ "-" => 69,
+ ":" => 68,
+ "?" => 70,
+ "<" => 71,
+ "+" => 73,
+ "~" => 72,
+ "&" => 75,
+ "{" => 74,
+ "/" => 76,
+ "=" => 77,
+ "|" => 79,
+ "(" => 78,
+ "*" => 80,
+ "." => 81,
+ "]" => 206,
+ ">" => 82
}
},
{#State 190
@@ -1557,7 +1561,7 @@ sub new {
DEFAULT => -97,
GOTOS => {
'identifier' => 50,
- 'anytext' => 206,
+ 'anytext' => 207,
'text' => 51,
'constant' => 47
}
@@ -1568,7 +1572,7 @@ sub new {
":" => 68,
"?" => 70,
"<" => 71,
- ";" => 207,
+ ";" => 208,
"+" => 73,
"~" => 72,
"&" => 75,
@@ -1583,29 +1587,20 @@ sub new {
}
},
{#State 192
- DEFAULT => -87
+ DEFAULT => -29
},
{#State 193
- ACTIONS => {
- "[" => 155
- },
- DEFAULT => -86,
- GOTOS => {
- 'array_len' => 208
- }
- },
- {#State 194
DEFAULT => -67
},
- {#State 195
+ {#State 194
ACTIONS => {
";" => 209
}
},
- {#State 196
+ {#State 195
DEFAULT => -66
},
- {#State 197
+ {#State 196
ACTIONS => {
'IDENTIFIER' => 26,
"signed" => 100,
@@ -1624,21 +1619,21 @@ sub new {
'identifier' => 96,
'struct' => 62,
'enum' => 65,
- 'type' => 199,
+ 'type' => 198,
'union' => 67,
'sign' => 97
}
},
- {#State 198
+ {#State 197
DEFAULT => -79
},
- {#State 199
+ {#State 198
DEFAULT => -75,
GOTOS => {
'pointers' => 211
}
},
- {#State 200
+ {#State 199
ACTIONS => {
"-" => 69,
":" => 68,
@@ -1658,13 +1653,13 @@ sub new {
},
DEFAULT => -50
},
- {#State 201
+ {#State 200
DEFAULT => -48
},
- {#State 202
+ {#State 201
DEFAULT => -56
},
- {#State 203
+ {#State 202
ACTIONS => {
"-" => 69,
":" => 68,
@@ -1684,23 +1679,35 @@ sub new {
},
DEFAULT => -59
},
- {#State 204
+ {#State 203
DEFAULT => -89,
GOTOS => {
'base_element' => 212,
- 'property_list' => 180
+ 'property_list' => 178
}
},
- {#State 205
+ {#State 204
DEFAULT => -28
},
+ {#State 205
+ DEFAULT => -87
+ },
{#State 206
ACTIONS => {
+ "[" => 169
+ },
+ DEFAULT => -86,
+ GOTOS => {
+ 'array_len' => 213
+ }
+ },
+ {#State 207
+ ACTIONS => {
"-" => 69,
":" => 68,
"?" => 70,
"<" => 71,
- ";" => 213,
+ ";" => 214,
"+" => 73,
"~" => 72,
"&" => 75,
@@ -1714,11 +1721,8 @@ sub new {
">" => 82
}
},
- {#State 207
- DEFAULT => -26
- },
{#State 208
- DEFAULT => -88
+ DEFAULT => -26
},
{#State 209
DEFAULT => -65
@@ -1732,25 +1736,28 @@ sub new {
"*" => 152
},
GOTOS => {
- 'identifier' => 214
+ 'identifier' => 215
}
},
{#State 212
DEFAULT => -85
},
{#State 213
- DEFAULT => -27
+ DEFAULT => -88
},
{#State 214
+ DEFAULT => -27
+ },
+ {#State 215
ACTIONS => {
- "[" => 155
+ "[" => 169
},
DEFAULT => -86,
GOTOS => {
- 'array_len' => 215
+ 'array_len' => 216
}
},
- {#State 215
+ {#State 216
DEFAULT => -74
}
],
@@ -1765,43 +1772,43 @@ sub new {
[#Rule 2
'idl', 2,
sub
-#line 20 "./../pidl/idl.yp"
+#line 20 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 3
'idl', 2,
sub
-#line 22 "./../pidl/idl.yp"
+#line 22 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 4
'idl', 2,
sub
-#line 24 "./../pidl/idl.yp"
+#line 24 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 5
'idl', 2,
sub
-#line 26 "./../pidl/idl.yp"
+#line 26 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 6
'idl', 2,
sub
-#line 28 "./../pidl/idl.yp"
+#line 28 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 7
'idl', 2,
sub
-#line 30 "./../pidl/idl.yp"
+#line 30 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 8
'import', 3,
sub
-#line 35 "./../pidl/idl.yp"
+#line 35 "idl.yp"
{{
"TYPE" => "IMPORT",
"PATHS" => $_[2],
@@ -1812,7 +1819,7 @@ sub
[#Rule 9
'include', 3,
sub
-#line 45 "./../pidl/idl.yp"
+#line 45 "idl.yp"
{{
"TYPE" => "INCLUDE",
"PATHS" => $_[2],
@@ -1823,7 +1830,7 @@ sub
[#Rule 10
'importlib', 3,
sub
-#line 55 "./../pidl/idl.yp"
+#line 55 "idl.yp"
{{
"TYPE" => "IMPORTLIB",
"PATHS" => $_[2],
@@ -1834,19 +1841,19 @@ sub
[#Rule 11
'commalist', 1,
sub
-#line 64 "./../pidl/idl.yp"
+#line 64 "idl.yp"
{ [ $_[1] ] }
],
[#Rule 12
'commalist', 3,
sub
-#line 66 "./../pidl/idl.yp"
+#line 66 "idl.yp"
{ push(@{$_[1]}, $_[3]); $_[1] }
],
[#Rule 13
'coclass', 7,
sub
-#line 71 "./../pidl/idl.yp"
+#line 71 "idl.yp"
{{
"TYPE" => "COCLASS",
"PROPERTIES" => $_[1],
@@ -1862,13 +1869,13 @@ sub
[#Rule 15
'interface_names', 4,
sub
-#line 84 "./../pidl/idl.yp"
+#line 84 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 16
'interface', 8,
sub
-#line 89 "./../pidl/idl.yp"
+#line 89 "idl.yp"
{{
"TYPE" => "INTERFACE",
"PROPERTIES" => $_[1],
@@ -1885,13 +1892,13 @@ sub
[#Rule 18
'base_interface', 2,
sub
-#line 103 "./../pidl/idl.yp"
+#line 103 "idl.yp"
{ $_[2] }
],
[#Rule 19
'cpp_quote', 4,
sub
-#line 109 "./../pidl/idl.yp"
+#line 109 "idl.yp"
{{
"TYPE" => "CPP_QUOTE",
"DATA" => $_[3],
@@ -1902,13 +1909,13 @@ sub
[#Rule 20
'definitions', 1,
sub
-#line 118 "./../pidl/idl.yp"
+#line 118 "idl.yp"
{ [ $_[1] ] }
],
[#Rule 21
'definitions', 2,
sub
-#line 120 "./../pidl/idl.yp"
+#line 120 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 22
@@ -1926,7 +1933,7 @@ sub
[#Rule 26
'const', 7,
sub
-#line 135 "./../pidl/idl.yp"
+#line 135 "idl.yp"
{{
"TYPE" => "CONST",
"DTYPE" => $_[2],
@@ -1940,7 +1947,7 @@ sub
[#Rule 27
'const', 8,
sub
-#line 146 "./../pidl/idl.yp"
+#line 146 "idl.yp"
{{
"TYPE" => "CONST",
"DTYPE" => $_[2],
@@ -1955,7 +1962,7 @@ sub
[#Rule 28
'function', 7,
sub
-#line 160 "./../pidl/idl.yp"
+#line 160 "idl.yp"
{{
"TYPE" => "FUNCTION",
"NAME" => $_[3],
@@ -1967,15 +1974,16 @@ sub
}}
],
[#Rule 29
- 'typedef', 6,
+ 'typedef', 7,
sub
-#line 173 "./../pidl/idl.yp"
+#line 173 "idl.yp"
{{
"TYPE" => "TYPEDEF",
"PROPERTIES" => $_[1],
- "NAME" => $_[4],
+ "NAME" => $_[5],
"DATA" => $_[3],
- "ARRAY_LEN" => $_[5],
+ "POINTERS" => $_[4],
+ "ARRAY_LEN" => $_[6],
"FILE" => $_[0]->YYData->{FILE},
"LINE" => $_[0]->YYData->{LINE},
}}
@@ -1998,7 +2006,7 @@ sub
[#Rule 35
'typedecl', 2,
sub
-#line 197 "./../pidl/idl.yp"
+#line 198 "idl.yp"
{ $_[1] }
],
[#Rule 36
@@ -2010,7 +2018,7 @@ sub
[#Rule 38
'existingtype', 2,
sub
-#line 207 "./../pidl/idl.yp"
+#line 208 "idl.yp"
{ ($_[1]?$_[1]:"signed") ." $_[2]" }
],
[#Rule 39
@@ -2025,13 +2033,13 @@ sub
[#Rule 42
'type', 1,
sub
-#line 217 "./../pidl/idl.yp"
+#line 218 "idl.yp"
{ "void" }
],
[#Rule 43
'enum_body', 3,
sub
-#line 221 "./../pidl/idl.yp"
+#line 222 "idl.yp"
{ $_[2] }
],
[#Rule 44
@@ -2043,7 +2051,7 @@ sub
[#Rule 46
'enum', 4,
sub
-#line 232 "./../pidl/idl.yp"
+#line 233 "idl.yp"
{{
"TYPE" => "ENUM",
"PROPERTIES" => $_[1],
@@ -2056,13 +2064,13 @@ sub
[#Rule 47
'enum_elements', 1,
sub
-#line 243 "./../pidl/idl.yp"
+#line 244 "idl.yp"
{ [ $_[1] ] }
],
[#Rule 48
'enum_elements', 3,
sub
-#line 245 "./../pidl/idl.yp"
+#line 246 "idl.yp"
{ push(@{$_[1]}, $_[3]); $_[1] }
],
[#Rule 49
@@ -2071,13 +2079,13 @@ sub
[#Rule 50
'enum_element', 3,
sub
-#line 251 "./../pidl/idl.yp"
+#line 252 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 51
'bitmap_body', 3,
sub
-#line 255 "./../pidl/idl.yp"
+#line 256 "idl.yp"
{ $_[2] }
],
[#Rule 52
@@ -2089,7 +2097,7 @@ sub
[#Rule 54
'bitmap', 4,
sub
-#line 266 "./../pidl/idl.yp"
+#line 267 "idl.yp"
{{
"TYPE" => "BITMAP",
"PROPERTIES" => $_[1],
@@ -2102,13 +2110,13 @@ sub
[#Rule 55
'bitmap_elements', 1,
sub
-#line 277 "./../pidl/idl.yp"
+#line 278 "idl.yp"
{ [ $_[1] ] }
],
[#Rule 56
'bitmap_elements', 3,
sub
-#line 279 "./../pidl/idl.yp"
+#line 280 "idl.yp"
{ push(@{$_[1]}, $_[3]); $_[1] }
],
[#Rule 57
@@ -2120,13 +2128,13 @@ sub
[#Rule 59
'bitmap_element', 3,
sub
-#line 289 "./../pidl/idl.yp"
+#line 290 "idl.yp"
{ "$_[1] ( $_[3] )" }
],
[#Rule 60
'struct_body', 3,
sub
-#line 293 "./../pidl/idl.yp"
+#line 294 "idl.yp"
{ $_[2] }
],
[#Rule 61
@@ -2138,7 +2146,7 @@ sub
[#Rule 63
'struct', 4,
sub
-#line 304 "./../pidl/idl.yp"
+#line 305 "idl.yp"
{{
"TYPE" => "STRUCT",
"PROPERTIES" => $_[1],
@@ -2151,7 +2159,7 @@ sub
[#Rule 64
'empty_element', 2,
sub
-#line 316 "./../pidl/idl.yp"
+#line 317 "idl.yp"
{{
"NAME" => "",
"TYPE" => "EMPTY",
@@ -2171,7 +2179,7 @@ sub
[#Rule 67
'optional_base_element', 2,
sub
-#line 333 "./../pidl/idl.yp"
+#line 334 "idl.yp"
{ $_[2]->{PROPERTIES} = FlattenHash([$_[1],$_[2]->{PROPERTIES}]); $_[2] }
],
[#Rule 68
@@ -2180,13 +2188,13 @@ sub
[#Rule 69
'union_elements', 2,
sub
-#line 339 "./../pidl/idl.yp"
+#line 340 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 70
'union_body', 3,
sub
-#line 343 "./../pidl/idl.yp"
+#line 344 "idl.yp"
{ $_[2] }
],
[#Rule 71
@@ -2198,7 +2206,7 @@ sub
[#Rule 73
'union', 4,
sub
-#line 354 "./../pidl/idl.yp"
+#line 355 "idl.yp"
{{
"TYPE" => "UNION",
"PROPERTIES" => $_[1],
@@ -2211,7 +2219,7 @@ sub
[#Rule 74
'base_element', 5,
sub
-#line 366 "./../pidl/idl.yp"
+#line 367 "idl.yp"
{{
"NAME" => $_[4],
"TYPE" => $_[2],
@@ -2225,24 +2233,47 @@ sub
[#Rule 75
'pointers', 0,
sub
-#line 379 "./../pidl/idl.yp"
+#line 380 "idl.yp"
{ 0 }
],
[#Rule 76
'pointers', 2,
sub
-#line 381 "./../pidl/idl.yp"
+#line 382 "idl.yp"
{ $_[1]+1 }
],
[#Rule 77
'pipe', 3,
sub
-#line 386 "./../pidl/idl.yp"
+#line 387 "idl.yp"
{{
"TYPE" => "PIPE",
"PROPERTIES" => $_[1],
- "NAME" => $_[4],
- "DATA" => $_[3],
+ "NAME" => undef,
+ "DATA" => {
+ "TYPE" => "STRUCT",
+ "PROPERTIES" => $_[1],
+ "NAME" => undef,
+ "ELEMENTS" => [{
+ "NAME" => "count",
+ "PROPERTIES" => $_[1],
+ "POINTERS" => 0,
+ "ARRAY_LEN" => [],
+ "TYPE" => "uint3264",
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ },{
+ "NAME" => "array",
+ "PROPERTIES" => $_[1],
+ "POINTERS" => 0,
+ "ARRAY_LEN" => [ "count" ],
+ "TYPE" => $_[3],
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ }],
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ },
"FILE" => $_[0]->YYData->{FILE},
"LINE" => $_[0]->YYData->{LINE},
}}
@@ -2250,13 +2281,13 @@ sub
[#Rule 78
'element_list1', 0,
sub
-#line 398 "./../pidl/idl.yp"
+#line 422 "idl.yp"
{ [] }
],
[#Rule 79
'element_list1', 3,
sub
-#line 400 "./../pidl/idl.yp"
+#line 424 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 80
@@ -2274,13 +2305,13 @@ sub
[#Rule 84
'element_list2', 2,
sub
-#line 414 "./../pidl/idl.yp"
+#line 438 "idl.yp"
{ [ $_[2] ] }
],
[#Rule 85
'element_list2', 4,
sub
-#line 416 "./../pidl/idl.yp"
+#line 440 "idl.yp"
{ push(@{$_[1]}, $_[4]); $_[1] }
],
[#Rule 86
@@ -2289,13 +2320,13 @@ sub
[#Rule 87
'array_len', 3,
sub
-#line 422 "./../pidl/idl.yp"
+#line 446 "idl.yp"
{ push(@{$_[3]}, "*"); $_[3] }
],
[#Rule 88
'array_len', 4,
sub
-#line 424 "./../pidl/idl.yp"
+#line 448 "idl.yp"
{ push(@{$_[4]}, "$_[2]"); $_[4] }
],
[#Rule 89
@@ -2304,31 +2335,31 @@ sub
[#Rule 90
'property_list', 4,
sub
-#line 430 "./../pidl/idl.yp"
+#line 454 "idl.yp"
{ FlattenHash([$_[1],$_[3]]); }
],
[#Rule 91
'properties', 1,
sub
-#line 434 "./../pidl/idl.yp"
+#line 458 "idl.yp"
{ $_[1] }
],
[#Rule 92
'properties', 3,
sub
-#line 436 "./../pidl/idl.yp"
+#line 460 "idl.yp"
{ FlattenHash([$_[1], $_[3]]); }
],
[#Rule 93
'property', 1,
sub
-#line 440 "./../pidl/idl.yp"
+#line 464 "idl.yp"
{{ "$_[1]" => "1" }}
],
[#Rule 94
'property', 4,
sub
-#line 442 "./../pidl/idl.yp"
+#line 466 "idl.yp"
{{ "$_[1]" => "$_[3]" }}
],
[#Rule 95
@@ -2337,13 +2368,13 @@ sub
[#Rule 96
'commalisttext', 3,
sub
-#line 448 "./../pidl/idl.yp"
+#line 472 "idl.yp"
{ "$_[1],$_[3]" }
],
[#Rule 97
'anytext', 0,
sub
-#line 453 "./../pidl/idl.yp"
+#line 477 "idl.yp"
{ "" }
],
[#Rule 98
@@ -2358,91 +2389,91 @@ sub
[#Rule 101
'anytext', 3,
sub
-#line 461 "./../pidl/idl.yp"
+#line 485 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 102
'anytext', 3,
sub
-#line 463 "./../pidl/idl.yp"
+#line 487 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 103
'anytext', 3,
sub
-#line 465 "./../pidl/idl.yp"
+#line 489 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 104
'anytext', 3,
sub
-#line 467 "./../pidl/idl.yp"
+#line 491 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 105
'anytext', 3,
sub
-#line 469 "./../pidl/idl.yp"
+#line 493 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 106
'anytext', 3,
sub
-#line 471 "./../pidl/idl.yp"
+#line 495 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 107
'anytext', 3,
sub
-#line 473 "./../pidl/idl.yp"
+#line 497 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 108
'anytext', 3,
sub
-#line 475 "./../pidl/idl.yp"
+#line 499 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 109
'anytext', 3,
sub
-#line 477 "./../pidl/idl.yp"
+#line 501 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 110
'anytext', 3,
sub
-#line 479 "./../pidl/idl.yp"
+#line 503 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 111
'anytext', 3,
sub
-#line 481 "./../pidl/idl.yp"
+#line 505 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 112
'anytext', 3,
sub
-#line 483 "./../pidl/idl.yp"
+#line 507 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 113
'anytext', 3,
sub
-#line 485 "./../pidl/idl.yp"
+#line 509 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 114
'anytext', 5,
sub
-#line 487 "./../pidl/idl.yp"
+#line 511 "idl.yp"
{ "$_[1]$_[2]$_[3]$_[4]$_[5]" }
],
[#Rule 115
'anytext', 5,
sub
-#line 489 "./../pidl/idl.yp"
+#line 513 "idl.yp"
{ "$_[1]$_[2]$_[3]$_[4]$_[5]" }
],
[#Rule 116
@@ -2460,7 +2491,7 @@ sub
[#Rule 120
'text', 1,
sub
-#line 507 "./../pidl/idl.yp"
+#line 531 "idl.yp"
{ "\"$_[1]\"" }
],
[#Rule 121
@@ -2474,7 +2505,7 @@ sub
bless($self,$class);
}
-#line 519 "./../pidl/idl.yp"
+#line 543 "idl.yp"
use Parse::Pidl qw(error);
@@ -2612,11 +2643,17 @@ sub parse_file($$)
my $saved_delim = $/;
undef $/;
my $cpp = $ENV{CPP};
+ my $options = "";
if (! defined $cpp) {
- $cpp = "cpp";
+ if (defined $ENV{CC}) {
+ $cpp = "$ENV{CC}";
+ $options = "-E";
+ } else {
+ $cpp = "cpp";
+ }
}
my $includes = join('',map { " -I$_" } @$incdirs);
- my $data = `$cpp -D__PIDL__$includes -xc $filename`;
+ my $data = `$cpp $options -D__PIDL__$includes -xc "$filename"`;
$/ = $saved_delim;
return parse_string($data, $filename);
diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm
index fbd54693bc..d91c324b53 100644
--- a/pidl/lib/Parse/Pidl/NDR.pm
+++ b/pidl/lib/Parse/Pidl/NDR.pm
@@ -34,12 +34,12 @@ require Exporter;
use vars qw($VERSION);
$VERSION = '0.01';
@ISA = qw(Exporter);
-@EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsString);
+@EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe ContainsString);
@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar ParseType can_contain_deferred is_charset_array);
use strict;
use Parse::Pidl qw(warning fatal);
-use Parse::Pidl::Typelist qw(hasType getType expandAlias);
+use Parse::Pidl::Typelist qw(hasType getType typeIs expandAlias mapScalarType is_fixed_size_scalar);
use Parse::Pidl::Util qw(has_property property_matches);
# Alignment of the built-in scalar types
@@ -54,6 +54,8 @@ my $scalar_alignment = {
'uint1632' => 3,
'int32' => 4,
'uint32' => 4,
+ 'int3264' => 5,
+ 'uint3264' => 5,
'hyper' => 8,
'double' => 8,
'pointer' => 8,
@@ -64,20 +66,26 @@ my $scalar_alignment = {
'string' => 4,
'string_array' => 4, #???
'time_t' => 4,
+ 'uid_t' => 8,
+ 'gid_t' => 8,
'NTTIME' => 4,
'NTTIME_1sec' => 4,
'NTTIME_hyper' => 8,
'WERROR' => 4,
'NTSTATUS' => 4,
'COMRESULT' => 4,
+ 'dns_string' => 4,
'nbt_string' => 4,
'wrepl_nbt_name' => 4,
- 'ipv4address' => 4
+ 'ipv4address' => 4,
+ 'ipv6address' => 4, #16?
+ 'dnsp_name' => 1,
+ 'dnsp_string' => 1
};
-sub GetElementLevelTable($$)
+sub GetElementLevelTable($$$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
my $order = [];
my $is_deferred = 0;
@@ -101,12 +109,57 @@ sub GetElementLevelTable($$)
if (has_property($e, "out")) {
my $needptrs = 1;
- if (has_property($e, "string")) { $needptrs++; }
+ if (has_property($e, "string") and not has_property($e, "in")) { $needptrs++; }
if ($#bracket_array >= 0) { $needptrs = 0; }
warning($e, "[out] argument `$e->{NAME}' not a pointer") if ($needptrs > $e->{POINTERS});
}
+ my $allow_pipe = ($e->{PARENT}->{TYPE} eq "FUNCTION");
+ my $is_pipe = typeIs($e->{TYPE}, "PIPE");
+
+ if ($is_pipe) {
+ if (not $allow_pipe) {
+ fatal($e, "argument `$e->{NAME}' is a pipe and not allowed on $e->{PARENT}->{TYPE}");
+ }
+
+ if ($e->{POINTERS} > 1) {
+ fatal($e, "$e->{POINTERS} are not allowed on pipe element $e->{NAME}");
+ }
+
+ if ($e->{POINTERS} < 0) {
+ fatal($e, "pipe element $e->{NAME} needs pointer");
+ }
+
+ if ($e->{POINTERS} == 1 and pointer_type($e) ne "ref") {
+ fatal($e, "pointer should be 'ref' on pipe element $e->{NAME}");
+ }
+
+ if (scalar(@size_is) > 0) {
+ fatal($e, "size_is() on pipe element");
+ }
+
+ if (scalar(@length_is) > 0) {
+ fatal($e, "length_is() on pipe element");
+ }
+
+ if (scalar(@bracket_array) > 0) {
+ fatal($e, "brackets on pipe element");
+ }
+
+ if (defined(has_property($e, "subcontext"))) {
+ fatal($e, "subcontext on pipe element");
+ }
+
+ if (has_property($e, "switch_is")) {
+ fatal($e, "switch_is on pipe element");
+ }
+
+ if (can_contain_deferred($e->{TYPE})) {
+ fatal($e, "$e->{TYPE} can_contain_deferred - not allowed on pipe element");
+ }
+ }
+
# Parse the [][][][] style array stuff
for my $i (0 .. $#bracket_array) {
my $d = $bracket_array[$#bracket_array - $i];
@@ -122,6 +175,10 @@ sub GetElementLevelTable($$)
if ($d eq "*") {
$is_conformant = 1;
if ($size = shift @size_is) {
+ if ($e->{POINTERS} < 1 and has_property($e, "string")) {
+ $is_string = 1;
+ delete($e->{PROPERTIES}->{string});
+ }
} elsif ((scalar(@size_is) == 0) and has_property($e, "string")) {
$is_string = 1;
delete($e->{PROPERTIES}->{string});
@@ -247,6 +304,19 @@ sub GetElementLevelTable($$)
}
}
+ if ($is_pipe) {
+ push (@$order, {
+ TYPE => "PIPE",
+ IS_DEFERRED => 0,
+ CONTAINS_DEFERRED => 0,
+ });
+
+ my $i = 0;
+ foreach (@$order) { $_->{LEVEL_INDEX} = $i; $i+=1; }
+
+ return $order;
+ }
+
if (defined(has_property($e, "subcontext"))) {
my $hdr_size = has_property($e, "subcontext");
my $subsize = has_property($e, "subcontext_size");
@@ -297,9 +367,9 @@ sub GetElementLevelTable($$)
return $order;
}
-sub GetTypedefLevelTable($$$)
+sub GetTypedefLevelTable($$$$)
{
- my ($e, $data, $pointer_default) = @_;
+ my ($e, $data, $pointer_default, $ms_union) = @_;
my $order = [];
@@ -349,6 +419,7 @@ sub pointer_type($)
return "sptr" if (has_property($e, "sptr"));
return "unique" if (has_property($e, "unique"));
return "relative" if (has_property($e, "relative"));
+ return "relative_short" if (has_property($e, "relative_short"));
return "ignore" if (has_property($e, "ignore"));
return undef;
@@ -406,6 +477,8 @@ sub align_type($)
if ($dt->{TYPE} eq "TYPEDEF") {
return align_type($dt->{DATA});
+ } elsif ($dt->{TYPE} eq "CONFORMANCE") {
+ return $dt->{DATA}->{ALIGN};
} elsif ($dt->{TYPE} eq "ENUM") {
return align_type(Parse::Pidl::Typelist::enum_type_fn($dt));
} elsif ($dt->{TYPE} eq "BITMAP") {
@@ -414,35 +487,37 @@ sub align_type($)
# Struct/union without body: assume 4
return 4 unless (defined($dt->{ELEMENTS}));
return find_largest_alignment($dt);
+ } elsif (($dt->{TYPE} eq "PIPE")) {
+ return 5;
}
die("Unknown data type type $dt->{TYPE}");
}
-sub ParseElement($$)
+sub ParseElement($$$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
$e->{TYPE} = expandAlias($e->{TYPE});
if (ref($e->{TYPE}) eq "HASH") {
- $e->{TYPE} = ParseType($e->{TYPE}, $pointer_default);
+ $e->{TYPE} = ParseType($e->{TYPE}, $pointer_default, $ms_union);
}
return {
NAME => $e->{NAME},
TYPE => $e->{TYPE},
PROPERTIES => $e->{PROPERTIES},
- LEVELS => GetElementLevelTable($e, $pointer_default),
+ LEVELS => GetElementLevelTable($e, $pointer_default, $ms_union),
REPRESENTATION_TYPE => ($e->{PROPERTIES}->{represent_as} or $e->{TYPE}),
ALIGN => align_type($e->{TYPE}),
ORIGINAL => $e
};
}
-sub ParseStruct($$)
+sub ParseStruct($$$)
{
- my ($struct, $pointer_default) = @_;
+ my ($struct, $pointer_default, $ms_union) = @_;
my @elements = ();
my $surrounding = undef;
@@ -460,7 +535,7 @@ sub ParseStruct($$)
foreach my $x (@{$struct->{ELEMENTS}})
{
- my $e = ParseElement($x, $pointer_default);
+ my $e = ParseElement($x, $pointer_default, $ms_union);
if ($x != $struct->{ELEMENTS}[-1] and
$e->{LEVELS}[0]->{IS_SURROUNDING}) {
fatal($x, "conformant member not at end of struct");
@@ -497,8 +572,10 @@ sub ParseStruct($$)
sub ParseUnion($$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
my @elements = ();
+ my $is_ms_union = $ms_union;
+ $is_ms_union = 1 if has_property($e, "ms_union");
my $hasdefault = 0;
my $switch_type = has_property($e, "switch_type");
unless (defined($switch_type)) { $switch_type = "uint32"; }
@@ -511,6 +588,7 @@ sub ParseUnion($$)
ELEMENTS => undef,
PROPERTIES => $e->{PROPERTIES},
HAS_DEFAULT => $hasdefault,
+ IS_MS_UNION => $is_ms_union,
ORIGINAL => $e,
ALIGN => undef
} unless defined($e->{ELEMENTS});
@@ -523,7 +601,7 @@ sub ParseUnion($$)
if ($x->{TYPE} eq "EMPTY") {
$t = { TYPE => "EMPTY" };
} else {
- $t = ParseElement($x, $pointer_default);
+ $t = ParseElement($x, $pointer_default, $ms_union);
}
if (has_property($x, "default")) {
$t->{CASE} = "default";
@@ -548,6 +626,7 @@ sub ParseUnion($$)
ELEMENTS => \@elements,
PROPERTIES => $e->{PROPERTIES},
HAS_DEFAULT => $hasdefault,
+ IS_MS_UNION => $is_ms_union,
ORIGINAL => $e,
ALIGN => $align
};
@@ -555,7 +634,7 @@ sub ParseUnion($$)
sub ParseEnum($$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
return {
TYPE => "ENUM",
@@ -567,9 +646,9 @@ sub ParseEnum($$)
};
}
-sub ParseBitmap($$)
+sub ParseBitmap($$$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
return {
TYPE => "BITMAP",
@@ -581,9 +660,60 @@ sub ParseBitmap($$)
};
}
-sub ParseType($$)
+sub ParsePipe($$$)
{
- my ($d, $pointer_default) = @_;
+ my ($pipe, $pointer_default, $ms_union) = @_;
+
+ my $pname = $pipe->{NAME};
+ $pname = $pipe->{PARENT}->{NAME} unless defined $pname;
+
+ if (not defined($pipe->{PROPERTIES})
+ and defined($pipe->{PARENT}->{PROPERTIES})) {
+ $pipe->{PROPERTIES} = $pipe->{PARENT}->{PROPERTIES};
+ }
+
+ if (ref($pipe->{DATA}) eq "HASH") {
+ if (not defined($pipe->{DATA}->{PROPERTIES})
+ and defined($pipe->{PROPERTIES})) {
+ $pipe->{DATA}->{PROPERTIES} = $pipe->{PROPERTIES};
+ }
+ }
+
+ my $struct = ParseStruct($pipe->{DATA}, $pointer_default, $ms_union);
+ $struct->{ALIGN} = 5;
+ $struct->{NAME} = "$pname\_chunk";
+
+ # 'count' is element [0] and 'array' [1]
+ my $e = $struct->{ELEMENTS}[1];
+ # level [0] is of type "ARRAY"
+ my $l = $e->{LEVELS}[1];
+
+ # here we check that pipe elements have a fixed size type
+ while (defined($l)) {
+ my $cl = $l;
+ $l = GetNextLevel($e, $cl);
+ if ($cl->{TYPE} ne "DATA") {
+ fatal($pipe, el_name($pipe) . ": pipe contains non DATA level");
+ }
+
+ # for now we only support scalars
+ next if is_fixed_size_scalar($cl->{DATA_TYPE});
+
+ fatal($pipe, el_name($pipe) . ": pipe contains non fixed size type[$cl->{DATA_TYPE}]");
+ }
+
+ return {
+ TYPE => "PIPE",
+ NAME => $pipe->{NAME},
+ DATA => $struct,
+ PROPERTIES => $pipe->{PROPERTIES},
+ ORIGINAL => $pipe,
+ };
+}
+
+sub ParseType($$$)
+{
+ my ($d, $pointer_default, $ms_union) = @_;
my $data = {
STRUCT => \&ParseStruct,
@@ -591,27 +721,35 @@ sub ParseType($$)
ENUM => \&ParseEnum,
BITMAP => \&ParseBitmap,
TYPEDEF => \&ParseTypedef,
- }->{$d->{TYPE}}->($d, $pointer_default);
+ PIPE => \&ParsePipe,
+ }->{$d->{TYPE}}->($d, $pointer_default, $ms_union);
return $data;
}
sub ParseTypedef($$)
{
- my ($d, $pointer_default) = @_;
+ my ($d, $pointer_default, $ms_union) = @_;
- if (defined($d->{DATA}->{PROPERTIES}) && !defined($d->{PROPERTIES})) {
- $d->{PROPERTIES} = $d->{DATA}->{PROPERTIES};
- }
+ my $data;
+
+ if (ref($d->{DATA}) eq "HASH") {
+ if (defined($d->{DATA}->{PROPERTIES})
+ and not defined($d->{PROPERTIES})) {
+ $d->{PROPERTIES} = $d->{DATA}->{PROPERTIES};
+ }
- my $data = ParseType($d->{DATA}, $pointer_default);
- $data->{ALIGN} = align_type($d->{NAME});
+ $data = ParseType($d->{DATA}, $pointer_default, $ms_union);
+ $data->{ALIGN} = align_type($d->{NAME});
+ } else {
+ $data = getType($d->{DATA});
+ }
return {
NAME => $d->{NAME},
TYPE => $d->{TYPE},
PROPERTIES => $d->{PROPERTIES},
- LEVELS => GetTypedefLevelTable($d, $data, $pointer_default),
+ LEVELS => GetTypedefLevelTable($d, $data, $pointer_default, $ms_union),
DATA => $data,
ORIGINAL => $d
};
@@ -624,9 +762,9 @@ sub ParseConst($$)
return $d;
}
-sub ParseFunction($$$)
+sub ParseFunction($$$$)
{
- my ($ndr,$d,$opnum) = @_;
+ my ($ndr,$d,$opnum,$ms_union) = @_;
my @elements = ();
my $rettype = undef;
my $thisopnum = undef;
@@ -639,7 +777,7 @@ sub ParseFunction($$$)
}
foreach my $x (@{$d->{ELEMENTS}}) {
- my $e = ParseElement($x, $ndr->{PROPERTIES}->{pointer_default});
+ my $e = ParseElement($x, $ndr->{PROPERTIES}->{pointer_default}, $ms_union);
push (@{$e->{DIRECTION}}, "in") if (has_property($x, "in"));
push (@{$e->{DIRECTION}}, "out") if (has_property($x, "out"));
@@ -650,14 +788,10 @@ sub ParseFunction($$$)
$rettype = expandAlias($d->{RETURN_TYPE});
}
- my $async = 0;
- if (has_property($d, "async")) { $async = 1; }
-
return {
NAME => $d->{NAME},
TYPE => "FUNCTION",
OPNUM => $thisopnum,
- ASYNC => $async,
RETURN_TYPE => $rettype,
PROPERTIES => $d->{PROPERTIES},
ELEMENTS => \@elements,
@@ -704,6 +838,8 @@ sub ParseInterface($)
my @endpoints;
my $opnum = 0;
my $version;
+ my $ms_union = 0;
+ $ms_union = 1 if has_property($idl, "ms_union");
if (not has_property($idl, "pointer_default")) {
# MIDL defaults to "ptr" in DCE compatible mode (/osf)
@@ -713,11 +849,11 @@ sub ParseInterface($)
foreach my $d (@{$idl->{DATA}}) {
if ($d->{TYPE} eq "FUNCTION") {
- push (@functions, ParseFunction($idl, $d, \$opnum));
+ push (@functions, ParseFunction($idl, $d, \$opnum, $ms_union));
} elsif ($d->{TYPE} eq "CONST") {
push (@consts, ParseConst($idl, $d));
} else {
- push (@types, ParseType($d, $idl->{PROPERTIES}->{pointer_default}));
+ push (@types, ParseType($d, $idl->{PROPERTIES}->{pointer_default}, $ms_union));
FindNestedTypes(\@types, $d);
}
}
@@ -829,6 +965,20 @@ sub ContainsDeferred($$)
return 0;
}
+sub ContainsPipe($$)
+{
+ my ($e,$l) = @_;
+
+ return 1 if ($l->{TYPE} eq "PIPE");
+
+ while ($l = GetNextLevel($e,$l))
+ {
+ return 1 if ($l->{TYPE} eq "PIPE");
+ }
+
+ return 0;
+}
+
sub el_name($)
{
my $e = shift;
@@ -877,7 +1027,8 @@ my %property_list = (
"helper" => ["INTERFACE"],
"pyhelper" => ["INTERFACE"],
"authservice" => ["INTERFACE"],
- "restricted" => ["INTERFACE"],
+ "restricted" => ["INTERFACE"],
+ "no_srv_register" => ["INTERFACE"],
# dcom
"object" => ["INTERFACE"],
@@ -890,33 +1041,35 @@ my %property_list = (
"noopnum" => ["FUNCTION"],
"in" => ["ELEMENT"],
"out" => ["ELEMENT"],
- "async" => ["FUNCTION"],
# pointer
- "ref" => ["ELEMENT"],
- "ptr" => ["ELEMENT"],
- "unique" => ["ELEMENT"],
+ "ref" => ["ELEMENT", "TYPEDEF"],
+ "ptr" => ["ELEMENT", "TYPEDEF"],
+ "unique" => ["ELEMENT", "TYPEDEF"],
"ignore" => ["ELEMENT"],
- "relative" => ["ELEMENT"],
- "null_is_ffffffff" => ["ELEMENT"],
+ "relative" => ["ELEMENT", "TYPEDEF"],
+ "relative_short" => ["ELEMENT", "TYPEDEF"],
+ "null_is_ffffffff" => ["ELEMENT"],
"relative_base" => ["TYPEDEF", "STRUCT", "UNION"],
"gensize" => ["TYPEDEF", "STRUCT", "UNION"],
"value" => ["ELEMENT"],
- "flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
+ "flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
# generic
- "public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "nopush" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "nopull" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
+ "public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
+ "nopush" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
+ "nopull" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
"nosize" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "noprint" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "ELEMENT"],
+ "noprint" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "ELEMENT", "PIPE"],
+ "nopython" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
"todo" => ["FUNCTION"],
# union
"switch_is" => ["ELEMENT"],
"switch_type" => ["ELEMENT", "UNION"],
"nodiscriminant" => ["UNION"],
+ "ms_union" => ["INTERFACE", "UNION"],
"case" => ["ELEMENT"],
"default" => ["ELEMENT"],
@@ -1006,13 +1159,13 @@ sub ValidElement($)
my $discriminator_type = has_property($type->{DATA}, "switch_type");
$discriminator_type = "uint32" unless defined ($discriminator_type);
- my $t1 = mapToScalar($discriminator_type);
+ my $t1 = mapScalarType(mapToScalar($discriminator_type));
if (not defined($t1)) {
fatal($e, el_name($e) . ": unable to map discriminator type '$discriminator_type' to scalar");
}
- my $t2 = mapToScalar($e2->{TYPE});
+ my $t2 = mapScalarType(mapToScalar($e2->{TYPE}));
if (not defined($t2)) {
fatal($e, el_name($e) . ": unable to map variable used for switch_is() to scalar");
}
@@ -1055,6 +1208,7 @@ sub ValidElement($)
has_property($e, "ptr") or
has_property($e, "unique") or
has_property($e, "relative") or
+ has_property($e, "relative_short") or
has_property($e, "ref"))) {
fatal($e, el_name($e) . " : pointer properties on non-pointer element\n");
}
@@ -1136,11 +1290,16 @@ sub ValidUnion($)
sub ValidPipe($)
{
my ($pipe) = @_;
- my $data = $pipe->{DATA};
+ my $struct = $pipe->{DATA};
ValidProperties($pipe, "PIPE");
- fatal($pipe, $pipe->{NAME} . ": 'pipe' is not yet supported by pidl");
+ $struct->{PARENT} = $pipe;
+
+ $struct->{FILE} = $pipe->{FILE} unless defined($struct->{FILE});
+ $struct->{LINE} = $pipe->{LINE} unless defined($struct->{LINE});
+
+ ValidType($struct);
}
#####################################################################
@@ -1152,12 +1311,14 @@ sub ValidTypedef($)
ValidProperties($typedef, "TYPEDEF");
+ return unless (ref($data) eq "HASH");
+
$data->{PARENT} = $typedef;
$data->{FILE} = $typedef->{FILE} unless defined($data->{FILE});
$data->{LINE} = $typedef->{LINE} unless defined($data->{LINE});
- ValidType($data) if (ref($data) eq "HASH");
+ ValidType($data);
}
#####################################################################
diff --git a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
index 17384241c9..8142b35699 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
@@ -9,11 +9,13 @@ package Parse::Pidl::Samba3::ClientNDR;
use Exporter;
@ISA = qw(Exporter);
-@EXPORT_OK = qw(ParseFunction $res $res_hdr ParseOutputArgument);
+@EXPORT_OK = qw(ParseFunction $res $res_hdr);
use strict;
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(ContainsPipe);
+use Parse::Pidl::Typelist qw(mapTypeName);
use Parse::Pidl::Samba4 qw(DeclLong);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
@@ -85,78 +87,6 @@ sub ParseInvalidResponse($$)
}
}
-sub ParseOutputArgument($$$;$$$)
-{
- my ($self, $fn, $e, $r, $o, $invalid_response_type) = @_;
- my $level = 0;
- $r = "r." unless defined($r);
- $o = "" unless defined($o);
- $invalid_response_type = "sync" unless defined($invalid_response_type);
-
- if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY") {
- $self->pidl("return NT_STATUS_NOT_SUPPORTED;");
- error($e->{ORIGINAL}, "[out] argument is not a pointer or array");
- return;
- }
-
- if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") {
- $level = 1;
- if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") {
- $self->pidl("if ($o$e->{NAME} && ${r}out.$e->{NAME}) {");
- $self->indent;
- }
- }
-
- if ($e->{LEVELS}[$level]->{TYPE} eq "ARRAY") {
- # This is a call to GenerateFunctionInEnv intentionally.
- # Since the data is being copied into a user-provided data
- # structure, the user should be able to know the size beforehand
- # to allocate a structure of the right size.
- my $in_env = GenerateFunctionInEnv($fn, $r);
- my $out_env = GenerateFunctionOutEnv($fn, $r);
- my $l = $e->{LEVELS}[$level];
- unless (defined($l->{SIZE_IS})) {
- $self->pidl('#error No size known for [out] array `$e->{NAME}');
- error($e->{ORIGINAL}, "no size known for [out] array `$e->{NAME}'");
- } else {
- my $in_size_is = ParseExpr($l->{SIZE_IS}, $in_env, $e->{ORIGINAL});
- my $out_size_is = ParseExpr($l->{SIZE_IS}, $out_env, $e->{ORIGINAL});
- my $out_length_is = $out_size_is;
- if (defined($l->{LENGTH_IS})) {
- $out_length_is = ParseExpr($l->{LENGTH_IS}, $out_env, $e->{ORIGINAL});
- }
- if ($out_size_is ne $in_size_is) {
- $self->pidl("if (($out_size_is) > ($in_size_is)) {");
- $self->indent;
- $self->ParseInvalidResponse($invalid_response_type);
- $self->deindent;
- $self->pidl("}");
- }
- if ($out_length_is ne $out_size_is) {
- $self->pidl("if (($out_length_is) > ($out_size_is)) {");
- $self->indent;
- $self->ParseInvalidResponse($invalid_response_type);
- $self->deindent;
- $self->pidl("}");
- }
- if (has_property($e, "charset")) {
- $self->pidl("memcpy(discard_const_p(uint8_t *, $o$e->{NAME}), ${r}out.$e->{NAME}, ($out_length_is) * sizeof(*$o$e->{NAME}));");
- } else {
- $self->pidl("memcpy($o$e->{NAME}, ${r}out.$e->{NAME}, ($out_length_is) * sizeof(*$o$e->{NAME}));");
- }
- }
- } else {
- $self->pidl("*$o$e->{NAME} = *${r}out.$e->{NAME};");
- }
-
- if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") {
- if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") {
- $self->deindent;
- $self->pidl("}");
- }
- }
-}
-
sub ParseFunctionAsyncState($$$)
{
my ($self, $if, $fn) = @_;
@@ -166,10 +96,10 @@ sub ParseFunctionAsyncState($$$)
$self->pidl("$state_str {");
$self->indent;
- $self->pidl("struct $fn->{NAME} orig;");
- $self->pidl("struct $fn->{NAME} tmp;");
$self->pidl("TALLOC_CTX *out_mem_ctx;");
- $self->pidl("NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);");
+ if (defined($fn->{RETURN_TYPE})) {
+ $self->pidl(mapTypeName($fn->{RETURN_TYPE}). " result;");
+ }
$self->deindent;
$self->pidl("};");
$self->pidl("");
@@ -215,32 +145,14 @@ sub ParseFunctionAsyncSend($$$)
$self->deindent;
$self->pidl("}");
$self->pidl("state->out_mem_ctx = NULL;");
- $self->pidl("state->dispatch_recv = cli->dispatch_recv;");
- $self->pidl("");
-
- $self->pidl("/* In parameters */");
- foreach (@{$fn->{ELEMENTS}}) {
- if (grep(/in/, @{$_->{DIRECTION}})) {
- $self->pidl("state->orig.in.$_->{NAME} = _$_->{NAME};");
- }
- }
$self->pidl("");
my $out_params = 0;
- $self->pidl("/* Out parameters */");
foreach (@{$fn->{ELEMENTS}}) {
if (grep(/out/, @{$_->{DIRECTION}})) {
- $self->pidl("state->orig.out.$_->{NAME} = _$_->{NAME};");
$out_params++;
}
}
- $self->pidl("");
-
- if (defined($fn->{RETURN_TYPE})) {
- $self->pidl("/* Result */");
- $self->pidl("ZERO_STRUCT(state->orig.out.result);");
- $self->pidl("");
- }
if ($out_params > 0) {
$self->pidl("state->out_mem_ctx = talloc_named_const(state, 0,");
@@ -253,14 +165,14 @@ sub ParseFunctionAsyncSend($$$)
$self->pidl("");
}
- $self->pidl("/* make a temporary copy, that we pass to the dispatch function */");
- $self->pidl("state->tmp = state->orig;");
- $self->pidl("");
+ $fn_str = "subreq = dcerpc_$fn->{NAME}_send";
+ $pad = "\t" . genpad($fn_str);
+ $fn_args = "state,\n" . $pad . "ev,\n" . $pad . "cli->binding_handle";
+ foreach (@{$fn->{ELEMENTS}}) {
+ $fn_args .= ",\n" . $pad . "_". $_->{NAME};
+ }
- $self->pidl("subreq = cli->dispatch_send(state, ev, cli,");
- $self->pidl("\t\t\t &ndr_table_$if,");
- $self->pidl("\t\t\t $ufn,");
- $self->pidl("\t\t\t &state->tmp);");
+ $self->pidl("$fn_str($fn_args);");
$self->pidl("if (tevent_req_nomem(subreq, req)) {");
$self->indent;
$self->pidl("return tevent_req_post(req, ev);");
@@ -302,7 +214,14 @@ sub ParseFunctionAsyncDone($$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("status = state->dispatch_recv(subreq, mem_ctx);");
+ my $fn_str = "status = dcerpc_$fn->{NAME}_recv";
+ my $pad = "\t" . genpad($fn_str);
+ my $fn_args = "subreq,\n" . $pad . "mem_ctx";
+ if (defined($fn->{RETURN_TYPE})) {
+ $fn_args .= ",\n" . $pad . "&state->result";
+ }
+
+ $self->pidl("$fn_str($fn_args);");
$self->pidl("TALLOC_FREE(subreq);");
$self->pidl("if (!NT_STATUS_IS_OK(status)) {");
$self->indent;
@@ -312,27 +231,6 @@ sub ParseFunctionAsyncDone($$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("/* Copy out parameters */");
- foreach my $e (@{$fn->{ELEMENTS}}) {
- next unless (grep(/out/, @{$e->{DIRECTION}}));
-
- $self->ParseOutputArgument($fn, $e,
- "state->tmp.",
- "state->orig.out.",
- "async");
- }
- $self->pidl("");
-
- if (defined($fn->{RETURN_TYPE})) {
- $self->pidl("/* Copy result */");
- $self->pidl("state->orig.out.result = state->tmp.out.result;");
- $self->pidl("");
- }
-
- $self->pidl("/* Reset temporary structure */");
- $self->pidl("ZERO_STRUCT(state->tmp);");
- $self->pidl("");
-
$self->pidl("tevent_req_done(req);");
$self->deindent;
$self->pidl("}");
@@ -369,13 +267,13 @@ sub ParseFunctionAsyncRecv($$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("/* Steal possbile out parameters to the callers context */");
+ $self->pidl("/* Steal possible out parameters to the callers context */");
$self->pidl("talloc_steal(mem_ctx, state->out_mem_ctx);");
$self->pidl("");
if (defined($fn->{RETURN_TYPE})) {
$self->pidl("/* Return result */");
- $self->pidl("*result = state->orig.out.result;");
+ $self->pidl("*result = state->result;");
$self->pidl("");
}
@@ -401,7 +299,7 @@ sub ParseFunctionSync($$$)
foreach (@{$fn->{ELEMENTS}}) {
my $dir = ElementDirection($_);
my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]);
- $fn_args .= ",\n" . $pad . DeclLong($_) . " /* $dir $prop */";
+ $fn_args .= ",\n" . $pad . DeclLong($_, "_") . " /* $dir $prop */";
}
if (defined($fn->{RETURN_TYPE}) && ($fn->{RETURN_TYPE} eq "WERROR")) {
@@ -411,60 +309,43 @@ sub ParseFunctionSync($$$)
$self->fn_declare("$fn_str($fn_args)");
$self->pidl("{");
$self->indent;
- $self->pidl("struct $fn->{NAME} r;");
+ if (defined($fn->{RETURN_TYPE})) {
+ $self->pidl(mapTypeName($fn->{RETURN_TYPE})." result;");
+ }
$self->pidl("NTSTATUS status;");
$self->pidl("");
- $self->pidl("/* In parameters */");
+ $fn_str = "status = dcerpc_$fn->{NAME}";
+ $pad = "\t" . genpad($fn_str);
+ $fn_args = "cli->binding_handle,\n" . $pad . "mem_ctx";
foreach (@{$fn->{ELEMENTS}}) {
- if (grep(/in/, @{$_->{DIRECTION}})) {
- $self->pidl("r.in.$_->{NAME} = $_->{NAME};");
- }
+ $fn_args .= ",\n" . $pad . "_". $_->{NAME};
+ }
+ if (defined($fn->{RETURN_TYPE})) {
+ $fn_args .= ",\n" . $pad . "&result";
}
- $self->pidl("");
- $self->pidl("status = cli->dispatch(cli,");
- $self->pidl("\t\t\tmem_ctx,");
- $self->pidl("\t\t\t&ndr_table_$if,");
- $self->pidl("\t\t\t$ufn,");
- $self->pidl("\t\t\t&r);");
- $self->pidl("");
-
+ $self->pidl("$fn_str($fn_args);");
$self->pidl("if (!NT_STATUS_IS_OK(status)) {");
$self->indent;
$self->pidl("return status;");
$self->deindent;
$self->pidl("}");
-
$self->pidl("");
- $self->pidl("if (NT_STATUS_IS_ERR(status)) {");
- $self->indent;
- $self->pidl("return status;");
- $self->deindent;
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("/* Return variables */");
- foreach my $e (@{$fn->{ELEMENTS}}) {
- next unless (grep(/out/, @{$e->{DIRECTION}}));
-
- $self->ParseOutputArgument($fn, $e);
-
- }
- $self->pidl("");
$self->pidl("/* Return result */");
if (not $fn->{RETURN_TYPE}) {
$self->pidl("return NT_STATUS_OK;");
} elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
- $self->pidl("return r.out.result;");
+ $self->pidl("return result;");
} elsif ($fn->{RETURN_TYPE} eq "WERROR") {
$self->pidl("if (werror) {");
$self->indent;
- $self->pidl("*werror = r.out.result;");
+ $self->pidl("*werror = result;");
$self->deindent;
$self->pidl("}");
$self->pidl("");
- $self->pidl("return werror_to_ntstatus(r.out.result);");
+ $self->pidl("return werror_to_ntstatus(result);");
} else {
warning($fn->{ORIGINAL}, "Unable to convert $fn->{RETURN_TYPE} to NTSTATUS");
$self->pidl("return NT_STATUS_OK;");
@@ -495,16 +376,27 @@ sub ParseInterface($$)
$self->pidl_hdr("#ifndef __CLI_$uif\__");
$self->pidl_hdr("#define __CLI_$uif\__");
- foreach (@{$if->{FUNCTIONS}}) {
- next if ($_->{PROPERTIES}{noopnum});
- $self->ParseFunction($if->{NAME}, $_);
+ foreach my $fn (@{$if->{FUNCTIONS}}) {
+ next if has_property($fn, "noopnum");
+ next if has_property($fn, "todo");
+
+ my $skip = 0;
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ if (ContainsPipe($e, $e->{LEVELS}[0])) {
+ $skip = 1;
+ last;
+ }
+ }
+ next if $skip;
+
+ $self->ParseFunction($if->{NAME}, $fn);
}
$self->pidl_hdr("#endif /* __CLI_$uif\__ */");
}
sub Parse($$$$)
{
- my($self,$ndr,$header,$ndr_header) = @_;
+ my($self,$ndr,$header,$c_header) = @_;
$self->pidl("/*");
$self->pidl(" * Unix SMB/CIFS implementation.");
@@ -513,7 +405,7 @@ sub Parse($$$$)
$self->pidl("");
$self->pidl("#include \"includes.h\"");
$self->pidl("#include \"$header\"");
- $self->pidl_hdr("#include \"$ndr_header\"");
+ $self->pidl_hdr("#include \"$c_header\"");
$self->pidl("");
foreach (@$ndr) {
diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
index 5599de9d79..c4374baf7c 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
@@ -100,7 +100,7 @@ sub CallWithStruct($$$$)
pidl "ZERO_STRUCT(r->out);" if ($hasout);
- my $proto = "_$fn->{NAME}(pipes_struct *p, struct $fn->{NAME} *r";
+ my $proto = "_$fn->{NAME}(struct pipes_struct *p, struct $fn->{NAME} *r";
my $ret = "_$fn->{NAME}($pipes_struct, r";
foreach (@{$fn->{ELEMENTS}}) {
my @dir = @{$_->{DIRECTION}};
@@ -138,14 +138,13 @@ sub ParseFunction($$)
my $op = "NDR_".uc($fn->{NAME});
- pidl "static bool api_$fn->{NAME}(pipes_struct *p)";
+ pidl "static bool api_$fn->{NAME}(struct pipes_struct *p)";
pidl "{";
indent;
pidl "const struct ndr_interface_call *call;";
pidl "struct ndr_pull *pull;";
pidl "struct ndr_push *push;";
pidl "enum ndr_err_code ndr_err;";
- pidl "DATA_BLOB blob;";
pidl "struct $fn->{NAME} *r;";
pidl "";
pidl "call = &ndr_table_$if->{NAME}.calls[$op];";
@@ -155,18 +154,16 @@ sub ParseFunction($$)
pidl "\treturn false;";
pidl "}";
pidl "";
- pidl "if (!prs_data_blob(&p->in_data.data, &blob, r)) {";
- pidl "\ttalloc_free(r);";
- pidl "\treturn false;";
- pidl "}";
- pidl "";
- pidl "pull = ndr_pull_init_blob(&blob, r, NULL);";
+ pidl "pull = ndr_pull_init_blob(&p->in_data.data, r);";
pidl "if (pull == NULL) {";
pidl "\ttalloc_free(r);";
pidl "\treturn false;";
pidl "}";
pidl "";
pidl "pull->flags |= LIBNDR_FLAG_REF_ALLOC;";
+ pidl "if (p->endian) {";
+ pidl "\tpull->flags |= LIBNDR_FLAG_BIGENDIAN;";
+ pidl "}";
pidl "ndr_err = call->ndr_pull(pull, NDR_IN, r);";
pidl "if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {";
pidl "\ttalloc_free(r);";
@@ -174,7 +171,7 @@ sub ParseFunction($$)
pidl "}";
pidl "";
pidl "if (DEBUGLEVEL >= 10) {";
- pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, r);";
+ pidl "\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_IN, r);";
pidl "}";
pidl "";
@@ -193,26 +190,29 @@ sub ParseFunction($$)
pidl "}";
pidl "";
pidl "if (DEBUGLEVEL >= 10) {";
- pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, r);";
+ pidl "\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_OUT | NDR_SET_VALUES, r);";
pidl "}";
pidl "";
- pidl "push = ndr_push_init_ctx(r, NULL);";
+ pidl "push = ndr_push_init_ctx(r);";
pidl "if (push == NULL) {";
pidl "\ttalloc_free(r);";
pidl "\treturn false;";
pidl "}";
pidl "";
+ pidl "/*";
+ pidl " * carry over the pointer count to the reply in case we are";
+ pidl " * using full pointer. See NDR specification for full pointers";
+ pidl " */";
+ pidl "push->ptr_count = pull->ptr_count;";
+ pidl "";
pidl "ndr_err = call->ndr_push(push, NDR_OUT, r);";
pidl "if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {";
pidl "\ttalloc_free(r);";
pidl "\treturn false;";
pidl "}";
pidl "";
- pidl "blob = ndr_push_blob(push);";
- pidl "if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) {";
- pidl "\ttalloc_free(r);";
- pidl "\treturn false;";
- pidl "}";
+ pidl "p->out_data.rdata = ndr_push_blob(push);";
+ pidl "talloc_steal(p->mem_ctx, p->out_data.rdata.data);";
pidl "";
pidl "talloc_free(r);";
pidl "";
@@ -222,45 +222,6 @@ sub ParseFunction($$)
pidl "";
}
-sub ParseDispatchFunction($)
-{
- my ($if) = @_;
-
- pidl_hdr "NTSTATUS rpc_$if->{NAME}_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r);";
- pidl "NTSTATUS rpc_$if->{NAME}_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *_r)";
- pidl "{";
- indent;
- pidl "if (cli->pipes_struct == NULL) {";
- pidl "\treturn NT_STATUS_INVALID_PARAMETER;";
- pidl "}";
- pidl "";
- pidl "switch (opnum)";
- pidl "{";
- indent;
- foreach my $fn (@{$if->{FUNCTIONS}}) {
- next if ($fn->{PROPERTIES}{noopnum});
- my $op = "NDR_".uc($fn->{NAME});
- pidl "case $op: {";
- indent;
- pidl "struct $fn->{NAME} *r = (struct $fn->{NAME} *)_r;";
- CallWithStruct("cli->pipes_struct", "mem_ctx", $fn,
- sub { pidl "return NT_STATUS_NO_MEMORY;"; });
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}";
- pidl "";
- }
-
- pidl "default:";
- pidl "\treturn NT_STATUS_NOT_IMPLEMENTED;";
- deindent;
- pidl "}";
- deindent;
- pidl "}";
-
- pidl "";
-}
-
sub ParseInterface($)
{
my $if = shift;
@@ -301,14 +262,22 @@ sub ParseInterface($)
pidl "}";
pidl "";
- ParseDispatchFunction($if);
-
- pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);";
- pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
- pidl "{";
- pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));";
- pidl "}";
-
+ if (not has_property($if, "no_srv_register")) {
+ pidl_hdr "struct rpc_srv_callbacks;";
+ pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb);";
+ pidl "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb)";
+ pidl "{";
+ pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct), rpc_srv_cb);";
+ pidl "}";
+
+ pidl "";
+
+ pidl_hdr "NTSTATUS rpc_$if->{NAME}_shutdown(void);";
+ pidl "NTSTATUS rpc_$if->{NAME}_shutdown(void)";
+ pidl "{";
+ pidl "\treturn rpc_srv_unregister(\&ndr_table_$if->{NAME});";
+ pidl "}";
+ }
pidl_hdr "#endif /* __SRV_$uif\__ */";
}
@@ -325,6 +294,7 @@ sub Parse($$$)
pidl " */";
pidl "";
pidl "#include \"includes.h\"";
+ pidl "#include \"ntdomain.h\"";
pidl "#include \"$header\"";
pidl_hdr "#include \"$ndr_header\"";
pidl "";
diff --git a/pidl/lib/Parse/Pidl/Samba4.pm b/pidl/lib/Parse/Pidl/Samba4.pm
index 1deb708689..b720ab9015 100644
--- a/pidl/lib/Parse/Pidl/Samba4.pm
+++ b/pidl/lib/Parse/Pidl/Samba4.pm
@@ -18,12 +18,17 @@ use strict;
use vars qw($VERSION);
$VERSION = '0.01';
+
+# return true if we are using pidl within the samba source tree. This changes
+# the names of include files, as some include files (such as ntstatus.h) have
+# different paths when installed to the patch in the source tree
sub is_intree()
{
my $srcdir = $ENV{srcdir};
$srcdir = $srcdir ? "$srcdir/" : "";
- return 4 if (-f "${srcdir}kdc/kdc.c");
- return 3 if (-f "${srcdir}include/smb.h");
+ return 1 if (-f "${srcdir}kdc/kdc.c");
+ return 1 if (-d "${srcdir}source4");
+ return 1 if (-f "${srcdir}include/smb.h");
return 0;
}
diff --git a/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm b/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm
index 150acbfde9..239f5baaee 100644
--- a/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm
@@ -89,7 +89,7 @@ sub Boilerplate_Iface($)
my $if_version = $interface->{PROPERTIES}->{version};
pidl "
-static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
+static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version)
{
#ifdef DCESRV_INTERFACE_$uname\_BIND
return DCESRV_INTERFACE_$uname\_BIND(dce_call,iface);
diff --git a/pidl/lib/Parse/Pidl/Samba4/Header.pm b/pidl/lib/Parse/Pidl/Samba4/Header.pm
index be1df4b118..3736315120 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Header.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Header.pm
@@ -5,7 +5,6 @@
# released under the GNU GPL
package Parse::Pidl::Samba4::Header;
-
require Exporter;
@ISA = qw(Exporter);
@@ -217,6 +216,30 @@ sub HeaderUnion($$;$)
}
#####################################################################
+# parse a pipe
+sub HeaderPipe($$;$)
+{
+ my($pipe,$name,$tail) = @_;
+
+ my $struct = $pipe->{DATA};
+ my $e = $struct->{ELEMENTS}[1];
+
+ pidl "struct $name;\n";
+ pidl "struct $struct->{NAME} {\n";
+ $tab_depth++;
+ pidl tabs()."uint32_t count;\n";
+ pidl tabs().mapTypeName($e->{TYPE})." *array;\n";
+ $tab_depth--;
+ pidl "}";
+
+ if (defined $struct->{PROPERTIES}) {
+ HeaderProperties($struct->{PROPERTIES}, []);
+ }
+
+ pidl $tail if defined($tail);
+}
+
+#####################################################################
# parse a type
sub HeaderType($$$;$)
{
@@ -226,6 +249,7 @@ sub HeaderType($$$;$)
($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name, $tail);
($data->{TYPE} eq "UNION") && HeaderUnion($data, $name, $tail);
+ ($data->{TYPE} eq "PIPE") && HeaderPipe($data, $name, $tail);
return;
}
@@ -386,6 +410,7 @@ sub HeaderInterface($)
HeaderUnion($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "UNION");
HeaderEnum($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "ENUM");
HeaderBitmap($t, $t->{NAME}) if ($t->{TYPE} eq "BITMAP");
+ HeaderPipe($t, $t->{NAME}, "\n\n") if ($t->{TYPE} eq "PIPE");
}
foreach my $fn (@{$interface->{FUNCTIONS}}) {
@@ -412,6 +437,20 @@ sub Parse($)
$res = "";
%headerstructs = ();
pidl "/* header auto-generated by pidl */\n\n";
+
+ my $ifacename = "";
+
+ # work out a unique interface name
+ foreach (@{$ndr}) {
+ if ($_->{TYPE} eq "INTERFACE") {
+ $ifacename = $_->{NAME};
+ last;
+ }
+ }
+
+ pidl "#ifndef _PIDL_HEADER_$ifacename\n";
+ pidl "#define _PIDL_HEADER_$ifacename\n\n";
+
if (!is_intree()) {
pidl "#include <util/data_blob.h>\n";
}
@@ -428,6 +467,8 @@ sub Parse($)
($_->{TYPE} eq "INCLUDE") && HeaderInclude(@{$_->{PATHS}});
}
+ pidl "#endif /* _PIDL_HEADER_$ifacename */\n";
+
return $res;
}
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
index 9d3ccaf8c8..c796b466ad 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
@@ -6,156 +6,870 @@
package Parse::Pidl::Samba4::NDR::Client;
-use Parse::Pidl::Samba4 qw(choose_header is_intree);
-use Parse::Pidl::Util qw(has_property);
+use Exporter;
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(Parse);
+
+use Parse::Pidl qw(fatal warning error);
+use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(ContainsPipe);
+use Parse::Pidl::Typelist qw(mapTypeName);
+use Parse::Pidl::Samba4 qw(choose_header is_intree DeclLong);
+use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
use vars qw($VERSION);
$VERSION = '0.01';
use strict;
-my($res,$res_hdr);
+sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
+sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
+sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; }
+sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
+sub pidl_both($$) { my ($self, $txt) = @_; $self->{hdr} .= "$txt\n"; $self->{res_hdr} .= "$txt\n"; }
+sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
-sub ParseFunctionSend($$$)
+sub genpad($)
{
- my ($interface, $fn, $name) = @_;
+ my ($s) = @_;
+ my $nt = int((length($s)+1)/8);
+ my $lt = ($nt*8)-1;
+ my $ns = (length($s)-$lt);
+ return "\t"x($nt)." "x($ns);
+}
+
+sub new($)
+{
+ my ($class) = shift;
+ my $self = { res => "", res_hdr => "", tabs => "" };
+ bless($self, $class);
+}
+
+sub ParseFunctionHasPipes($$)
+{
+ my ($self, $fn) = @_;
+
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ return 1 if ContainsPipe($e, $e->{LEVELS}[0]);
+ }
+
+ return 0;
+}
+
+sub ParseFunction_r_State($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
my $uname = uc $name;
- my $proto = "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)";
+ $self->pidl("struct dcerpc_$name\_r_state {");
+ $self->indent;
+ $self->pidl("TALLOC_CTX *out_mem_ctx;");
+ $self->deindent;
+ $self->pidl("};");
+ $self->pidl("");
+ $self->pidl("static void dcerpc_$name\_r_done(struct tevent_req *subreq);");
+ $self->pidl("");
+}
- $res_hdr .= "\n$proto;\n";
+sub ParseFunction_r_Send($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
+ my $uname = uc $name;
- $res .= "$proto\n{\n";
+ my $proto = "struct tevent_req *dcerpc_$name\_r_send(TALLOC_CTX *mem_ctx,\n";
+ $proto .= "\tstruct tevent_context *ev,\n",
+ $proto .= "\tstruct dcerpc_binding_handle *h,\n",
+ $proto .= "\tstruct $name *r)";
+
+ $self->fn_declare($proto);
+
+ $self->pidl("{");
+ $self->indent;
+
+ $self->pidl("struct tevent_req *req;");
+ $self->pidl("struct dcerpc_$name\_r_state *state;");
+ $self->pidl("struct tevent_req *subreq;");
+ $self->pidl("");
+
+ $self->pidl("req = tevent_req_create(mem_ctx, &state,");
+ $self->pidl("\t\t\tstruct dcerpc_$name\_r_state);");
+ $self->pidl("if (req == NULL) {");
+ $self->indent;
+ $self->pidl("return NULL;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ my $out_params = 0;
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless grep(/out/, @{$e->{DIRECTION}});
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
+ $out_params++;
- if (has_property($fn, "todo")) {
- $res .= "\treturn NULL;\n";
- } else {
- $res .= "
- if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
- NDR_PRINT_IN_DEBUG($name, r);
}
- return dcerpc_ndr_request_send(p, NULL, &ndr_table_$interface->{NAME},
- NDR_$uname, true, mem_ctx, r);
-";
+ my $submem;
+ if ($out_params > 0) {
+ $self->pidl("state->out_mem_ctx = talloc_new(state);");
+ $self->pidl("if (tevent_req_nomem(state->out_mem_ctx, req)) {");
+ $self->indent;
+ $self->pidl("return tevent_req_post(req, ev);");
+ $self->deindent;
+ $self->pidl("}");
+ $submem = "state->out_mem_ctx";
+ } else {
+ $self->pidl("state->out_mem_ctx = NULL;");
+ $submem = "state";
}
+ $self->pidl("");
+
+ $self->pidl("subreq = dcerpc_binding_handle_call_send(state, ev, h,");
+ $self->pidl("\t\tNULL, &ndr_table_$if->{NAME},");
+ $self->pidl("\t\tNDR_$uname, $submem, r);");
+ $self->pidl("if (tevent_req_nomem(subreq, req)) {");
+ $self->indent;
+ $self->pidl("return tevent_req_post(req, ev);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("tevent_req_set_callback(subreq, dcerpc_$name\_r_done, req);");
+ $self->pidl("");
+
+ $self->pidl("return req;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
- $res .= "}\n\n";
+sub ParseFunction_r_Done($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
+ my $uname = uc $name;
+
+ my $proto = "static void dcerpc_$name\_r_done(struct tevent_req *subreq)";
+
+ $self->pidl("$proto");
+ $self->pidl("{");
+ $self->indent;
+
+ $self->pidl("struct tevent_req *req =");
+ $self->pidl("\ttevent_req_callback_data(subreq,");
+ $self->pidl("\tstruct tevent_req);");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
+
+ $self->pidl("status = dcerpc_binding_handle_call_recv(subreq);");
+ $self->pidl("if (!NT_STATUS_IS_OK(status)) {");
+ $self->indent;
+ $self->pidl("tevent_req_nterror(req, status);");
+ $self->pidl("return;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("tevent_req_done(req);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
}
-sub ParseFunctionSync($$$)
+sub ParseFunction_r_Recv($$$$)
{
- my ($interface, $fn, $name) = @_;
+ my ($self, $if, $fn, $name) = @_;
my $uname = uc $name;
- my $proto = "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)";
+ my $proto = "NTSTATUS dcerpc_$name\_r_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx)";
+
+ $self->fn_declare($proto);
+
+ $self->pidl("{");
+ $self->indent;
+
+ $self->pidl("struct dcerpc_$name\_r_state *state =");
+ $self->pidl("\ttevent_req_data(req,");
+ $self->pidl("\tstruct dcerpc_$name\_r_state);");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
- $res_hdr .= "\n$proto;\n";
- $res .= "$proto\n{\n";
+ $self->pidl("if (tevent_req_is_nterror(req, &status)) {");
+ $self->indent;
+ $self->pidl("tevent_req_received(req);");
+ $self->pidl("return status;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
- if (has_property($fn, "todo")) {
- $res .= "\treturn NT_STATUS_NOT_IMPLEMENTED;\n";
+ $self->pidl("talloc_steal(mem_ctx, state->out_mem_ctx);");
+ $self->pidl("");
+
+ $self->pidl("tevent_req_received(req);");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParseFunction_r_Sync($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
+ my $uname = uc $name;
+
+ if ($self->ParseFunctionHasPipes($fn)) {
+ $self->pidl_both("/*");
+ $self->pidl_both(" * The following function is skipped because");
+ $self->pidl_both(" * it uses pipes:");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$name\_r()");
+ $self->pidl_both(" */");
+ $self->pidl_both("");
+ return;
+ }
+
+ my $proto = "NTSTATUS dcerpc_$name\_r(struct dcerpc_binding_handle *h, TALLOC_CTX *mem_ctx, struct $name *r)";
+
+ $self->fn_declare($proto);
+
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
+
+ $self->pidl("status = dcerpc_binding_handle_call(h,");
+ $self->pidl("\t\tNULL, &ndr_table_$if->{NAME},");
+ $self->pidl("\t\tNDR_$uname, mem_ctx, r);");
+ $self->pidl("");
+ $self->pidl("return status;");
+
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ElementDirection($)
+{
+ my ($e) = @_;
+
+ return "[in,out]" if (has_property($e, "in") and has_property($e, "out"));
+ return "[in]" if (has_property($e, "in"));
+ return "[out]" if (has_property($e, "out"));
+ return "[in,out]";
+}
+
+sub HeaderProperties($$)
+{
+ my($props,$ignores) = @_;
+ my $ret = "";
+
+ foreach my $d (keys %{$props}) {
+ next if (grep(/^$d$/, @$ignores));
+ if($props->{$d} ne "1") {
+ $ret.= "$d($props->{$d}),";
+ } else {
+ $ret.="$d,";
+ }
+ }
+
+ if ($ret) {
+ return "[" . substr($ret, 0, -1) . "]";
+ }
+}
+
+sub ParseCopyArgument($$$$$)
+{
+ my ($self, $fn, $e, $r, $i) = @_;
+ my $l = $e->{LEVELS}[0];
+
+ if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED} == 1) {
+ $self->pidl("memcpy(${r}$e->{NAME}, ${i}$e->{NAME}, sizeof(${r}$e->{NAME}));");
} else {
- $res .= "
- NTSTATUS status;
+ $self->pidl("${r}$e->{NAME} = ${i}$e->{NAME};");
+ }
+}
+
+sub ParseInvalidResponse($$)
+{
+ my ($self, $type) = @_;
- if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
- NDR_PRINT_IN_DEBUG($name, r);
+ if ($type eq "sync") {
+ $self->pidl("return NT_STATUS_INVALID_NETWORK_RESPONSE;");
+ } elsif ($type eq "async") {
+ $self->pidl("tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);");
+ $self->pidl("return;");
+ } else {
+ die("ParseInvalidResponse($type)");
}
+}
+
+sub ParseOutputArgument($$$$$$)
+{
+ my ($self, $fn, $e, $r, $o, $invalid_response_type) = @_;
+ my $level = 0;
- status = dcerpc_ndr_request(p, NULL, &ndr_table_$interface->{NAME},
- NDR_$uname, mem_ctx, r);
+ if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY") {
+ fatal($e->{ORIGINAL}, "[out] argument is not a pointer or array");
+ return;
+ }
- if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
- NDR_PRINT_OUT_DEBUG($name, r);
+ if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") {
+ $level = 1;
+ if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") {
+ $self->pidl("if ($o$e->{NAME} && ${r}out.$e->{NAME}) {");
+ $self->indent;
+ }
}
-";
-
- if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") {
- $res .= "\tif (NT_STATUS_IS_OK(status)) status = r->out.result;\n";
- }
- $res .=
-"
- return status;
-";
+
+ if ($e->{LEVELS}[$level]->{TYPE} eq "ARRAY") {
+ # This is a call to GenerateFunctionInEnv intentionally.
+ # Since the data is being copied into a user-provided data
+ # structure, the user should be able to know the size beforehand
+ # to allocate a structure of the right size.
+ my $in_env = GenerateFunctionInEnv($fn, $r);
+ my $out_env = GenerateFunctionOutEnv($fn, $r);
+ my $l = $e->{LEVELS}[$level];
+
+ my $in_var = undef;
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $in_var = ParseExpr($e->{NAME}, $in_env, $e->{ORIGINAL});
+ }
+ my $out_var = ParseExpr($e->{NAME}, $out_env, $e->{ORIGINAL});
+
+ my $in_size_is = undef;
+ my $out_size_is = undef;
+ my $out_length_is = undef;
+
+ my $avail_len = undef;
+ my $needed_len = undef;
+
+ $self->pidl("{");
+ $self->indent;
+ my $copy_len_var = "_copy_len_$e->{NAME}";
+ $self->pidl("size_t $copy_len_var;");
+
+ if (not defined($l->{SIZE_IS})) {
+ if (not $l->{IS_ZERO_TERMINATED}) {
+ fatal($e->{ORIGINAL}, "no size known for [out] array `$e->{NAME}'");
+ }
+ if (has_property($e, "charset")) {
+ $avail_len = "ndr_charset_length($in_var, CH_UNIX)";
+ $needed_len = "ndr_charset_length($out_var, CH_UNIX)";
+ } else {
+ $avail_len = "ndr_string_length($in_var, sizeof(*$in_var))";
+ $needed_len = "ndr_string_length($out_var, sizeof(*$out_var))";
+ }
+ $in_size_is = "";
+ $out_size_is = "";
+ $out_length_is = "";
+ } else {
+ $in_size_is = ParseExpr($l->{SIZE_IS}, $in_env, $e->{ORIGINAL});
+ $out_size_is = ParseExpr($l->{SIZE_IS}, $out_env, $e->{ORIGINAL});
+ $out_length_is = $out_size_is;
+ if (defined($l->{LENGTH_IS})) {
+ $out_length_is = ParseExpr($l->{LENGTH_IS}, $out_env, $e->{ORIGINAL});
+ }
+ if (has_property($e, "charset")) {
+ if (defined($in_var)) {
+ $avail_len = "ndr_charset_length($in_var, CH_UNIX)";
+ } else {
+ $avail_len = $out_length_is;
+ }
+ $needed_len = "ndr_charset_length($out_var, CH_UNIX)";
+ }
+ }
+
+ if ($out_size_is ne $in_size_is) {
+ $self->pidl("if (($out_size_is) > ($in_size_is)) {");
+ $self->indent;
+ $self->ParseInvalidResponse($invalid_response_type);
+ $self->deindent;
+ $self->pidl("}");
+ }
+ if ($out_length_is ne $out_size_is) {
+ $self->pidl("if (($out_length_is) > ($out_size_is)) {");
+ $self->indent;
+ $self->ParseInvalidResponse($invalid_response_type);
+ $self->deindent;
+ $self->pidl("}");
+ }
+ if (defined($needed_len)) {
+ $self->pidl("$copy_len_var = $needed_len;");
+ $self->pidl("if ($copy_len_var > $avail_len) {");
+ $self->indent;
+ $self->ParseInvalidResponse($invalid_response_type);
+ $self->deindent;
+ $self->pidl("}");
+ } else {
+ $self->pidl("$copy_len_var = $out_length_is;");
+ }
+
+ if (has_property($e, "charset")) {
+ $self->pidl("memcpy(discard_const_p(uint8_t *, $o$e->{NAME}), $out_var, $copy_len_var * sizeof(*$o$e->{NAME}));");
+ } else {
+ $self->pidl("memcpy($o$e->{NAME}, $out_var, $copy_len_var * sizeof(*$o$e->{NAME}));");
+ }
+
+ $self->deindent;
+ $self->pidl("}");
+ } else {
+ $self->pidl("*$o$e->{NAME} = *${r}out.$e->{NAME};");
}
- $res .= "}\n\n";
+ if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") {
+ if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") {
+ $self->deindent;
+ $self->pidl("}");
+ }
+ }
+}
+
+sub ParseFunction_State($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
+
+ my $state_str = "struct dcerpc_$name\_state";
+ my $done_fn = "dcerpc_$name\_done";
+
+ $self->pidl("$state_str {");
+ $self->indent;
+ $self->pidl("struct $name orig;");
+ $self->pidl("struct $name tmp;");
+ $self->pidl("TALLOC_CTX *out_mem_ctx;");
+ $self->deindent;
+ $self->pidl("};");
+ $self->pidl("");
+ $self->pidl("static void $done_fn(struct tevent_req *subreq);");
+ $self->pidl("");
+}
+
+sub ParseFunction_Send($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
+
+ my $fn_args = "";
+ my $state_str = "struct dcerpc_$name\_state";
+ my $done_fn = "dcerpc_$name\_done";
+ my $out_mem_ctx = "dcerpc_$name\_out_memory";
+ my $fn_str = "struct tevent_req *dcerpc_$name\_send";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "TALLOC_CTX *mem_ctx";
+ $fn_args .= ",\n" . $pad . "struct tevent_context *ev";
+ $fn_args .= ",\n" . $pad . "struct dcerpc_binding_handle *h";
+
+ foreach (@{$fn->{ELEMENTS}}) {
+ my $dir = ElementDirection($_);
+ my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]);
+ $fn_args .= ",\n" . $pad . DeclLong($_, "_") . " /* $dir $prop */";
+ }
+
+ $self->fn_declare("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("struct tevent_req *req;");
+ $self->pidl("$state_str *state;");
+ $self->pidl("struct tevent_req *subreq;");
+ $self->pidl("");
+ $self->pidl("req = tevent_req_create(mem_ctx, &state,");
+ $self->pidl("\t\t\t$state_str);");
+ $self->pidl("if (req == NULL) {");
+ $self->indent;
+ $self->pidl("return NULL;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("state->out_mem_ctx = NULL;");
+ $self->pidl("");
+
+ $self->pidl("/* In parameters */");
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless (grep(/in/, @{$e->{DIRECTION}}));
+
+ $self->ParseCopyArgument($fn, $e, "state->orig.in.", "_");
+ }
+ $self->pidl("");
+
+ my $out_params = 0;
+ $self->pidl("/* Out parameters */");
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless grep(/out/, @{$e->{DIRECTION}});
+
+ $self->ParseCopyArgument($fn, $e, "state->orig.out.", "_");
+
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
+
+ $out_params++;
+ }
+ $self->pidl("");
+
+ if (defined($fn->{RETURN_TYPE})) {
+ $self->pidl("/* Result */");
+ $self->pidl("ZERO_STRUCT(state->orig.out.result);");
+ $self->pidl("");
+ }
+
+ if ($out_params > 0) {
+ $self->pidl("state->out_mem_ctx = talloc_named_const(state, 0,");
+ $self->pidl("\t\t \"$out_mem_ctx\");");
+ $self->pidl("if (tevent_req_nomem(state->out_mem_ctx, req)) {");
+ $self->indent;
+ $self->pidl("return tevent_req_post(req, ev);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+ }
+
+ $self->pidl("/* make a temporary copy, that we pass to the dispatch function */");
+ $self->pidl("state->tmp = state->orig;");
+ $self->pidl("");
+
+ $self->pidl("subreq = dcerpc_$name\_r_send(state, ev, h, &state->tmp);");
+ $self->pidl("if (tevent_req_nomem(subreq, req)) {");
+ $self->indent;
+ $self->pidl("return tevent_req_post(req, ev);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("tevent_req_set_callback(subreq, $done_fn, req);");
+ $self->pidl("return req;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParseFunction_Done($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
+
+ my $state_str = "struct dcerpc_$name\_state";
+ my $done_fn = "dcerpc_$name\_done";
+
+ $self->pidl("static void $done_fn(struct tevent_req *subreq)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("struct tevent_req *req = tevent_req_callback_data(");
+ $self->pidl("\tsubreq, struct tevent_req);");
+ $self->pidl("$state_str *state = tevent_req_data(");
+ $self->pidl("\treq, $state_str);");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("TALLOC_CTX *mem_ctx;");
+ $self->pidl("");
+
+ $self->pidl("if (state->out_mem_ctx) {");
+ $self->indent;
+ $self->pidl("mem_ctx = state->out_mem_ctx;");
+ $self->deindent;
+ $self->pidl("} else {");
+ $self->indent;
+ $self->pidl("mem_ctx = state;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("status = dcerpc_$name\_r_recv(subreq, mem_ctx);");
+ $self->pidl("TALLOC_FREE(subreq);");
+ $self->pidl("if (!NT_STATUS_IS_OK(status)) {");
+ $self->indent;
+ $self->pidl("tevent_req_nterror(req, status);");
+ $self->pidl("return;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("/* Copy out parameters */");
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
+ next unless (grep(/out/, @{$e->{DIRECTION}}));
+
+ $self->ParseOutputArgument($fn, $e,
+ "state->tmp.",
+ "state->orig.out.",
+ "async");
+ }
+ $self->pidl("");
+
+ if (defined($fn->{RETURN_TYPE})) {
+ $self->pidl("/* Copy result */");
+ $self->pidl("state->orig.out.result = state->tmp.out.result;");
+ $self->pidl("");
+ }
+
+ $self->pidl("/* Reset temporary structure */");
+ $self->pidl("ZERO_STRUCT(state->tmp);");
+ $self->pidl("");
+
+ $self->pidl("tevent_req_done(req);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParseFunction_Recv($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
+
+ my $fn_args = "";
+ my $state_str = "struct dcerpc_$name\_state";
+ my $fn_str = "NTSTATUS dcerpc_$name\_recv";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "struct tevent_req *req,\n" . $pad . "TALLOC_CTX *mem_ctx";
+
+ if (defined($fn->{RETURN_TYPE})) {
+ $fn_args .= ",\n" . $pad . mapTypeName($fn->{RETURN_TYPE}). " *result";
+ }
+
+ $self->fn_declare("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("$state_str *state = tevent_req_data(");
+ $self->pidl("\treq, $state_str);");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
+ $self->pidl("if (tevent_req_is_nterror(req, &status)) {");
+ $self->indent;
+ $self->pidl("tevent_req_received(req);");
+ $self->pidl("return status;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("/* Steal possible out parameters to the callers context */");
+ $self->pidl("talloc_steal(mem_ctx, state->out_mem_ctx);");
+ $self->pidl("");
+
+ if (defined($fn->{RETURN_TYPE})) {
+ $self->pidl("/* Return result */");
+ $self->pidl("*result = state->orig.out.result;");
+ $self->pidl("");
+ }
+
+ $self->pidl("tevent_req_received(req);");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParseFunction_Sync($$$$)
+{
+ my ($self, $if, $fn, $name) = @_;
+
+ if ($self->ParseFunctionHasPipes($fn)) {
+ $self->pidl_both("/*");
+ $self->pidl_both(" * The following function is skipped because");
+ $self->pidl_both(" * it uses pipes:");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$name()");
+ $self->pidl_both(" */");
+ $self->pidl_both("");
+ return;
+ }
+
+ my $uname = uc $name;
+ my $fn_args = "";
+ my $fn_str = "NTSTATUS dcerpc_$name";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "struct dcerpc_binding_handle *h,\n" . $pad . "TALLOC_CTX *mem_ctx";
+
+ foreach (@{$fn->{ELEMENTS}}) {
+ my $dir = ElementDirection($_);
+ my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]);
+ $fn_args .= ",\n" . $pad . DeclLong($_, "_") . " /* $dir $prop */";
+ }
+
+ if (defined($fn->{RETURN_TYPE})) {
+ $fn_args .= ",\n" . $pad . mapTypeName($fn->{RETURN_TYPE}). " *result";
+ }
+
+ $self->fn_declare("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("struct $name r;");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
+
+ $self->pidl("/* In parameters */");
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless (grep(/in/, @{$e->{DIRECTION}}));
+
+ $self->ParseCopyArgument($fn, $e, "r.in.", "_");
+ }
+ $self->pidl("");
+
+ $self->pidl("status = dcerpc_$name\_r(h, mem_ctx, &r);");
+ $self->pidl("if (!NT_STATUS_IS_OK(status)) {");
+ $self->indent;
+ $self->pidl("return status;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("/* Return variables */");
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
+ next unless (grep(/out/, @{$e->{DIRECTION}}));
+
+ $self->ParseOutputArgument($fn, $e, "r.", "_", "sync");
+ }
+ $self->pidl("");
+
+ $self->pidl("/* Return result */");
+ if ($fn->{RETURN_TYPE}) {
+ $self->pidl("*result = r.out.result;");
+ }
+ $self->pidl("");
+
+ $self->pidl("return NT_STATUS_OK;");
+
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
}
#####################################################################
# parse a function
-sub ParseFunction($$)
+sub ParseFunction($$$)
{
- my ($interface, $fn) = @_;
+ my ($self, $if, $fn) = @_;
+
+ if ($self->ParseFunctionHasPipes($fn)) {
+ $self->pidl_both("/*");
+ $self->pidl_both(" * The following function is skipped because");
+ $self->pidl_both(" * it uses pipes:");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_r_send()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_r_recv()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_r()");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_send()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_recv()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}()");
+ $self->pidl_both(" */");
+ $self->pidl_both("");
+ warning($fn->{ORIGINAL}, "$fn->{NAME}: dcerpc client does not support pipe yet");
+ return;
+ }
+
+ $self->ParseFunction_r_State($if, $fn, $fn->{NAME});
+ $self->ParseFunction_r_Send($if, $fn, $fn->{NAME});
+ $self->ParseFunction_r_Done($if, $fn, $fn->{NAME});
+ $self->ParseFunction_r_Recv($if, $fn, $fn->{NAME});
+ $self->ParseFunction_r_Sync($if, $fn, $fn->{NAME});
+
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless (grep(/out/, @{$e->{DIRECTION}}));
+
+ my $reason = "is not a pointer or array";
+
+ # TODO: make this fatal at NDR level
+ if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") {
+ if ($e->{LEVELS}[1]->{TYPE} eq "DATA" and
+ $e->{LEVELS}[1]->{DATA_TYPE} eq "string") {
+ $reason = "is a pointer to type 'string'";
+ } elsif ($e->{LEVELS}[1]->{TYPE} eq "ARRAY" and
+ $e->{LEVELS}[1]->{IS_ZERO_TERMINATED}) {
+ next;
+ } elsif ($e->{LEVELS}[1]->{TYPE} eq "ARRAY" and
+ not defined($e->{LEVELS}[1]->{SIZE_IS})) {
+ $reason = "is a pointer to an unsized array";
+ } else {
+ next;
+ }
+ }
+ if ($e->{LEVELS}[0]->{TYPE} eq "ARRAY") {
+ if (not defined($e->{LEVELS}[0]->{SIZE_IS})) {
+ $reason = "is an unsized array";
+ } else {
+ next;
+ }
+ }
+
+ $self->pidl_both("/*");
+ $self->pidl_both(" * The following functions are skipped because");
+ $self->pidl_both(" * an [out] argument $e->{NAME} $reason:");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_send()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_recv()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}()");
+ $self->pidl_both(" */");
+ $self->pidl_both("");
+
+ error($e->{ORIGINAL}, "$fn->{NAME}: [out] argument '$e->{NAME}' $reason, skip client functions");
+ return;
+ }
+
+ $self->ParseFunction_State($if, $fn, $fn->{NAME});
+ $self->ParseFunction_Send($if, $fn, $fn->{NAME});
+ $self->ParseFunction_Done($if, $fn, $fn->{NAME});
+ $self->ParseFunction_Recv($if, $fn, $fn->{NAME});
+ $self->ParseFunction_Sync($if, $fn, $fn->{NAME});
- ParseFunctionSend($interface, $fn, $fn->{NAME});
- ParseFunctionSync($interface, $fn, $fn->{NAME});
+ $self->pidl_hdr("");
}
my %done;
#####################################################################
# parse the interface definitions
-sub ParseInterface($)
+sub ParseInterface($$)
{
- my($interface) = shift;
+ my ($self, $if) = @_;
+ my $ifu = uc($if->{NAME});
- $res_hdr .= "#ifndef _HEADER_RPC_$interface->{NAME}\n";
- $res_hdr .= "#define _HEADER_RPC_$interface->{NAME}\n\n";
+ $self->pidl_hdr("#ifndef _HEADER_RPC_$if->{NAME}");
+ $self->pidl_hdr("#define _HEADER_RPC_$if->{NAME}");
+ $self->pidl_hdr("");
- if (defined $interface->{PROPERTIES}->{uuid}) {
- $res_hdr .= "extern const struct ndr_interface_table ndr_table_$interface->{NAME};\n";
+ if (defined $if->{PROPERTIES}->{uuid}) {
+ $self->pidl_hdr("extern const struct ndr_interface_table ndr_table_$if->{NAME};");
+ $self->pidl_hdr("");
}
- $res .= "/* $interface->{NAME} - client functions generated by pidl */\n\n";
+ $self->pidl("/* $if->{NAME} - client functions generated by pidl */");
+ $self->pidl("");
- foreach my $fn (@{$interface->{FUNCTIONS}}) {
- next if not defined($fn->{OPNUM});
+ foreach my $fn (@{$if->{FUNCTIONS}}) {
next if defined($done{$fn->{NAME}});
- ParseFunction($interface, $fn);
+ next if has_property($fn, "noopnum");
+ next if has_property($fn, "todo");
+ $self->ParseFunction($if, $fn);
$done{$fn->{NAME}} = 1;
}
- $res_hdr .= "#endif /* _HEADER_RPC_$interface->{NAME} */\n";
-
- return $res;
+ $self->pidl_hdr("#endif /* _HEADER_RPC_$if->{NAME} */");
}
-sub Parse($$$$)
+sub Parse($$$$$$)
{
- my($ndr,$header,$ndr_header,$client_header) = @_;
-
- $res = "";
- $res_hdr = "";
+ my($self,$ndr,$header,$ndr_header,$client_header) = @_;
- $res .= "/* client functions auto-generated by pidl */\n";
- $res .= "\n";
+ $self->pidl("/* client functions auto-generated by pidl */");
+ $self->pidl("");
if (is_intree()) {
- $res .= "#include \"includes.h\"\n";
+ $self->pidl("#include \"includes.h\"");
} else {
- $res .= "#ifndef _GNU_SOURCE\n";
- $res .= "#define _GNU_SOURCE\n";
- $res .= "#endif\n";
- $res .= "#include <stdio.h>\n";
- $res .= "#include <stdbool.h>\n";
- $res .= "#include <stdlib.h>\n";
- $res .= "#include <stdint.h>\n";
- $res .= "#include <stdarg.h>\n";
- $res .= "#include <core/ntstatus.h>\n";
- }
- $res .= "#include \"$ndr_header\"\n";
- $res .= "#include \"$client_header\"\n";
- $res .= "\n";
-
- $res_hdr .= choose_header("librpc/rpc/dcerpc.h", "dcerpc.h")."\n";
- $res_hdr .= "#include \"$header\"\n";
+ $self->pidl("#ifndef _GNU_SOURCE");
+ $self->pidl("#define _GNU_SOURCE");
+ $self->pidl("#endif");
+ $self->pidl("#include <stdio.h>");
+ $self->pidl("#include <stdbool.h>");
+ $self->pidl("#include <stdlib.h>");
+ $self->pidl("#include <stdint.h>");
+ $self->pidl("#include <stdarg.h>");
+ $self->pidl("#include <string.h>");
+ $self->pidl("#include <core/ntstatus.h>");
+ }
+ $self->pidl("#include <tevent.h>");
+ $self->pidl(choose_header("lib/util/tevent_ntstatus.h", "util/tevent_ntstatus.h")."");
+ $self->pidl("#include \"$ndr_header\"");
+ $self->pidl("#include \"$client_header\"");
+ $self->pidl("");
+
+ $self->pidl_hdr(choose_header("librpc/rpc/dcerpc.h", "dcerpc.h")."");
+ $self->pidl_hdr("#include \"$header\"");
foreach my $x (@{$ndr}) {
- ($x->{TYPE} eq "INTERFACE") && ParseInterface($x);
+ ($x->{TYPE} eq "INTERFACE") && $self->ParseInterface($x);
}
- return ($res,$res_hdr);
+ return ($self->{res},$self->{res_hdr});
}
1;
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index da536beef4..7cda2729fc 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -15,7 +15,7 @@ use strict;
use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody);
use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid unmake_str);
use Parse::Pidl::CUtil qw(get_pointer_to get_value_of get_array_element);
-use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
use Parse::Pidl::Samba4 qw(is_intree choose_header ArrayDynamicallyAllocated);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
use Parse::Pidl qw(warning);
@@ -206,11 +206,11 @@ sub ParseArrayPushHeader($$$$$$)
if ((!$l->{IS_SURROUNDING}) and $l->{IS_CONFORMANT}) {
$self->pidl("NDR_CHECK(ndr_push_uint3264($ndr, NDR_SCALARS, $size));");
}
-
+
if ($l->{IS_VARYING}) {
$self->pidl("NDR_CHECK(ndr_push_uint3264($ndr, NDR_SCALARS, 0));"); # array offset
$self->pidl("NDR_CHECK(ndr_push_uint3264($ndr, NDR_SCALARS, $length));");
- }
+ }
return $length;
}
@@ -574,6 +574,9 @@ sub ParseElementPushLevel
if ($l->{POINTER_TYPE} eq "relative") {
$self->pidl("NDR_CHECK(ndr_push_relative_ptr2_start($ndr, $rel_var_name));");
}
+ if ($l->{POINTER_TYPE} eq "relative_short") {
+ $self->pidl("NDR_CHECK(ndr_push_short_relative_ptr2($ndr, $var_name));");
+ }
}
$var_name = get_value_of($var_name);
$self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 1, 1);
@@ -627,6 +630,8 @@ sub ParseElementPush($$$$$$)
my $var_name = $env->{$e->{NAME}};
+ return if ContainsPipe($e, $e->{LEVELS}[0]);
+
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
# Representation type is different from transmit_as
@@ -674,6 +679,8 @@ sub ParsePtrPush($$$$$)
}
} elsif ($l->{POINTER_TYPE} eq "relative") {
$self->pidl("NDR_CHECK(ndr_push_relative_ptr1($ndr, $var_name));");
+ } elsif ($l->{POINTER_TYPE} eq "relative_short") {
+ $self->pidl("NDR_CHECK(ndr_push_short_relative_ptr1($ndr, $var_name));");
} elsif ($l->{POINTER_TYPE} eq "unique") {
$self->pidl("NDR_CHECK(ndr_push_unique_ptr($ndr, $var_name));");
} elsif ($l->{POINTER_TYPE} eq "full") {
@@ -786,9 +793,6 @@ sub ParseElementPrint($$$$$)
$self->pidl("$ndr->depth++;");
$self->pidl("for ($counter=0;$counter<$length;$counter++) {");
$self->indent;
- $self->pidl("char *idx_$l->{LEVEL_INDEX}=NULL;");
- $self->pidl("if (asprintf(&idx_$l->{LEVEL_INDEX}, \"[\%d]\", $counter) != -1) {");
- $self->indent;
$var_name = get_array_element($var_name, $counter);
}
@@ -811,9 +815,6 @@ sub ParseElementPrint($$$$$)
} elsif (($l->{TYPE} eq "ARRAY")
and not is_charset_array($e,$l)
and not has_fast_array($e,$l)) {
- $self->pidl("free(idx_$l->{LEVEL_INDEX});");
- $self->deindent;
- $self->pidl("}");
$self->deindent;
$self->pidl("}");
$self->pidl("$ndr->depth--;");
@@ -865,7 +866,10 @@ sub ParseDataPull($$$$$$$)
$self->pidl("NDR_CHECK(".TypeFunctionName("ndr_pull", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));");
- if (my $range = has_property($e, "range")) {
+ my $pl = GetPrevLevel($e, $l);
+
+ my $range = has_property($e, "range");
+ if ($range and $pl->{TYPE} ne "ARRAY") {
$var_name = get_value_of($var_name);
my $signed = Parse::Pidl::Typelist::is_signed($l->{DATA_TYPE});
my ($low, $high) = split(/,/, $range, 2);
@@ -943,12 +947,11 @@ sub ParseMemCtxPullFlags($$$$)
if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
my $nl = GetNextLevel($e, $l);
- my $next_is_array = ($nl->{TYPE} eq "ARRAY");
- my $next_is_string = (($nl->{TYPE} eq "DATA") and
- ($nl->{DATA_TYPE} eq "string"));
- if ($next_is_array or $next_is_string) {
- return undef;
- } elsif ($l->{LEVEL} eq "TOP") {
+ return undef if ($nl->{TYPE} eq "PIPE");
+ return undef if ($nl->{TYPE} eq "ARRAY");
+ return undef if (($nl->{TYPE} eq "DATA") and ($nl->{DATA_TYPE} eq "string"));
+
+ if ($l->{LEVEL} eq "TOP") {
$mem_flags = "LIBNDR_FLAG_REF_ALLOC";
}
}
@@ -1010,6 +1013,20 @@ sub ParseElementPullLevel
} elsif ($l->{TYPE} eq "ARRAY") {
my $length = $self->ParseArrayPullHeader($e, $l, $ndr, $var_name, $env);
+ if (my $range = has_property($e, "range")) {
+ my ($low, $high) = split(/,/, $range, 2);
+ if ($low < 0) {
+ warning(0, "$low is invalid for the range of an array size");
+ }
+ if ($low == 0) {
+ $self->pidl("if ($length > $high) {");
+ } else {
+ $self->pidl("if ($length < $low || $length > $high) {");
+ }
+ $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");");
+ $self->pidl("}");
+ }
+
my $nl = GetNextLevel($e, $l);
if (is_charset_array($e,$l)) {
@@ -1042,7 +1059,7 @@ sub ParseElementPullLevel
$self->pidl("if ($var_name) {");
$self->indent;
- if ($l->{POINTER_TYPE} eq "relative") {
+ if ($l->{POINTER_TYPE} eq "relative" or $l->{POINTER_TYPE} eq "relative_short") {
$self->pidl("uint32_t _relative_save_offset;");
$self->pidl("_relative_save_offset = $ndr->offset;");
$self->pidl("NDR_CHECK(ndr_pull_relative_ptr2($ndr, $var_name));");
@@ -1057,7 +1074,12 @@ sub ParseElementPullLevel
$self->ParseMemCtxPullEnd($e, $l, $ndr);
if ($l->{POINTER_TYPE} ne "ref") {
- if ($l->{POINTER_TYPE} eq "relative") {
+ if ($l->{POINTER_TYPE} eq "relative") {
+ $self->pidl("if ($ndr->offset > $ndr->relative_highest_offset) {");
+ $self->indent;
+ $self->pidl("$ndr->relative_highest_offset = $ndr->offset;");
+ $self->deindent;
+ $self->pidl("}");
$self->pidl("$ndr->offset = _relative_save_offset;");
}
$self->deindent;
@@ -1073,6 +1095,20 @@ sub ParseElementPullLevel
$length = "ndr_get_array_length($ndr, " . get_pointer_to($var_name) .")";
}
+ if (my $range = has_property($e, "range")) {
+ my ($low, $high) = split(/,/, $range, 2);
+ if ($low < 0) {
+ warning(0, "$low is invalid for the range of an array size");
+ }
+ if ($low == 0) {
+ $self->pidl("if ($length > $high) {");
+ } else {
+ $self->pidl("if ($length < $low || $length > $high) {");
+ }
+ $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");");
+ $self->pidl("}");
+ }
+
$var_name = get_array_element($var_name, $counter);
$self->ParseMemCtxPullStart($e, $l, $ndr, $array_name);
@@ -1116,6 +1152,8 @@ sub ParseElementPull($$$$$$)
my $represent_name;
my $transmit_name;
+ return if ContainsPipe($e, $e->{LEVELS}[0]);
+
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
@@ -1161,7 +1199,7 @@ sub ParsePtrPull($$$$$)
$self->pidl("\tNDR_PULL_ALLOC($ndr, $var_name);");
$self->pidl("}");
}
-
+
return;
} elsif ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "EMBEDDED") {
$self->pidl("NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));");
@@ -1169,6 +1207,8 @@ sub ParsePtrPull($$$$$)
($l->{POINTER_TYPE} eq "relative") or
($l->{POINTER_TYPE} eq "full")) {
$self->pidl("NDR_CHECK(ndr_pull_generic_ptr($ndr, &_ptr_$e->{NAME}));");
+ } elsif ($l->{POINTER_TYPE} eq "relative_short") {
+ $self->pidl("NDR_CHECK(ndr_pull_relative_ptr_short($ndr, &_ptr_$e->{NAME}));");
} else {
die("Unhandled pointer type $l->{POINTER_TYPE}");
}
@@ -1189,7 +1229,7 @@ sub ParsePtrPull($$$$$)
}
#$self->pidl("memset($var_name, 0, sizeof($var_name));");
- if ($l->{POINTER_TYPE} eq "relative") {
+ if ($l->{POINTER_TYPE} eq "relative" or $l->{POINTER_TYPE} eq "relative_short") {
$self->pidl("NDR_CHECK(ndr_pull_relative_ptr1($ndr, $var_name, _ptr_$e->{NAME}));");
}
$self->deindent;
@@ -1454,6 +1494,7 @@ sub ParseStructPrint($$$$$)
$self->DeclareArrayVariables($_) foreach (@{$struct->{ELEMENTS}});
$self->pidl("ndr_print_struct($ndr, name, \"$name\");");
+ $self->pidl("if (r == NULL) { ndr_print_null($ndr); return; }");
$self->start_flags($struct, $ndr);
@@ -1470,9 +1511,13 @@ sub DeclarePtrVariables($$)
{
my ($self,$e) = @_;
foreach my $l (@{$e->{LEVELS}}) {
+ my $size = 32;
if ($l->{TYPE} eq "POINTER" and
not ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP")) {
- $self->pidl("uint32_t _ptr_$e->{NAME};");
+ if ($l->{POINTER_TYPE} eq "relative_short") {
+ $size = 16;
+ }
+ $self->pidl("uint${size}_t _ptr_$e->{NAME};");
last;
}
}
@@ -1602,7 +1647,7 @@ sub ParseStructNdrSize($$$$)
if (my $flags = has_property($t, "flag")) {
$self->pidl("flags |= $flags;");
}
- $self->pidl("return ndr_size_struct($varname, flags, (ndr_push_flags_fn_t)ndr_push_$name, ic);");
+ $self->pidl("return ndr_size_struct($varname, flags, (ndr_push_flags_fn_t)ndr_push_$name);");
}
sub DeclStruct($$$$)
@@ -1614,7 +1659,7 @@ sub DeclStruct($$$$)
sub ArgsStructNdrSize($$$)
{
my ($d, $name, $varname) = @_;
- return "const struct $name *$varname, struct smb_iconv_convenience *ic, int flags";
+ return "const struct $name *$varname, int flags";
}
$typefamily{STRUCT} = {
@@ -1637,7 +1682,7 @@ sub ParseUnionNdrSize($$$)
$self->pidl("flags |= $flags;");
}
- $self->pidl("return ndr_size_union($varname, flags, level, (ndr_push_flags_fn_t)ndr_push_$name, ic);");
+ $self->pidl("return ndr_size_union($varname, flags, level, (ndr_push_flags_fn_t)ndr_push_$name);");
}
sub ParseUnionPushPrimitives($$$$)
@@ -1646,14 +1691,23 @@ sub ParseUnionPushPrimitives($$$$)
my $have_default = 0;
- $self->pidl("int level = ndr_push_get_switch_value($ndr, $varname);");
+ $self->pidl("uint32_t level = ndr_push_get_switch_value($ndr, $varname);");
if (defined($e->{SWITCH_TYPE})) {
+ if (defined($e->{ALIGN})) {
+ $self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
+ }
+
$self->pidl("NDR_CHECK(ndr_push_$e->{SWITCH_TYPE}($ndr, NDR_SCALARS, level));");
}
if (defined($e->{ALIGN})) {
- $self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
+ if ($e->{IS_MS_UNION}) {
+ $self->pidl("/* ms_union is always aligned to the largest union arm*/");
+ $self->pidl("NDR_CHECK(ndr_push_align($ndr, $e->{ALIGN}));");
+ } else {
+ $self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
+ }
}
$self->pidl("switch (level) {");
@@ -1693,7 +1747,7 @@ sub ParseUnionPushDeferred($$$$)
my $have_default = 0;
- $self->pidl("int level = ndr_push_get_switch_value($ndr, $varname);");
+ $self->pidl("uint32_t level = ndr_push_get_switch_value($ndr, $varname);");
if (defined($e->{PROPERTIES}{relative_base})) {
# retrieve the current offset as base for relative pointers
# based on the toplevel struct/union
@@ -1752,7 +1806,7 @@ sub ParseUnionPrint($$$$$)
my ($self,$e,$ndr,$name,$varname) = @_;
my $have_default = 0;
- $self->pidl("int level;");
+ $self->pidl("uint32_t level;");
foreach my $el (@{$e->{ELEMENTS}}) {
$self->DeclareArrayVariables($el);
}
@@ -1793,7 +1847,12 @@ sub ParseUnionPullPrimitives($$$$$)
my ($self,$e,$ndr,$varname,$switch_type) = @_;
my $have_default = 0;
+
if (defined($switch_type)) {
+ if (defined($e->{ALIGN})) {
+ $self->pidl("NDR_CHECK(ndr_pull_union_align($ndr, $e->{ALIGN}));");
+ }
+
$self->pidl("NDR_CHECK(ndr_pull_$switch_type($ndr, NDR_SCALARS, &_level));");
$self->pidl("if (_level != level) {");
$self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $varname at \%s\", _level, __location__);");
@@ -1801,7 +1860,12 @@ sub ParseUnionPullPrimitives($$$$$)
}
if (defined($e->{ALIGN})) {
- $self->pidl("NDR_CHECK(ndr_pull_union_align($ndr, $e->{ALIGN}));");
+ if ($e->{IS_MS_UNION}) {
+ $self->pidl("/* ms_union is always aligned to the largest union arm*/");
+ $self->pidl("NDR_CHECK(ndr_pull_align($ndr, $e->{ALIGN}));");
+ } else {
+ $self->pidl("NDR_CHECK(ndr_pull_union_align($ndr, $e->{ALIGN}));");
+ }
}
$self->pidl("switch (level) {");
@@ -1879,7 +1943,7 @@ sub ParseUnionPull($$$$)
my ($self,$e,$ndr,$varname) = @_;
my $switch_type = $e->{SWITCH_TYPE};
- $self->pidl("int level;");
+ $self->pidl("uint32_t level;");
if (defined($switch_type)) {
if (Parse::Pidl::Typelist::typeIs($switch_type, "ENUM")) {
$switch_type = Parse::Pidl::Typelist::enum_type_fn(getType($switch_type)->{DATA});
@@ -1925,7 +1989,7 @@ sub DeclUnion($$$$)
sub ArgsUnionNdrSize($$)
{
my ($d,$name) = @_;
- return "const union $name *r, uint32_t level, struct smb_iconv_convenience *ic, int flags";
+ return "const union $name *r, uint32_t level, int flags";
}
$typefamily{UNION} = {
@@ -2003,6 +2067,99 @@ $typefamily{TYPEDEF} = {
SIZE_FN_BODY => \&ParseTypedefNdrSize,
};
+sub ParsePipePushChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "push", $name, $varname);
+
+ $self->fn_declare("push", $struct, "enum ndr_err_code ndr_push_$name(struct ndr_push *$ndr, int ndr_flags, $args)") or return;
+
+ return if has_property($t, "nopush");
+
+ $self->pidl("{");
+ $self->indent;
+
+ $self->ParseStructPush($struct, $ndr, $varname);
+ $self->pidl("");
+
+ $self->pidl("NDR_CHECK(ndr_push_pipe_chunk_trailer(ndr, ndr_flags, $varname->count));");
+ $self->pidl("");
+
+ $self->pidl("return NDR_ERR_SUCCESS;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipePullChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "pull", $name, $varname);
+
+ $self->fn_declare("pull", $struct, "enum ndr_err_code ndr_pull_$name(struct ndr_pull *$ndr, int ndr_flags, $args)") or return;
+
+ return if has_property($struct, "nopull");
+
+ $self->pidl("{");
+ $self->indent;
+
+ $self->ParseStructPull($struct, $ndr, $varname);
+ $self->pidl("");
+
+ $self->pidl("NDR_CHECK(ndr_check_pipe_chunk_trailer($ndr, ndr_flags, $varname->count));");
+ $self->pidl("");
+
+ $self->pidl("return NDR_ERR_SUCCESS;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipePrintChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "print", $name, $varname);
+
+ $self->pidl_hdr("void ndr_print_$name(struct ndr_print *ndr, const char *name, $args);");
+
+ return if (has_property($t, "noprint"));
+
+ $self->pidl("_PUBLIC_ void ndr_print_$name(struct ndr_print *$ndr, const char *name, $args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->ParseTypePrint($struct, $ndr, $varname);
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
#####################################################################
# parse a function - print side
sub ParseFunctionPrint($$)
@@ -2023,6 +2180,7 @@ sub ParseFunctionPrint($$)
}
$self->pidl("ndr_print_struct($ndr, name, \"$fn->{NAME}\");");
+ $self->pidl("if (r == NULL) { ndr_print_null($ndr); return; }");
$self->pidl("$ndr->depth++;");
$self->pidl("if (flags & NDR_SET_VALUES) {");
@@ -2204,6 +2362,7 @@ sub ParseFunctionPull($$)
$e->{LEVELS}[0]->{POINTER_TYPE} eq "ref");
next if (($e->{LEVELS}[1]->{TYPE} eq "DATA") and
($e->{LEVELS}[1]->{DATA_TYPE} eq "string"));
+ next if ($e->{LEVELS}[1]->{TYPE} eq "PIPE");
next if (($e->{LEVELS}[1]->{TYPE} eq "ARRAY")
and $e->{LEVELS}[1]->{IS_ZERO_TERMINATED});
@@ -2219,6 +2378,12 @@ sub ParseFunctionPull($$)
} else {
$self->pidl("memset(r->out.$e->{NAME}, 0, ($size) * sizeof(*r->out.$e->{NAME}));");
}
+ } elsif ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") {
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $self->pidl("r->out.$e->{NAME} = r->in.$e->{NAME};");
+ } else {
+ $self->pidl("r->out.$e->{NAME} = NULL;");
+ }
} else {
$self->pidl("NDR_PULL_ALLOC($ndr, r->out.$e->{NAME});");
@@ -2277,17 +2442,102 @@ sub AuthServiceStruct($$$)
$self->pidl("");
}
+sub ParseGeneratePipeArray($$$)
+{
+ my ($self, $fn, $direction) = @_;
+
+ $self->pidl("static const struct ndr_interface_call_pipe $fn->{NAME}\_$direction\_pipes[] = {");
+ $self->indent;
+
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+ next unless (grep(/$direction/, @{$e->{DIRECTION}}));
+
+ my $cname = "$e->{TYPE}_chunk";
+
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("\"$direction.$e->{NAME}\",");
+ $self->pidl("\"$cname\",");
+ $self->pidl("sizeof(struct $cname),");
+ $self->pidl("(ndr_push_flags_fn_t) ndr_push_$cname,");
+ $self->pidl("(ndr_pull_flags_fn_t) ndr_pull_$cname,");
+ $self->pidl("(ndr_print_fn_t) ndr_print_$cname,");
+ $self->deindent;
+ $self->pidl("},");
+ }
+ $self->pidl("{ NULL, NULL, 0, NULL, NULL, NULL }");
+ $self->deindent;
+ $self->pidl("};");
+ $self->pidl("");
+}
+
+sub FunctionCallPipes($$)
+{
+ my ($self, $d) = @_;
+ return if not defined($d->{OPNUM});
+
+ my $in_pipes = 0;
+ my $out_pipes = 0;
+
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $in_pipes++;
+ }
+ if (grep(/out/, @{$e->{DIRECTION}})) {
+ $out_pipes++;
+ }
+ }
+
+ if ($in_pipes) {
+ $self->ParseGeneratePipeArray($d, "in");
+ }
+
+ if ($out_pipes) {
+ $self->ParseGeneratePipeArray($d, "out");
+ }
+}
+
sub FunctionCallEntry($$)
{
my ($self, $d) = @_;
return 0 if not defined($d->{OPNUM});
+
+ my $in_pipes = 0;
+ my $out_pipes = 0;
+
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $in_pipes++;
+ }
+ if (grep(/out/, @{$e->{DIRECTION}})) {
+ $out_pipes++;
+ }
+ }
+
+ my $in_pipes_ptr = "NULL";
+ my $out_pipes_ptr = "NULL";
+
+ if ($in_pipes) {
+ $in_pipes_ptr = "$d->{NAME}_in_pipes";
+ }
+
+ if ($out_pipes) {
+ $out_pipes_ptr = "$d->{NAME}_out_pipes";
+ }
+
$self->pidl("\t{");
$self->pidl("\t\t\"$d->{NAME}\",");
$self->pidl("\t\tsizeof(struct $d->{NAME}),");
$self->pidl("\t\t(ndr_push_flags_fn_t) ndr_push_$d->{NAME},");
$self->pidl("\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},");
$self->pidl("\t\t(ndr_print_function_t) ndr_print_$d->{NAME},");
- $self->pidl("\t\t".($d->{ASYNC}?"true":"false").",");
+ $self->pidl("\t\t{ $in_pipes, $in_pipes_ptr },");
+ $self->pidl("\t\t{ $out_pipes, $out_pipes_ptr },");
$self->pidl("\t},");
return 1;
}
@@ -2303,12 +2553,16 @@ sub FunctionTable($$)
return if ($#{$interface->{FUNCTIONS}}+1 == 0);
return unless defined ($interface->{PROPERTIES}->{uuid});
+ foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
+ $self->FunctionCallPipes($d);
+ }
+
$self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {");
foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
$count += $self->FunctionCallEntry($d);
}
- $self->pidl("\t{ NULL, 0, NULL, NULL, NULL, false }");
+ $self->pidl("\t{ NULL, 0, NULL, NULL, NULL }");
$self->pidl("};");
$self->pidl("");
@@ -2556,6 +2810,20 @@ sub ParseInterface($$$)
# Typedefs
foreach my $d (@{$interface->{TYPES}}) {
+ if (Parse::Pidl::Typelist::typeIs($d, "PIPE")) {
+ ($needed->{TypeFunctionName("ndr_push", $d)}) &&
+ $self->ParsePipePushChunk($d);
+ ($needed->{TypeFunctionName("ndr_pull", $d)}) &&
+ $self->ParsePipePullChunk($d);
+ ($needed->{TypeFunctionName("ndr_print", $d)}) &&
+ $self->ParsePipePrintChunk($d);
+
+ $needed->{TypeFunctionName("ndr_pull", $d)} = 0;
+ $needed->{TypeFunctionName("ndr_push", $d)} = 0;
+ $needed->{TypeFunctionName("ndr_print", $d)} = 0;
+ next;
+ }
+
next unless(typeHasBody($d));
($needed->{TypeFunctionName("ndr_push", $d)}) && $self->ParseTypePushFunction($d, "r");
@@ -2575,10 +2843,6 @@ sub ParseInterface($$$)
($needed->{"ndr_push_$d->{NAME}"}) && $self->ParseFunctionPush($d);
($needed->{"ndr_pull_$d->{NAME}"}) && $self->ParseFunctionPull($d);
($needed->{"ndr_print_$d->{NAME}"}) && $self->ParseFunctionPrint($d);
-
- # Make sure we don't generate a function twice...
- $needed->{"ndr_push_$d->{NAME}"} = $needed->{"ndr_pull_$d->{NAME}"} =
- $needed->{"ndr_print_$d->{NAME}"} = 0;
}
$self->FunctionTable($interface);
@@ -2701,6 +2965,7 @@ sub NeededType($$$)
my ($t,$needed,$req) = @_;
NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "TYPEDEF");
+ NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "PIPE");
if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "UNION") {
return unless defined($t->{ELEMENTS});
@@ -2722,6 +2987,7 @@ sub NeededInterface($$)
my ($interface,$needed) = @_;
NeededFunction($_, $needed) foreach (@{$interface->{FUNCTIONS}});
foreach (reverse @{$interface->{TYPES}}) {
+
if (has_property($_, "public")) {
$needed->{TypeFunctionName("ndr_pull", $_)} = $needed->{TypeFunctionName("ndr_push", $_)} =
$needed->{TypeFunctionName("ndr_print", $_)} = 1;
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
index bb0c18e13c..20c94c89e0 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
@@ -81,7 +81,7 @@ sub Boilerplate_Iface($)
my $if_version = $interface->{PROPERTIES}->{version};
pidl "
-static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
+static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version)
{
#ifdef DCESRV_INTERFACE_$uname\_BIND
return DCESRV_INTERFACE_$uname\_BIND(dce_call,iface);
diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index c785619adb..db2d79d2f6 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -12,7 +12,7 @@ use strict;
use Parse::Pidl qw(warning fatal error);
use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias);
use Parse::Pidl::Util qw(has_property ParseExpr unmake_str);
-use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
use Parse::Pidl::Samba4 qw(ArrayDynamicallyAllocated);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
@@ -24,8 +24,9 @@ sub new($) {
my ($class) = @_;
my $self = { res => "", res_hdr => "", tabs => "", constants => {},
module_methods => [], module_objects => [], ready_types => [],
- module_imports => [], type_imports => {},
- patch_type_calls => [], readycode => [] };
+ module_imports => {}, type_imports => {},
+ patch_type_calls => [], prereadycode => [],
+ postreadycode => []};
bless($self, $class);
}
@@ -63,8 +64,11 @@ sub PrettifyTypeName($$)
{
my ($name, $basename) = @_;
+ $basename =~ s/^.*\.([^.]+)$/\1/;
+
$name =~ s/^$basename\_//;
+
return $name;
}
@@ -76,7 +80,7 @@ sub Import
$_ = unmake_str($_);
s/\.idl$//;
$self->pidl_hdr("#include \"librpc/gen_ndr/$_\.h\"\n");
- $self->register_module_import($_);
+ $self->register_module_import("samba.dcerpc.$_");
}
}
@@ -126,6 +130,7 @@ sub FromUnionToPythonFunction($$$$)
$self->ConvertObjectToPython($mem_ctx, {}, $e, "$name->$e->{NAME}", "ret", "return NULL;");
} else {
$self->pidl("ret = Py_None;");
+ $self->pidl("Py_INCREF(ret);");
}
$self->pidl("return ret;");
@@ -213,7 +218,7 @@ sub PythonStruct($$$$$$)
if ($l->{TYPE} eq "POINTER" and
not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and
not ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE}))) {
- $self->pidl("talloc_free($varname);");
+ $self->pidl("talloc_unlink(py_talloc_get_mem_ctx(py_obj), $varname);");
}
$self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;");
$self->pidl("return 0;");
@@ -253,7 +258,7 @@ sub PythonStruct($$$$$$)
$self->pidl("$cname *object = ($cname *)py_talloc_get_ptr(py_obj);");
$self->pidl("DATA_BLOB blob;");
$self->pidl("enum ndr_err_code err;");
- $self->pidl("err = ndr_push_struct_blob(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_push_flags_fn_t)ndr_push_$name);");
+ $self->pidl("err = ndr_push_struct_blob(&blob, py_talloc_get_mem_ctx(py_obj), object, (ndr_push_flags_fn_t)ndr_push_$name);");
$self->pidl("if (err != NDR_ERR_SUCCESS) {");
$self->indent;
$self->pidl("PyErr_SetNdrError(err);");
@@ -275,24 +280,7 @@ sub PythonStruct($$$$$$)
$self->pidl("if (!PyArg_ParseTuple(args, \"s#:__ndr_unpack__\", &blob.data, &blob.length))");
$self->pidl("\treturn NULL;");
$self->pidl("");
-
- # This disgusting hack works around the fact that ndr_pull_struct_blob_all will always fail on structures with relative pointers.
- # So, map ndr_unpack to ndr_pull_struct_blob_all only if we don't have any relative pointers in this
- my $got_relative = 0;
- if ($#{$d->{ELEMENTS}} > -1) {
- foreach my $e (@{$d->{ELEMENTS}}) {
- my $l = $e->{LEVELS}[0];
- if ($l->{TYPE} eq "POINTER" and ($l->{POINTER_TYPE} eq "relative")) {
- $got_relative = 1;
- last;
- }
- }
- }
- if ($got_relative == 0) {
- $self->pidl("err = ndr_pull_struct_blob_all(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);");
- } else {
- $self->pidl("err = ndr_pull_struct_blob(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);");
- }
+ $self->pidl("err = ndr_pull_struct_blob_all(&blob, py_talloc_get_mem_ctx(py_obj), object, (ndr_pull_flags_fn_t)ndr_pull_$name);");
$self->pidl("if (err != NDR_ERR_SUCCESS) {");
$self->indent;
$self->pidl("PyErr_SetNdrError(err);");
@@ -304,11 +292,29 @@ sub PythonStruct($$$$$$)
$self->deindent;
$self->pidl("}");
$self->pidl("");
+
+ $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("$cname *object = ($cname *)py_talloc_get_ptr(py_obj);");
+ $self->pidl("PyObject *ret;");
+ $self->pidl("char *retstr;");
+ $self->pidl("");
+ $self->pidl("retstr = ndr_print_struct_string(py_talloc_get_mem_ctx(py_obj), (ndr_print_fn_t)ndr_print_$name, \"$name\", object);");
+ $self->pidl("ret = PyString_FromString(retstr);");
+ $self->pidl("talloc_free(retstr);");
+ $self->pidl("");
+ $self->pidl("return ret;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
$py_methods = "py_$name\_methods";
$self->pidl("static PyMethodDef $py_methods\[] = {");
$self->indent;
- $self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.pack() -> blob\\nNDR pack\" },");
- $self->pidl("{ \"__ndr_unpack__\", (PyCFunction)py_$name\_ndr_unpack, METH_VARARGS, \"S.unpack(blob) -> None\\nNDR unpack\" },");
+ $self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.ndr_pack(object) -> blob\\nNDR pack\" },");
+ $self->pidl("{ \"__ndr_unpack__\", (PyCFunction)py_$name\_ndr_unpack, METH_VARARGS, \"S.ndr_unpack(class, blob) -> None\\nNDR unpack\" },");
+ $self->pidl("{ \"__ndr_print__\", (PyCFunction)py_$name\_ndr_print, METH_VARARGS, \"S.ndr_print(object) -> None\\nNDR print\" },");
$self->pidl("{ NULL, NULL, 0, NULL }");
$self->deindent;
$self->pidl("};");
@@ -323,21 +329,22 @@ sub PythonStruct($$$$$$)
$self->indent;
$self->pidl("PyObject_HEAD_INIT(NULL) 0,");
$self->pidl(".tp_name = \"$modulename.$prettyname\",");
- $self->pidl(".tp_basicsize = sizeof(py_talloc_Object),");
- $self->pidl(".tp_dealloc = py_talloc_dealloc,");
$self->pidl(".tp_getset = $getsetters,");
- $self->pidl(".tp_repr = py_talloc_default_repr,");
if ($docstring) {
$self->pidl(".tp_doc = $docstring,");
}
$self->pidl(".tp_methods = $py_methods,");
$self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,");
+ $self->pidl(".tp_basicsize = sizeof(py_talloc_Object),");
$self->pidl(".tp_new = py_$name\_new,");
$self->deindent;
$self->pidl("};");
$self->pidl("");
+ my $talloc_typename = $self->import_type_variable("talloc", "Object");
+ $self->register_module_prereadycode(["$name\_Type.tp_base = $talloc_typename;", ""]);
+
return "&$typeobject";
}
@@ -388,7 +395,7 @@ sub PythonFunctionUnpackOut($$$)
$self->pidl("static PyObject *$outfnname(struct $fn->{NAME} *r)");
$self->pidl("{");
$self->indent;
- $self->pidl("PyObject *result = Py_None;");
+ $self->pidl("PyObject *result;");
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless (grep(/out/,@{$e->{DIRECTION}}));
next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or
@@ -407,6 +414,8 @@ sub PythonFunctionUnpackOut($$$)
$self->pidl("result = PyTuple_New($result_size);");
$signature .= "(";
} elsif ($result_size == 0) {
+ $self->pidl("result = Py_None;");
+ $self->pidl("Py_INCREF(result);");
$signature .= "None";
}
@@ -505,7 +514,7 @@ sub PythonFunctionPackIn($$$)
if ($metadata_args->{in}->{$e->{NAME}}) {
my $py_var = "py_".$metadata_args->{in}->{$e->{NAME}};
$self->pidl("PY_CHECK_TYPE(&PyList_Type, $py_var, $fail);");
- my $val = "PyList_Size($py_var)";
+ my $val = "PyList_GET_SIZE($py_var)";
if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") {
$self->pidl("r->in.$e->{NAME} = talloc_ptrtype(r, r->in.$e->{NAME});");
$self->pidl("*r->in.$e->{NAME} = $val;");
@@ -530,22 +539,13 @@ sub PythonFunction($$$)
my $fnname = "py_$fn->{NAME}";
my $docstring = $self->DocString($fn, $fn->{NAME});
- my ($insignature, $outsignature);
- my ($infn, $outfn);
-
- if (has_property($fn, "todo")) {
- unless ($docstring) { $docstring = "NULL"; }
- $infn = "NULL";
- $outfn = "NULL";
+ my ($infn, $insignature) = $self->PythonFunctionPackIn($fn, $fnname);
+ my ($outfn, $outsignature) = $self->PythonFunctionUnpackOut($fn, $fnname);
+ my $signature = "S.$prettyname($insignature) -> $outsignature";
+ if ($docstring) {
+ $docstring = "\"$signature\\n\\n\"$docstring";
} else {
- ($infn, $insignature) = $self->PythonFunctionPackIn($fn, $fnname);
- ($outfn, $outsignature) = $self->PythonFunctionUnpackOut($fn, $fnname);
- my $signature = "S.$prettyname($insignature) -> $outsignature";
- if ($docstring) {
- $docstring = "\"$signature\\n\\n\"$docstring";
- } else {
- $docstring = "\"$signature\"";
- }
+ $docstring = "\"$signature\"";
}
return ($infn, $outfn, $docstring);
@@ -663,8 +663,18 @@ sub Interface($$$)
my @fns = ();
foreach my $d (@{$interface->{FUNCTIONS}}) {
- next if not defined($d->{OPNUM});
+ next if has_property($d, "noopnum");
next if has_property($d, "nopython");
+ next if has_property($d, "todo");
+
+ my $skip = 0;
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ if (ContainsPipe($e, $e->{LEVELS}[0])) {
+ $skip = 1;
+ last;
+ }
+ }
+ next if $skip;
my $prettyname = $d->{NAME};
@@ -673,14 +683,14 @@ sub Interface($$$)
my ($infn, $outfn, $fndocstring) = $self->PythonFunction($d, $interface->{NAME}, $prettyname);
- push (@fns, [$infn, $outfn, "dcerpc_$d->{NAME}", $prettyname, $fndocstring, $d->{OPNUM}]);
+ push (@fns, [$infn, $outfn, "dcerpc_$d->{NAME}_r", $prettyname, $fndocstring, $d->{OPNUM}]);
}
$self->pidl("const struct PyNdrRpcMethodDef py_ndr_$interface->{NAME}\_methods[] = {");
$self->indent;
foreach my $d (@fns) {
my ($infn, $outfn, $callfn, $prettyname, $docstring, $opnum) = @$d;
- $self->pidl("{ \"$prettyname\", $docstring, (dcerpc_call_fn)$callfn, (py_data_pack_fn)$infn, (py_data_unpack_fn)$outfn, $opnum, &ndr_table_$interface->{NAME} },");
+ $self->pidl("{ \"$prettyname\", $docstring, (py_dcerpc_call_fn)$callfn, (py_data_pack_fn)$infn, (py_data_unpack_fn)$outfn, $opnum, &ndr_table_$interface->{NAME} },");
}
$self->pidl("{ NULL }");
$self->deindent;
@@ -711,12 +721,13 @@ sub Interface($$$)
$docstring = $signature;
}
- $self->pidl("static PyTypeObject $interface->{NAME}_InterfaceType = {");
+ my $if_typename = "$interface->{NAME}_InterfaceType";
+
+ $self->pidl("static PyTypeObject $if_typename = {");
$self->indent;
$self->pidl("PyObject_HEAD_INIT(NULL) 0,");
$self->pidl(".tp_name = \"$basename.$interface->{NAME}\",");
$self->pidl(".tp_basicsize = sizeof(dcerpc_InterfaceObject),");
- $self->pidl(".tp_base = &dcerpc_InterfaceType,");
$self->pidl(".tp_doc = $docstring,");
$self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,");
$self->pidl(".tp_new = interface_$interface->{NAME}_new,");
@@ -725,8 +736,10 @@ sub Interface($$$)
$self->pidl("");
- $self->register_module_typeobject($interface->{NAME}, "&$interface->{NAME}_InterfaceType");
- $self->register_module_readycode(["if (!PyInterface_AddNdrRpcMethods(&$interface->{NAME}_InterfaceType, py_ndr_$interface->{NAME}\_methods))", "\treturn;", ""]);
+ $self->register_module_typeobject($interface->{NAME}, "&$if_typename");
+ my $dcerpc_typename = $self->import_type_variable("samba.dcerpc.base", "ClientConnection");
+ $self->register_module_prereadycode(["$if_typename.tp_base = $dcerpc_typename;", ""]);
+ $self->register_module_postreadycode(["if (!PyInterface_AddNdrRpcMethods(&$if_typename, py_ndr_$interface->{NAME}\_methods))", "\treturn;", ""]);
}
$self->pidl_hdr("\n");
@@ -743,7 +756,7 @@ sub register_module_typeobject($$$)
{
my ($self, $name, $py_name) = @_;
- $self->register_module_object($name, "(PyObject *)$py_name");
+ $self->register_module_object($name, "(PyObject *)(void *)$py_name");
$self->check_ready_type($py_name);
@@ -758,9 +771,26 @@ sub check_ready_type($$)
sub register_module_import($$)
{
- my ($self, $basename) = @_;
+ my ($self, $module_path) = @_;
+
+ my $var_name = $module_path;
+ $var_name =~ s/\./_/g;
+ $var_name = "dep_$var_name";
+
+ $self->{module_imports}->{$var_name} = $module_path;
+
+ return $var_name;
+}
+
+sub import_type_variable($$$)
+{
+ my ($self, $module, $name) = @_;
- push (@{$self->{module_imports}}, $basename) unless (grep(/^$basename$/,@{$self->{module_imports}}));
+ $self->register_module_import($module);
+ unless (defined($self->{type_imports}->{$name})) {
+ $self->{type_imports}->{$name} = $module;
+ }
+ return "$name\_Type";
}
sub use_type_variable($$)
@@ -768,7 +798,7 @@ sub use_type_variable($$)
my ($self, $orig_ctype) = @_;
# FIXME: Have a global lookup table for types that look different on the
# wire than they are named in C?
- if ($orig_ctype->{NAME} eq "dom_sid2") {
+ if ($orig_ctype->{NAME} eq "dom_sid2" or $orig_ctype->{NAME} eq "dom_sid28") {
$orig_ctype->{NAME} = "dom_sid";
}
my $ctype = resolveType($orig_ctype);
@@ -777,11 +807,7 @@ sub use_type_variable($$)
}
# If this is an external type, make sure we do the right imports.
if (($ctype->{BASEFILE} ne $self->{BASENAME})) {
- $self->register_module_import($ctype->{BASEFILE});
- unless (defined($self->{type_imports}->{$ctype->{NAME}})) {
- $self->{type_imports}->{$ctype->{NAME}} = $ctype->{BASEFILE};
- }
- return "$ctype->{NAME}_Type";
+ return $self->import_type_variable("samba.dcerpc.$ctype->{BASEFILE}", $ctype->{NAME});
}
return "&$ctype->{NAME}_Type";
}
@@ -794,11 +820,18 @@ sub register_patch_type_call($$$)
}
-sub register_module_readycode($$)
+sub register_module_prereadycode($$)
+{
+ my ($self, $code) = @_;
+
+ push (@{$self->{prereadycode}}, @$code);
+}
+
+sub register_module_postreadycode($$)
{
my ($self, $code) = @_;
- push (@{$self->{readycode}}, @$code);
+ push (@{$self->{postreadycode}}, @$code);
}
sub register_module_object($$$)
@@ -814,7 +847,8 @@ sub assign($$$)
if ($dest =~ /^\&/ and $src eq "NULL") {
$self->pidl("memset($dest, 0, sizeof(" . get_value_of($dest) . "));");
} elsif ($dest =~ /^\&/) {
- $self->pidl("memcpy($dest, $src, sizeof(" . get_value_of($dest) . "));");
+ my $destvar = get_value_of($dest);
+ $self->pidl("$destvar = *$src;");
} else {
$self->pidl("$dest = $src;");
}
@@ -833,42 +867,103 @@ sub ConvertObjectFromPythonData($$$$$$;$)
$actual_ctype = $actual_ctype->{DATA};
}
- if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or
- $actual_ctype->{TYPE} eq "SCALAR" and (
- expandAlias($actual_ctype->{NAME}) =~ /^(u?int[0-9]*|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong|udlongr)$/)) {
- $self->pidl("PY_CHECK_TYPE(&PyInt_Type, $cvar, $fail);");
+ if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP") {
+ $self->pidl("if (PyLong_Check($cvar)) {");
+ $self->indent;
+ $self->pidl("$target = PyLong_AsLongLong($cvar);");
+ $self->deindent;
+ $self->pidl("} else if (PyInt_Check($cvar)) {");
+ $self->indent;
$self->pidl("$target = PyInt_AsLong($cvar);");
+ $self->deindent;
+ $self->pidl("} else {");
+ $self->indent;
+ $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
+ $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name);");
+ $self->pidl($fail);
+ $self->deindent;
+ $self->pidl("}");
return;
}
+ if ($actual_ctype->{TYPE} eq "SCALAR" ) {
+ if (expandAlias($actual_ctype->{NAME}) =~ /^(u?int64|hyper|dlong|udlong|udlongr|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) {
+ $self->pidl("if (PyLong_Check($cvar)) {");
+ $self->indent;
+ $self->pidl("$target = PyLong_AsLongLong($cvar);");
+ $self->deindent;
+ $self->pidl("} else if (PyInt_Check($cvar)) {");
+ $self->indent;
+ $self->pidl("$target = PyInt_AsLong($cvar);");
+ $self->deindent;
+ $self->pidl("} else {");
+ $self->indent;
+ $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
+ $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name);");
+ $self->pidl($fail);
+ $self->deindent;
+ $self->pidl("}");
+ return;
+ }
+ if (expandAlias($actual_ctype->{NAME}) =~ /^(char|u?int[0-9]*|time_t|uid_t|gid_t)$/) {
+ $self->pidl("PY_CHECK_TYPE(&PyInt_Type, $cvar, $fail);");
+ $self->pidl("$target = PyInt_AsLong($cvar);");
+ return;
+ }
+ }
if ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
my $ctype_name = $self->use_type_variable($ctype);
unless (defined ($ctype_name)) {
error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
- $self->pidl("PyErr_SetString(PyExc_TypeError, \"Can not convert C Type " . mapTypeName($ctype) . " to Python\");");
+ $self->pidl("PyErr_SetString(PyExc_TypeError, \"Can not convert C Type " . mapTypeName($ctype) . " from Python\");");
return;
}
$self->pidl("PY_CHECK_TYPE($ctype_name, $cvar, $fail);");
- $self->assign($target, "py_talloc_get_ptr($cvar)");
+ $self->pidl("if (talloc_reference($mem_ctx, py_talloc_get_mem_ctx($cvar)) == NULL) {");
+ $self->indent;
+ $self->pidl("PyErr_NoMemory();");
+ $self->pidl("$fail");
+ $self->deindent;
+ $self->pidl("}");
+ $self->assign($target, "(".mapTypeName($ctype)." *)py_talloc_get_ptr($cvar)");
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "DATA_BLOB") {
- $self->pidl("$target = data_blob_talloc($mem_ctx, PyString_AsString($cvar), PyString_Size($cvar));");
+ $self->pidl("$target = data_blob_talloc($mem_ctx, PyString_AS_STRING($cvar), PyString_GET_SIZE($cvar));");
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and
($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) {
- $self->pidl("$target = talloc_strdup($mem_ctx, PyString_AsString($cvar));");
+ $self->pidl("$target = talloc_strdup($mem_ctx, PyString_AS_STRING($cvar));");
+ return;
+ }
+
+ if ($actual_ctype->{TYPE} eq "SCALAR" and ($actual_ctype->{NAME} eq "dns_string" or $actual_ctype->{NAME} eq "dns_name")) {
+ $self->pidl("$target = talloc_strdup($mem_ctx, PyString_AS_STRING($cvar));");
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") {
+ $self->pidl("$target = PyString_AS_STRING($cvar);");
+ return;
+ }
+
+ if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv6address") {
$self->pidl("$target = PyString_AsString($cvar);");
return;
- }
+ }
+ if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "dnsp_name") {
+ $self->pidl("$target = PyString_AS_STRING($cvar);");
+ return;
+ }
+
+ if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "dnsp_string") {
+ $self->pidl("$target = PyString_AS_STRING($cvar);");
+ return;
+ }
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
$self->pidl("$target = NT_STATUS(PyInt_AsLong($cvar));");
@@ -898,12 +993,15 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
{
my ($self, $env, $mem_ctx, $py_var, $e, $l, $var_name, $fail) = @_;
my $nl = GetNextLevel($e, $l);
+ if ($nl and $nl->{TYPE} eq "SUBCONTEXT") {
+ $nl = GetNextLevel($e, $nl);
+ }
+ my $pl = GetPrevLevel($e, $l);
+ if ($pl and $pl->{TYPE} eq "SUBCONTEXT") {
+ $pl = GetPrevLevel($e, $pl);
+ }
if ($l->{TYPE} eq "POINTER") {
- if ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail);
- return;
- }
if ($l->{POINTER_TYPE} ne "ref") {
$self->pidl("if ($py_var == Py_None) {");
$self->indent;
@@ -912,22 +1010,45 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
$self->pidl("} else {");
$self->indent;
}
- $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, get_value_of($var_name), $fail);
+ # if we want to handle more than one level of pointer in python interfaces
+ # then this is where we would need to allocate it
+ if ($l->{POINTER_TYPE} eq "ref") {
+ $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
+ } elsif ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::is_scalar($nl->{DATA_TYPE})
+ and not Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
+ $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
+ } else {
+ $self->pidl("$var_name = NULL;");
+ }
+ unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
+ $var_name = get_value_of($var_name);
+ }
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail);
if ($l->{POINTER_TYPE} ne "ref") {
$self->deindent;
$self->pidl("}");
}
} elsif ($l->{TYPE} eq "ARRAY") {
- my $pl = GetPrevLevel($e, $l);
if ($pl && $pl->{TYPE} eq "POINTER") {
$var_name = get_pointer_to($var_name);
}
if (is_charset_array($e, $l)) {
- $self->pidl("PY_CHECK_TYPE(&PyUnicode_Type, $py_var, $fail);");
+ $self->pidl("if (PyUnicode_Check($py_var)) {");
+ $self->indent;
# FIXME: Use Unix charset setting rather than utf-8
- $self->pidl($var_name . " = PyString_AsString(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));");
+ $self->pidl($var_name . " = PyString_AS_STRING(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));");
+ $self->deindent;
+ $self->pidl("} else if (PyString_Check($py_var)) {");
+ $self->indent;
+ $self->pidl($var_name . " = PyString_AS_STRING($py_var);");
+ $self->deindent;
+ $self->pidl("} else {");
+ $self->indent;
+ $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected string or unicode object, got %s\", Py_TYPE($py_var)->tp_name);");
+ $self->pidl("$fail");
+ $self->deindent;
+ $self->pidl("}");
} else {
my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}";
$self->pidl("PY_CHECK_TYPE(&PyList_Type, $py_var, $fail);");
@@ -935,18 +1056,19 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
$self->indent;
$self->pidl("int $counter;");
if (ArrayDynamicallyAllocated($e, $l)) {
- $self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_Size($py_var));");
+ $self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_GET_SIZE($py_var));");
+ $self->pidl("if (!$var_name) { $fail; }");
+ $self->pidl("talloc_set_name_const($var_name, \"ARRAY: $var_name\");");
}
- $self->pidl("for ($counter = 0; $counter < PyList_Size($py_var); $counter++) {");
+ $self->pidl("for ($counter = 0; $counter < PyList_GET_SIZE($py_var); $counter++) {");
$self->indent;
- $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail);
+ $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, $var_name."[$counter]", $fail);
$self->deindent;
$self->pidl("}");
$self->deindent;
$self->pidl("}");
}
} elsif ($l->{TYPE} eq "DATA") {
-
if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
$var_name = get_pointer_to($var_name);
}
@@ -954,9 +1076,18 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
} elsif ($l->{TYPE} eq "SWITCH") {
$var_name = get_pointer_to($var_name);
my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e);
- $self->assign($var_name, "py_export_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $py_var)");
+ my $switch_ptr = "$e->{NAME}_switch_$l->{LEVEL_INDEX}";
+ $self->pidl("{");
+ $self->indent;
+ my $union_type = mapTypeName($nl->{DATA_TYPE});
+ $self->pidl("$union_type *$switch_ptr;");
+ $self->pidl("$switch_ptr = py_export_" . $nl->{DATA_TYPE} . "($mem_ctx, $switch, $py_var);");
+ $self->fail_on_null($switch_ptr, $fail);
+ $self->assign($var_name, "$switch_ptr");
+ $self->deindent;
+ $self->pidl("}");
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail);
} else {
fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}");
}
@@ -977,7 +1108,11 @@ sub ConvertScalarToPython($$$)
$ctypename = expandAlias($ctypename);
- if ($ctypename =~ /^(char|u?int[0-9]*|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) {
+ if ($ctypename =~ /^(u?int64|hyper|dlong|udlong|udlongr|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) {
+ return "PyLong_FromLongLong($cvar)";
+ }
+
+ if ($ctypename =~ /^(char|u?int[0-9]*|time_t|uid_t|gid_t)$/) {
return "PyInt_FromLong($cvar)";
}
@@ -994,12 +1129,19 @@ sub ConvertScalarToPython($$$)
}
if (($ctypename eq "string" or $ctypename eq "nbt_string" or $ctypename eq "nbt_name" or $ctypename eq "wrepl_nbt_name")) {
- return "PyString_FromString($cvar)";
+ return "PyString_FromStringOrNULL($cvar)";
+ }
+
+ if (($ctypename eq "dns_string" or $ctypename eq "dns_name")) {
+ return "PyString_FromStringOrNULL($cvar)";
}
# Not yet supported
if ($ctypename eq "string_array") { return "PyCObject_FromTallocPtr($cvar)"; }
- if ($ctypename eq "ipv4address") { return "PyString_FromString($cvar)"; }
+ if ($ctypename eq "ipv4address") { return "PyString_FromStringOrNULL($cvar)"; }
+ if ($ctypename eq "ipv6address") { return "PyString_FromStringOrNULL($cvar)"; }
+ if ($ctypename eq "dnsp_name") { return "PyString_FromStringOrNULL($cvar)"; }
+ if ($ctypename eq "dnsp_string") { return "PyString_FromStringOrNULL($cvar)"; }
if ($ctypename eq "pointer") {
return "PyCObject_FromTallocPtr($cvar)";
}
@@ -1054,34 +1196,50 @@ sub ConvertObjectToPythonLevel($$$$$$)
{
my ($self, $mem_ctx, $env, $e, $l, $var_name, $py_var, $fail) = @_;
my $nl = GetNextLevel($e, $l);
+ if ($nl and $nl->{TYPE} eq "SUBCONTEXT") {
+ $nl = GetNextLevel($e, $nl);
+ }
+ my $pl = GetPrevLevel($e, $l);
+ if ($pl and $pl->{TYPE} eq "SUBCONTEXT") {
+ $pl = GetPrevLevel($e, $pl);
+ }
if ($l->{TYPE} eq "POINTER") {
- if ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
- $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name, $py_var, $fail);
- return;
- }
if ($l->{POINTER_TYPE} ne "ref") {
$self->pidl("if ($var_name == NULL) {");
$self->indent;
$self->pidl("$py_var = Py_None;");
+ $self->pidl("Py_INCREF($py_var);");
$self->deindent;
$self->pidl("} else {");
$self->indent;
}
- $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, get_value_of($var_name), $py_var, $fail);
+ my $var_name2 = $var_name;
+ unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
+ $var_name2 = get_value_of($var_name);
+ }
+ $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name2, $py_var, $fail);
if ($l->{POINTER_TYPE} ne "ref") {
$self->deindent;
$self->pidl("}");
}
} elsif ($l->{TYPE} eq "ARRAY") {
- my $pl = GetPrevLevel($e, $l);
if ($pl && $pl->{TYPE} eq "POINTER") {
$var_name = get_pointer_to($var_name);
}
if (is_charset_array($e, $l)) {
# FIXME: Use Unix charset setting rather than utf-8
+ $self->pidl("if ($var_name == NULL) {");
+ $self->indent;
+ $self->pidl("$py_var = Py_None;");
+ $self->pidl("Py_INCREF($py_var);");
+ $self->deindent;
+ $self->pidl("} else {");
+ $self->indent;
$self->pidl("$py_var = PyUnicode_Decode($var_name, strlen($var_name), \"utf-8\", \"ignore\");");
+ $self->deindent;
+ $self->pidl("}");
} else {
die("No SIZE_IS for array $var_name") unless (defined($l->{SIZE_IS}));
my $length = $l->{SIZE_IS};
@@ -1100,7 +1258,7 @@ sub ConvertObjectToPythonLevel($$$$$$)
$self->indent;
my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}";
$self->pidl("PyObject *$member_var;");
- $self->ConvertObjectToPythonLevel($var_name, $env, $e, GetNextLevel($e, $l), $var_name."[$counter]", $member_var, $fail);
+ $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name."[$counter]", $member_var, $fail);
$self->pidl("PyList_SetItem($py_var, $counter, $member_var);");
$self->deindent;
$self->pidl("}");
@@ -1110,7 +1268,7 @@ sub ConvertObjectToPythonLevel($$$$$$)
} elsif ($l->{TYPE} eq "SWITCH") {
$var_name = get_pointer_to($var_name);
my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e);
- $self->pidl("$py_var = py_import_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $var_name);");
+ $self->pidl("$py_var = py_import_" . $nl->{DATA_TYPE} . "($mem_ctx, $switch, $var_name);");
$self->fail_on_null($py_var, $fail);
} elsif ($l->{TYPE} eq "DATA") {
@@ -1120,7 +1278,7 @@ sub ConvertObjectToPythonLevel($$$$$$)
my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $e->{ORIGINAL});
$self->pidl("$py_var = $conv;");
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
- $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, GetNextLevel($e, $l), $var_name, $py_var, $fail);
+ $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, $nl, $var_name, $py_var, $fail);
} else {
fatal($e->{ORIGINAL}, "Unknown level type $l->{TYPE} $var_name");
}
@@ -1141,18 +1299,14 @@ sub Parse($$$$$)
$self->pidl_hdr("
/* Python wrapper functions auto-generated by pidl */
-#include \"includes.h\"
#include <Python.h>
-#include \"librpc/rpc/dcerpc.h\"
-#include \"lib/talloc/pytalloc.h\"
+#include \"includes.h\"
+#include <pytalloc.h>
#include \"librpc/rpc/pyrpc.h\"
+#include \"librpc/rpc/pyrpc_util.h\"
#include \"$hdr\"
#include \"$ndr_hdr\"
-#ifndef Py_RETURN_NONE
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
");
foreach my $x (@$ndr) {
@@ -1173,38 +1327,46 @@ sub Parse($$$$$)
$self->pidl("");
+ $self->pidl_hdr("void init$basename(void);");
$self->pidl("void init$basename(void)");
$self->pidl("{");
$self->indent;
$self->pidl("PyObject *m;");
- foreach (@{$self->{module_imports}}) {
- $self->pidl("PyObject *dep_$_;");
+ foreach (keys %{$self->{module_imports}}) {
+ $self->pidl("PyObject *$_;");
}
$self->pidl("");
- foreach (@{$self->{module_imports}}) {
- $self->pidl("dep_$_ = PyImport_ImportModule(\"samba.dcerpc.$_\");");
- $self->pidl("if (dep_$_ == NULL)");
+ foreach (keys %{$self->{module_imports}}) {
+ my $var_name = $_;
+ my $module_path = $self->{module_imports}->{$var_name};
+ $self->pidl("$var_name = PyImport_ImportModule(\"$module_path\");");
+ $self->pidl("if ($var_name == NULL)");
$self->pidl("\treturn;");
$self->pidl("");
}
foreach (keys %{$self->{type_imports}}) {
- my $basefile = $self->{type_imports}->{$_};
- $self->pidl_hdr("static PyTypeObject *$_\_Type;\n");
- my $pretty_name = PrettifyTypeName($_, $basefile);
- $self->pidl("$_\_Type = (PyTypeObject *)PyObject_GetAttrString(dep_$basefile, \"$pretty_name\");");
- $self->pidl("if ($_\_Type == NULL)");
+ my $type_var = "$_\_Type";
+ my $module_path = $self->{type_imports}->{$_};
+ $self->pidl_hdr("static PyTypeObject *$type_var;\n");
+ my $pretty_name = PrettifyTypeName($_, $module_path);
+ my $module_var = "dep_$module_path";
+ $module_var =~ s/\./_/g;
+ $self->pidl("$type_var = (PyTypeObject *)PyObject_GetAttrString($module_var, \"$pretty_name\");");
+ $self->pidl("if ($type_var == NULL)");
$self->pidl("\treturn;");
$self->pidl("");
}
+ $self->pidl($_) foreach (@{$self->{prereadycode}});
+
foreach (@{$self->{ready_types}}) {
$self->pidl("if (PyType_Ready($_) < 0)");
$self->pidl("\treturn;");
}
- $self->pidl($_) foreach (@{$self->{readycode}});
+ $self->pidl($_) foreach (@{$self->{postreadycode}});
foreach (@{$self->{patch_type_calls}}) {
my ($typename, $cvar) = @$_;
diff --git a/pidl/lib/Parse/Pidl/Typelist.pm b/pidl/lib/Parse/Pidl/Typelist.pm
index ca5ea0cfd2..4f26a92ed2 100644
--- a/pidl/lib/Parse/Pidl/Typelist.pm
+++ b/pidl/lib/Parse/Pidl/Typelist.pm
@@ -8,8 +8,8 @@ package Parse::Pidl::Typelist;
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(hasType getType resolveType mapTypeName scalar_is_reference expandAlias
- mapScalarType addType typeIs is_signed is_scalar enum_type_fn
- bitmap_type_fn mapType typeHasBody
+ mapScalarType addType typeIs is_signed is_scalar enum_type_fn
+ bitmap_type_fn mapType typeHasBody is_fixed_size_scalar
);
use vars qw($VERSION);
$VERSION = '0.01';
@@ -20,8 +20,14 @@ use strict;
my %types = ();
my @reference_scalars = (
- "string", "string_array", "nbt_string",
- "wrepl_nbt_name", "ipv4address"
+ "string", "string_array", "nbt_string", "dns_string",
+ "wrepl_nbt_name", "dnsp_name", "dnsp_string",
+ "ipv4address", "ipv6address"
+);
+
+my @non_fixed_size_scalars = (
+ "string", "string_array", "nbt_string", "dns_string",
+ "wrepl_nbt_name", "dnsp_name", "dnsp_string"
);
# a list of known scalar types
@@ -36,6 +42,8 @@ my %scalars = (
"uint1632" => "uint16_t",
"int32" => "int32_t",
"uint32" => "uint32_t",
+ "int3264" => "int32_t",
+ "uint3264" => "uint32_t",
"hyper" => "uint64_t",
"dlong" => "int64_t",
"udlong" => "uint64_t",
@@ -46,15 +54,21 @@ my %scalars = (
"string" => "const char *",
"string_array" => "const char **",
"time_t" => "time_t",
+ "uid_t" => "uid_t",
+ "gid_t" => "gid_t",
"NTTIME" => "NTTIME",
"NTTIME_1sec" => "NTTIME",
"NTTIME_hyper" => "NTTIME",
"WERROR" => "WERROR",
"NTSTATUS" => "NTSTATUS",
"COMRESULT" => "COMRESULT",
+ "dns_string" => "const char *",
"nbt_string" => "const char *",
"wrepl_nbt_name"=> "struct nbt_name *",
"ipv4address" => "const char *",
+ "ipv6address" => "const char *",
+ "dnsp_name" => "const char *",
+ "dnsp_string" => "const char *",
);
my %aliases = (
@@ -122,16 +136,19 @@ sub getType($)
return $types{$t};
}
+sub typeIs($$);
sub typeIs($$)
{
my ($t,$tt) = @_;
-
+
if (ref($t) eq "HASH") {
+ return 1 if ($t->{TYPE} eq "TYPEDEF" and $t->{DATA}->{TYPE} eq $tt);
return 1 if ($t->{TYPE} eq $tt);
return 0;
}
- return 1 if (hasType($t) and getType($t)->{TYPE} eq "TYPEDEF" and
- getType($t)->{DATA}->{TYPE} eq $tt);
+ if (hasType($t) and getType($t)->{TYPE} eq "TYPEDEF") {
+ return typeIs(getType($t)->{DATA}, $tt);
+ }
return 0;
}
@@ -179,6 +196,15 @@ sub is_scalar($)
return 0;
}
+sub is_fixed_size_scalar($)
+{
+ my $name = shift;
+
+ return 0 unless is_scalar($name);
+ return 0 if (grep(/^$name$/, @non_fixed_size_scalars));
+ return 1;
+}
+
sub scalar_is_reference($)
{
my $name = shift;
@@ -265,6 +291,7 @@ sub mapType($$)
return "struct $n" if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "INTERFACE");
return "union $n" if ($t->{TYPE} eq "UNION");
return mapScalarType(bitmap_type_fn($t)) if ($t->{TYPE} eq "BITMAP");
+ return "struct $n" if ($t->{TYPE} eq "PIPE");
die("Unknown type $t->{TYPE}");
}
@@ -303,11 +330,12 @@ sub LoadIdl($;$)
}) if (has_property($x, "object"));
foreach my $y (@{$x->{DATA}}) {
- if ($y->{TYPE} eq "TYPEDEF"
- or $y->{TYPE} eq "UNION"
- or $y->{TYPE} eq "STRUCT"
- or $y->{TYPE} eq "ENUM"
- or $y->{TYPE} eq "BITMAP") {
+ if ($y->{TYPE} eq "TYPEDEF"
+ or $y->{TYPE} eq "UNION"
+ or $y->{TYPE} eq "STRUCT"
+ or $y->{TYPE} eq "ENUM"
+ or $y->{TYPE} eq "BITMAP"
+ or $y->{TYPE} eq "PIPE") {
$y->{BASEFILE} = $basename;
addType($y);
}
diff --git a/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm b/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm
index 5c37b4a0c4..1dec647d87 100644
--- a/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm
+++ b/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm
@@ -110,6 +110,7 @@ use strict;
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property);
+use Parse::Pidl::Typelist qw(addType);
sub handle_type($$$$$$$$$$)
{
@@ -149,6 +150,17 @@ sub handle_type($$$$$$$$$$)
VALSSTRING => $valsstring,
ALIGNMENT => $alignment
};
+
+ addType({
+ NAME => $name,
+ TYPE => "CONFORMANCE",
+ BASEFILE => "conformance file",
+ DATA => {
+ NAME => $name,
+ TYPE => "CONFORMANCE",
+ ALIGN => $alignment
+ }
+ });
}
sub handle_tfs($$$$$)
diff --git a/pidl/lib/Parse/Pidl/Wireshark/NDR.pm b/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
index a9ad555cca..64b8dcf18c 100644
--- a/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
+++ b/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
@@ -1,5 +1,5 @@
##################################################
-# Samba4 NDR parser generator for IDL structures
+# Wireshark NDR parser generator for IDL structures
# Copyright tridge@samba.org 2000-2003
# Copyright tpot@samba.org 2001,2005
# Copyright jelmer@samba.org 2004-2007
@@ -545,6 +545,9 @@ sub Struct($$$$)
$self->indent;
$self->pidl_code("proto_item *item = NULL;");
$self->pidl_code("proto_tree *tree = NULL;");
+ if ($e->{ALIGN} > 1) {
+ $self->pidl_code("dcerpc_info *di = pinfo->private_data;");
+ }
$self->pidl_code("int old_offset;");
$self->pidl_code("");
@@ -565,6 +568,15 @@ sub Struct($$$$)
$self->pidl_code("\n$res");
$self->pidl_code("proto_item_set_len(item, offset-old_offset);\n");
+ if ($e->{ALIGN} > 1) {
+ $self->pidl_code("");
+ $self->pidl_code("if (di->call_data->flags & DCERPC_IS_NDR64) {");
+ $self->indent;
+ $self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
+ $self->deindent;
+ $self->pidl_code("}");
+ }
+ $self->pidl_code("");
$self->pidl_code("return offset;");
$self->deindent;
$self->pidl_code("}\n");
@@ -634,6 +646,8 @@ sub Union($$$$)
$self->pidl_code("switch(level) {$res\t}");
$self->pidl_code("proto_item_set_len(item, offset-old_offset);\n");
+ $self->pidl_code("");
+
$self->pidl_code("return offset;");
$self->deindent;
$self->pidl_code("}");
@@ -872,10 +886,10 @@ sub Initialize($$)
$self->register_type("dlong", "offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, drep, \@HF\@, NULL);","FT_INT64", "BASE_DEC", 0, "NULL", 8);
$self->register_type("GUID", "offset = dissect_ndr_uuid_t(tvb, offset, pinfo, tree, drep, \@HF\@, NULL);","FT_GUID", "BASE_NONE", 0, "NULL", 4);
$self->register_type("policy_handle", "offset = PIDL_dissect_policy_hnd(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_BYTES", "BASE_NONE", 0, "NULL", 4);
- $self->register_type("NTTIME", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);","FT_ABSOLUTE_TIME", "BASE_NONE", 0, "NULL", 4);
- $self->register_type("NTTIME_hyper", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);","FT_ABSOLUTE_TIME", "BASE_NONE", 0, "NULL", 4);
- $self->register_type("time_t", "offset = dissect_ndr_time_t(tvb, offset, pinfo,tree, drep, \@HF\@, NULL);","FT_ABSOLUTE_TIME", "BASE_NONE", 0, "NULL", 4);
- $self->register_type("NTTIME_1sec", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);", "FT_ABSOLUTE_TIME", "BASE_NONE", 0, "NULL", 4);
+ $self->register_type("NTTIME", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);","FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
+ $self->register_type("NTTIME_hyper", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);","FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
+ $self->register_type("time_t", "offset = dissect_ndr_time_t(tvb, offset, pinfo,tree, drep, \@HF\@, NULL);","FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
+ $self->register_type("NTTIME_1sec", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);", "FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
$self->register_type("SID", "
dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
@@ -895,7 +909,7 @@ sub Initialize($$)
sub Parse($$$$$)
{
my($self,$ndr,$idl_file,$h_filename,$cnf_file) = @_;
-
+
$self->Initialize($cnf_file);
return (undef, undef) if defined($self->{conformance}->{noemit_dissector});
diff --git a/pidl/lib/wscript_build b/pidl/lib/wscript_build
new file mode 100644
index 0000000000..eb5f1e0c37
--- /dev/null
+++ b/pidl/lib/wscript_build
@@ -0,0 +1,4 @@
+#!/usr/bin/env python
+
+# install the pidl modules
+bld.INSTALL_WILDCARD('${DATAROOTDIR}/perl5', '**/*.pm', flat=False)
diff --git a/pidl/pidl b/pidl/pidl
index bc0bb3524b..2a46e92925 100755
--- a/pidl/pidl
+++ b/pidl/pidl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
###################################################
# package to parse IDL files and generate code for
@@ -653,7 +653,18 @@ sub process_file($)
$pidl = Parse::Pidl::ODL::ODL2IDL($pidl, dirname($idl_file), \@opt_incdirs);
- if (defined($opt_ws_parser) or
+ if (defined($opt_ws_parser)) {
+ require Parse::Pidl::Wireshark::NDR;
+
+ my $cnffile = $idl_file;
+ $cnffile =~ s/\.idl$/\.cnf/;
+
+ my $generator = new Parse::Pidl::Wireshark::NDR();
+ $generator->Initialize($cnffile);
+ }
+
+
+ if (defined($opt_ws_parser) or
defined($opt_client) or
defined($opt_server) or
defined($opt_header) or
@@ -681,13 +692,15 @@ sub process_file($)
}
my $h_filename = "$outputdir/ndr_$basename.h";
- if (defined($opt_client)) {
+ my $c_header = "$outputdir/ndr_$basename\_c.h";
+ if (defined($opt_client) or defined($opt_samba3_ndr_client)) {
require Parse::Pidl::Samba4::NDR::Client;
my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c");
- my ($c_header) = $c_client;
+ $c_header = $c_client;
$c_header =~ s/\.c$/.h/;
- my ($srcd,$hdrd) = Parse::Pidl::Samba4::NDR::Client::Parse(
+ my $generator = new Parse::Pidl::Samba4::NDR::Client();
+ my ($srcd,$hdrd) = $generator->Parse(
$ndr,$gen_header,$h_filename,$c_header);
FileSave($c_client, $srcd);
@@ -760,7 +773,7 @@ sub process_file($)
my $header = $client; $header =~ s/\.c$/\.h/;
require Parse::Pidl::Samba3::ClientNDR;
my $generator = new Parse::Pidl::Samba3::ClientNDR();
- my ($c_code,$h_code) = $generator->Parse($ndr, $header, $h_filename);
+ my ($c_code,$h_code) = $generator->Parse($ndr, $header, $c_header);
FileSave($client, $c_code);
FileSave($header, $h_code);
}
diff --git a/pidl/tests/Util.pm b/pidl/tests/Util.pm
index ff876ec039..63949eb5a3 100644
--- a/pidl/tests/Util.pm
+++ b/pidl/tests/Util.pm
@@ -76,7 +76,6 @@ SKIP: {
}
my $main = "
-#define uint_t unsigned int
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
diff --git a/pidl/tests/ndr.pl b/pidl/tests/ndr.pl
index 53b8cb89e3..b6fd4899b0 100755
--- a/pidl/tests/ndr.pl
+++ b/pidl/tests/ndr.pl
@@ -22,7 +22,7 @@ my $e = {
'PARENT' => { TYPE => 'STRUCT' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "unique"), [
+is_deeply(GetElementLevelTable($e, "unique", 0), [
{
'IS_DEFERRED' => 0,
'LEVEL_INDEX' => 0,
@@ -33,7 +33,7 @@ is_deeply(GetElementLevelTable($e, "unique"), [
}
]);
-my $ne = ParseElement($e, "unique");
+my $ne = ParseElement($e, "unique", 0);
is($ne->{ORIGINAL}, $e);
is($ne->{NAME}, "v");
is($ne->{ALIGN}, 1);
@@ -60,7 +60,7 @@ $e = {
'TYPE' => 'uint8',
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "unique"), [
+is_deeply(GetElementLevelTable($e, "unique", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -90,7 +90,7 @@ $e = {
'PARENT' => { TYPE => 'STRUCT' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "unique"), [
+is_deeply(GetElementLevelTable($e, "unique", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -128,7 +128,7 @@ $e = {
'PARENT' => { TYPE => 'STRUCT' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "unique"), [
+is_deeply(GetElementLevelTable($e, "unique", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -158,7 +158,7 @@ $e = {
'PARENT' => { TYPE => 'STRUCT' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "unique"), [
+is_deeply(GetElementLevelTable($e, "unique", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -204,7 +204,7 @@ $e = {
'PARENT' => { TYPE => 'STRUCT' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "ref"), [
+is_deeply(GetElementLevelTable($e, "ref", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -250,7 +250,7 @@ $e = {
'PARENT' => { TYPE => 'FUNCTION' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "unique"), [
+is_deeply(GetElementLevelTable($e, "unique", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -280,7 +280,7 @@ $e = {
'PARENT' => { TYPE => 'FUNCTION' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "unique"), [
+is_deeply(GetElementLevelTable($e, "unique", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -326,7 +326,7 @@ $e = {
'PARENT' => { TYPE => 'FUNCTION' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "unique"), [
+is_deeply(GetElementLevelTable($e, "unique", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -372,7 +372,7 @@ $e = {
'PARENT' => { TYPE => 'FUNCTION' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "ref"), [
+is_deeply(GetElementLevelTable($e, "ref", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -418,7 +418,7 @@ $e = {
'PARENT' => { TYPE => 'FUNCTION' },
'LINE' => 42 };
-is_deeply(GetElementLevelTable($e, "ref"), [
+is_deeply(GetElementLevelTable($e, "ref", 0), [
{
LEVEL_INDEX => 0,
IS_DEFERRED => 0,
@@ -463,7 +463,7 @@ $e = {
'PARENT' => { TYPE => 'STRUCT' },
'LINE' => 42 };
-$ne = ParseElement($e, undef);
+$ne = ParseElement($e, undef, 0);
is($ne->{REPRESENTATION_TYPE}, "bar");
# representation_type
@@ -476,7 +476,7 @@ $e = {
'PARENT' => { TYPE => 'STRUCT' },
'LINE' => 42 };
-$ne = ParseElement($e, undef);
+$ne = ParseElement($e, undef, 0);
is($ne->{REPRESENTATION_TYPE}, "uint8");
is(align_type("hyper"), 8);
@@ -521,7 +521,7 @@ $t = {
},
ALIGN => undef
};
-is_deeply(ParseType($t->{ORIGINAL}, "ref"), $t);
+is_deeply(ParseType($t->{ORIGINAL}, "ref", 0), $t);
$t = {
TYPE => "UNION",
@@ -530,12 +530,14 @@ $t = {
ELEMENTS => undef,
PROPERTIES => undef,
HAS_DEFAULT => 0,
+ IS_MS_UNION => 0,
ORIGINAL => {
TYPE => "UNION",
NAME => "foo"
- }
+ },
+ ALIGN => undef
};
-is_deeply(ParseType($t->{ORIGINAL}, "ref"), $t);
+is_deeply(ParseType($t->{ORIGINAL}, "ref", 0), $t);
ok(not can_contain_deferred("uint32"));
ok(can_contain_deferred("some_unknown_type"));
@@ -552,8 +554,8 @@ ok(not can_contain_deferred({ TYPE => "TYPEDEF",
ok(can_contain_deferred({ TYPE => "STRUCT",
ELEMENTS => [ { TYPE => "someunknowntype" } ]}));
# Make sure the elements for a enum without body aren't filled in
-ok(not defined(ParseType({TYPE => "ENUM", NAME => "foo" }, "ref")->{ELEMENTS}));
+ok(not defined(ParseType({TYPE => "ENUM", NAME => "foo" }, "ref", 0)->{ELEMENTS}));
# Make sure the elements for a bitmap without body aren't filled in
-ok(not defined(ParseType({TYPE => "BITMAP", NAME => "foo" }, "ref")->{ELEMENTS}));
+ok(not defined(ParseType({TYPE => "BITMAP", NAME => "foo" }, "ref", 0)->{ELEMENTS}));
# Make sure the elements for a union without body aren't filled in
-ok(not defined(ParseType({TYPE => "UNION", NAME => "foo" }, "ref")->{ELEMENTS}));
+ok(not defined(ParseType({TYPE => "UNION", NAME => "foo" }, "ref", 0)->{ELEMENTS}));
diff --git a/pidl/tests/ndr_string.pl b/pidl/tests/ndr_string.pl
index 7b76c7b295..8e8b8ecbad 100755
--- a/pidl/tests/ndr_string.pl
+++ b/pidl/tests/ndr_string.pl
@@ -14,8 +14,7 @@ test_samba4_ndr("string-pull-empty",
'
uint8_t data[] = { 0x00, 0x00, 0x00, 0x00 };
DATA_BLOB b = { data, 4 };
- struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
struct TestString r;
r.in.data = NULL;
@@ -37,8 +36,7 @@ test_samba4_ndr("string-ascii-pull",
uint8_t data[] = { 0x03, 0x00, 0x00, 0x00,
\'f\', \'o\', \'o\', 0 };
DATA_BLOB b = { data, 8 };
- struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
struct TestString r;
r.in.data = NULL;
@@ -74,8 +72,7 @@ test_samba4_ndr("string-wchar-fixed-array-01",
0x02, 0x00, 0x00, 0x00
};
DATA_BLOB b = { data, sizeof(data) };
- struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
@@ -120,8 +117,7 @@ test_samba4_ndr("string-wchar-fixed-array-02",
0x02, 0x00, 0x00, 0x00
};
DATA_BLOB b = { data, sizeof(data) };
- struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
@@ -152,8 +148,7 @@ test_samba4_ndr("string-wchar-fixed-array-03",
0x02, 0x00, 0x00, 0x00
};
DATA_BLOB b = { data, sizeof(data) };
- struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
@@ -174,8 +169,7 @@ test_samba4_ndr("string-out",
uint8_t data[] = { 0x03, 0x00, 0x00, 0x00,
\'f\', \'o\', \'o\', 0 };
DATA_BLOB b = { data, 8 };
- struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
struct TestString r;
char *str = NULL;
r.out.data = &str;
diff --git a/pidl/tests/parse_idl.pl b/pidl/tests/parse_idl.pl
index e06526dd1e..14138a37b8 100755
--- a/pidl/tests/parse_idl.pl
+++ b/pidl/tests/parse_idl.pl
@@ -158,6 +158,7 @@ is_deeply($x, [ {
'DATA' => [ {
'TYPE' => 'TYPEDEF',
'NAME' => 'y',
+ 'POINTERS' => 0,
'DATA' => {
'TYPE' => 'STRUCT',
'NAME' => 'x',
@@ -180,6 +181,7 @@ is_deeply($x, [ {
'DATA' => [ {
'TYPE' => 'TYPEDEF',
'NAME' => 'y',
+ 'POINTERS' => 0,
'DATA' => {
'TYPE' => 'STRUCT',
'ELEMENTS' => [],
@@ -202,6 +204,7 @@ is_deeply($x, [ {
'DATA' => [ {
'TYPE' => 'TYPEDEF',
'NAME' => 'y',
+ 'POINTERS' => 0,
'DATA' => {
'TYPE' => 'BITMAP',
'NAME' => 'x',
@@ -225,6 +228,7 @@ is_deeply($x, [ {
'DATA' => [ {
'TYPE' => 'TYPEDEF',
'NAME' => 'y',
+ 'POINTERS' => 0,
'DATA' => {
'TYPE' => 'UNION',
'NAME' => 'x',
diff --git a/pidl/tests/samba-ndr.pl b/pidl/tests/samba-ndr.pl
index 5c9c6afd85..e257817809 100755
--- a/pidl/tests/samba-ndr.pl
+++ b/pidl/tests/samba-ndr.pl
@@ -223,6 +223,7 @@ $generator->ParseStructPush({
ELEMENTS => [ ]}, "ndr", "x");
is($generator->{res}, "if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_trailer_align(ndr, 4));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -248,6 +249,7 @@ is($generator->{res}, "if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_string_array_size(ndr, x->el1)));
NDR_CHECK(ndr_push_align(ndr, 4));
NDR_CHECK(ndr_push_mytype(ndr, NDR_SCALARS, &x->el1));
+ NDR_CHECK(ndr_push_trailer_align(ndr, 4));
}
if (ndr_flags & NDR_BUFFERS) {
}
diff --git a/pidl/tests/samba3-cli.pl b/pidl/tests/samba3-cli.pl
index 0d283a2d5a..c758ef4542 100755
--- a/pidl/tests/samba3-cli.pl
+++ b/pidl/tests/samba3-cli.pl
@@ -4,12 +4,12 @@
use strict;
use warnings;
-use Test::More tests => 9;
+use Test::More tests => 8;
use FindBin qw($RealBin);
use lib "$RealBin";
use Util;
use Parse::Pidl::Util qw(MyDumper);
-use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction ParseOutputArgument);
+use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
@@ -31,10 +31,7 @@ $fn = { NAME => "bar", ELEMENTS => [ ] };
$x->ParseFunction("foo", $fn);
is($x->{res},
"struct rpccli_bar_state {
- struct bar orig;
- struct bar tmp;
TALLOC_CTX *out_mem_ctx;
- NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
};
static void rpccli_bar_done(struct tevent_req *subreq);
@@ -53,23 +50,10 @@ struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
return NULL;
}
state->out_mem_ctx = NULL;
- state->dispatch_recv = cli->dispatch_recv;
- /* In parameters */
-
- /* Out parameters */
-
- if (DEBUGLEVEL >= 10) {
- NDR_PRINT_IN_DEBUG(bar, &state->orig);
- }
-
- /* make a temporary copy, that we pass to the dispatch function */
- state->tmp = state->orig;
-
- subreq = cli->dispatch_send(state, ev, cli,
- &ndr_table_foo,
- NDR_BAR,
- &state->tmp);
+ subreq = dcerpc_bar_send(state,
+ ev,
+ cli->binding_handle);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
@@ -92,22 +76,14 @@ static void rpccli_bar_done(struct tevent_req *subreq)
mem_ctx = state;
}
- status = state->dispatch_recv(subreq, mem_ctx);
+ status = dcerpc_bar_recv(subreq,
+ mem_ctx);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
}
- /* Copy out parameters */
-
- /* Reset temporary structure */
- ZERO_STRUCT(state->tmp);
-
- if (DEBUGLEVEL >= 10) {
- NDR_PRINT_OUT_DEBUG(bar, &state->orig);
- }
-
tevent_req_done(req);
}
@@ -123,7 +99,7 @@ NTSTATUS rpccli_bar_recv(struct tevent_req *req,
return status;
}
- /* Steal possbile out parameters to the callers context */
+ /* Steal possible out parameters to the callers context */
talloc_steal(mem_ctx, state->out_mem_ctx);
tevent_req_received(req);
@@ -133,37 +109,16 @@ NTSTATUS rpccli_bar_recv(struct tevent_req *req,
NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx)
{
-\tstruct bar r;
-\tNTSTATUS status;
-
-\t/* In parameters */
-
-\tif (DEBUGLEVEL >= 10) {
-\t\tNDR_PRINT_IN_DEBUG(bar, &r);
-\t}
-
- status = cli->dispatch(cli,
- mem_ctx,
- &ndr_table_foo,
- NDR_BAR,
- &r);
-
-\tif (!NT_STATUS_IS_OK(status)) {
-\t\treturn status;
-\t}
-
-\tif (DEBUGLEVEL >= 10) {
-\t\tNDR_PRINT_OUT_DEBUG(bar, &r);
-\t}
-
-\tif (NT_STATUS_IS_ERR(status)) {
-\t\treturn status;
-\t}
+ NTSTATUS status;
-\t/* Return variables */
+ status = dcerpc_bar(cli->binding_handle,
+ mem_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
-\t/* Return result */
-\treturn NT_STATUS_OK;
+ /* Return result */
+ return NT_STATUS_OK;
}
");
@@ -174,10 +129,8 @@ $fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" };
$x->ParseFunction("foo", $fn);
is($x->{res},
"struct rpccli_bar_state {
- struct bar orig;
- struct bar tmp;
TALLOC_CTX *out_mem_ctx;
- NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
+ WERROR result;
};
static void rpccli_bar_done(struct tevent_req *subreq);
@@ -196,26 +149,10 @@ struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
return NULL;
}
state->out_mem_ctx = NULL;
- state->dispatch_recv = cli->dispatch_recv;
-
- /* In parameters */
-
- /* Out parameters */
-
- /* Result */
- ZERO_STRUCT(state->orig.out.result);
- if (DEBUGLEVEL >= 10) {
- NDR_PRINT_IN_DEBUG(bar, &state->orig);
- }
-
- /* make a temporary copy, that we pass to the dispatch function */
- state->tmp = state->orig;
-
- subreq = cli->dispatch_send(state, ev, cli,
- &ndr_table_foo,
- NDR_BAR,
- &state->tmp);
+ subreq = dcerpc_bar_send(state,
+ ev,
+ cli->binding_handle);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
@@ -238,25 +175,15 @@ static void rpccli_bar_done(struct tevent_req *subreq)
mem_ctx = state;
}
- status = state->dispatch_recv(subreq, mem_ctx);
+ status = dcerpc_bar_recv(subreq,
+ mem_ctx,
+ &state->result);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
}
- /* Copy out parameters */
-
- /* Copy result */
- state->orig.out.result = state->tmp.out.result;
-
- /* Reset temporary structure */
- ZERO_STRUCT(state->tmp);
-
- if (DEBUGLEVEL >= 10) {
- NDR_PRINT_OUT_DEBUG(bar, &state->orig);
- }
-
tevent_req_done(req);
}
@@ -273,11 +200,11 @@ NTSTATUS rpccli_bar_recv(struct tevent_req *req,
return status;
}
- /* Steal possbile out parameters to the callers context */
+ /* Steal possible out parameters to the callers context */
talloc_steal(mem_ctx, state->out_mem_ctx);
/* Return result */
- *result = state->orig.out.result;
+ *result = state->result;
tevent_req_received(req);
return NT_STATUS_OK;
@@ -287,50 +214,23 @@ NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
WERROR *werror)
{
-\tstruct bar r;
-\tNTSTATUS status;
-
-\t/* In parameters */
-
-\tif (DEBUGLEVEL >= 10) {
-\t\tNDR_PRINT_IN_DEBUG(bar, &r);
-\t}
-
- status = cli->dispatch(cli,
- mem_ctx,
- &ndr_table_foo,
- NDR_BAR,
- &r);
-
-\tif (!NT_STATUS_IS_OK(status)) {
-\t\treturn status;
-\t}
-
-\tif (DEBUGLEVEL >= 10) {
-\t\tNDR_PRINT_OUT_DEBUG(bar, &r);
-\t}
-
-\tif (NT_STATUS_IS_ERR(status)) {
-\t\treturn status;
-\t}
+ WERROR result;
+ NTSTATUS status;
-\t/* Return variables */
+ status = dcerpc_bar(cli->binding_handle,
+ mem_ctx,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
-\t/* Return result */
-\tif (werror) {
-\t\t*werror = r.out.result;
-\t}
+ /* Return result */
+ if (werror) {
+ *werror = result;
+ }
-\treturn werror_to_ntstatus(r.out.result);
+ return werror_to_ntstatus(result);
}
");
-$x = new Parse::Pidl::Samba3::ClientNDR();
-
-$fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" };
-my $e = { NAME => "foo", ORIGINAL => { FILE => "f", LINE => -1 },
- LEVELS => [ { TYPE => "ARRAY", SIZE_IS => "mysize" }, { TYPE => "DATA", DATA_TYPE => "int" } ]};
-
-$x->ParseOutputArgument($fn, $e);
-is($x->{res}, "memcpy(foo, r.out.foo, (mysize) * sizeof(*foo));\n");
diff --git a/pidl/wscript b/pidl/wscript
new file mode 100644
index 0000000000..e60ca202f5
--- /dev/null
+++ b/pidl/wscript
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+
+import os, sys, Logs
+from samba_utils import MODE_755
+
+def set_options(opt):
+ opt.tool_options('perl')
+
+def configure(conf):
+ conf.check_tool('perl')
+ # we need a recent version of MakeMaker to get the right man page names
+ if conf.CHECK_PERL_MANPAGE():
+ conf.env.PERLMAN1EXT = conf.CHECK_PERL_MANPAGE(section='1')
+ conf.env.PERLMAN3EXT = conf.CHECK_PERL_MANPAGE(section='3')
+ conf.DEFINE('HAVE_PERL_MAKEMAKER', 1)
+
+ # yapp is used for building the parser
+ conf.find_program('yapp', var='YAPP')
+ conf.find_program('pod2man', var='POD2MAN')
+
+def build(bld):
+ bld.INSTALL_FILES('${BINDIR}', 'pidl', chmod=MODE_755)
+
+ bld.RECURSE('lib')
+
+ if not bld.CONFIG_SET('HAVE_PERL_MAKEMAKER'):
+ return
+
+ pidl_src = ['pidl']
+ pidl_src.extend(bld.path.ant_glob('lib/**/*.pm').split())
+
+ pidl_manpages = {
+ 'pidl': 'man1/pidl.${PERLMAN1EXT}',
+ 'lib/Parse/Pidl/NDR.pm': 'man3/Parse::Pidl::NDR.${PERLMAN3EXT}',
+ 'lib/Parse/Pidl/Wireshark/Conformance.pm': 'man3/Parse::Pidl::Wireshark::Conformance.${PERLMAN3EXT}',
+ 'lib/Parse/Pidl/Dump.pm': 'man3/Parse::Pidl::Dump.${PERLMAN3EXT}',
+ 'lib/Parse/Pidl/Util.pm': 'man3/Parse::Pidl::Util.${PERLMAN3EXT}',
+ 'lib/Parse/Pidl/Wireshark/NDR.pm': 'man3/Parse::Pidl::Wireshark::NDR.${PERLMAN3EXT}'
+ }
+
+ for k, v in pidl_manpages.iteritems():
+ pidl_manpages[k] = bld.EXPAND_VARIABLES(v)
+
+ # use perl to build the manpages
+ bld.env.pidl_srcdir = os.path.join(bld.srcnode.abspath(), 'pidl')
+
+ blib_bld = os.path.join(bld.srcnode.abspath(bld.env), 'pidl/blib')
+
+ bld.SET_BUILD_GROUP('final')
+ if 'POD2MAN' in bld.env and bld.env['POD2MAN'] != '':
+ for src, manpage in pidl_manpages.iteritems():
+ bld(rule='${PERL} ${POD2MAN} -c "Samba Documentation" ${SRC} ${TGT}',
+ shell=True,
+ source=src,
+ install_path=os.path.dirname(bld.EXPAND_VARIABLES('${MANDIR}/'+manpage)),
+ target=os.path.basename(manpage))
+
+ # we want to prefer the git version of the parsers if we can.
+ # Only if the source has changed do we want to re-run yapp
+ # But we force the developer to use the pidl standalone build
+ # to regenerate the files.
+ # TODO: only warn in developer mode and if 'git diff HEAD'
+ # shows a difference
+ warn_about_grammar_changes = ('PIDL_BUILD_WARNINGS' in bld.env and (
+ bld.IS_NEWER('idl.yp', 'lib/Parse/Pidl/IDL.pm') or
+ bld.IS_NEWER('expr.yp', 'lib/Parse/Pidl/Expr.pm')))
+
+ if warn_about_grammar_changes:
+ Logs.warn('''
+Pidl grammar files have changed. Please use the pidl standalone build
+to regenerate them with yapp.
+
+$ cd ../pidl
+$ perl Makefile.PL
+$ make lib/Parse/Pidl/IDL.pm lib/Parse/Pidl/Expr.pm
+$ git add lib/Parse/Pidl/IDL.pm lib/Parse/Pidl/Expr.pm
+$ git commit
+$ cd -
+
+If your 100% sure you haven't changed idl.yp and expr.yp
+try this to avoid this message:
+
+$ touch ../pidl/lib/Parse/Pidl/IDL.pm ../pidl/lib/Parse/Pidl/Expr.pm
+''')
+