aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/pidl/TODO13
-rw-r--r--tools/pidl/idl.yp16
-rw-r--r--tools/pidl/lib/Parse/Pidl/Dump.pm14
-rw-r--r--tools/pidl/lib/Parse/Pidl/Ethereal/Conformance.pm75
-rw-r--r--tools/pidl/lib/Parse/Pidl/Ethereal/NDR.pm47
-rw-r--r--tools/pidl/lib/Parse/Pidl/IDL.pm405
-rw-r--r--tools/pidl/lib/Parse/Pidl/NDR.pm52
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba/NDR/Client.pm2
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm66
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/Client.pm3
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/Header.pm29
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm86
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/Server.pm3
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/Types.pm71
-rwxr-xr-xtools/pidl/pidl85
15 files changed, 558 insertions, 409 deletions
diff --git a/tools/pidl/TODO b/tools/pidl/TODO
index 9fc3a7d904..ca5047c0d7 100644
--- a/tools/pidl/TODO
+++ b/tools/pidl/TODO
@@ -1,16 +1,17 @@
-- True multiple dimension array / strings in arrays support
+- true multiple dimension array / strings in arrays support
- compatibility mode for generating MIDL-readable data:
- strip out pidl-specific properties
- - convert subcontext() to an array of uint8.
- - perhaps replace subcontext() with something more generic? The argument
- to subcontext() isn't really intuitive at the moment
- don't be so strict on array boundaries.. arrays can and will be empty when
a (regular) remote error occurs
- support nested elements
-- Don't output [ref] pointers for Samba 4?
+- auto-alloc [ref] pointers for Samba4 during pull if they were NULL
-- alternative to subcontext()
+- better replacement for subcontext()
+
+- --explain-ndr option that dumps out parse tree
+
+- fix test suite
diff --git a/tools/pidl/idl.yp b/tools/pidl/idl.yp
index b703d4fa72..2613f11320 100644
--- a/tools/pidl/idl.yp
+++ b/tools/pidl/idl.yp
@@ -62,22 +62,24 @@ definitions:
definition: function | const | typedef | declare | typedecl
;
-const: 'const' identifier identifier '=' anytext ';'
+const: 'const' identifier pointers identifier '=' anytext ';'
{{
"TYPE" => "CONST",
"DTYPE" => $_[2],
- "NAME" => $_[3],
- "VALUE" => $_[5],
+ "POINTERS" => $_[3],
+ "NAME" => $_[4],
+ "VALUE" => $_[6],
"FILE" => $_[0]->YYData->{INPUT_FILENAME},
"LINE" => $_[0]->YYData->{LINE},
}}
- | 'const' identifier identifier array_len '=' anytext ';'
+ | 'const' identifier pointers identifier array_len '=' anytext ';'
{{
"TYPE" => "CONST",
"DTYPE" => $_[2],
- "NAME" => $_[3],
- "ARRAY_LEN" => $_[4],
- "VALUE" => $_[6],
+ "POINTERS" => $_[3],
+ "NAME" => $_[4],
+ "ARRAY_LEN" => $_[5],
+ "VALUE" => $_[7],
"FILE" => $_[0]->YYData->{INPUT_FILENAME},
"LINE" => $_[0]->YYData->{LINE},
}}
diff --git a/tools/pidl/lib/Parse/Pidl/Dump.pm b/tools/pidl/lib/Parse/Pidl/Dump.pm
index 80219a8f1a..3a1cec1b59 100644
--- a/tools/pidl/lib/Parse/Pidl/Dump.pm
+++ b/tools/pidl/lib/Parse/Pidl/Dump.pm
@@ -1,8 +1,22 @@
###################################################
# dump function for IDL structures
# Copyright tridge@samba.org 2000
+# Copyright jelmer@samba.org 2005
# released under the GNU GPL
+=pod
+
+=head1 NAME
+
+Parse::Pidl::Dump - Dump support
+
+=head1 DESCRIPTION
+
+This module provides functions that can generate IDL code from
+internal pidl data structures.
+
+=cut
+
package Parse::Pidl::Dump;
use Exporter;
diff --git a/tools/pidl/lib/Parse/Pidl/Ethereal/Conformance.pm b/tools/pidl/lib/Parse/Pidl/Ethereal/Conformance.pm
index 706a259306..1b550ae1e7 100644
--- a/tools/pidl/lib/Parse/Pidl/Ethereal/Conformance.pm
+++ b/tools/pidl/lib/Parse/Pidl/Ethereal/Conformance.pm
@@ -3,6 +3,81 @@
# Copyright jelmer@samba.org 2005
# released under the GNU GPL
+=pod
+
+=head1 NAME
+
+Parse::Pidl::Ethereal::Conformance - Conformance file parser for Ethereal
+
+=head1 DESCRIPTION
+
+This module supports parsing Ethereal conformance files (*.cnf).
+
+=head1 FILE FORMAT
+
+Pidl needs additional data for ethereal output. This data is read from
+so-called conformance files. This section describes the format of these
+files.
+
+Conformance files are simple text files with a single command on each line.
+Empty lines and lines starting with a '#' character are ignored.
+Arguments to commands are seperated by spaces.
+
+The following commands are currently supported:
+
+=over 4
+
+=item I<TYPE> name dissector ft_type base_type mask valsstring alignment
+
+Register new data type with specified name, what dissector function to call
+and what properties to give header fields for elements of this type.
+
+=item I<NOEMIT> type
+
+Suppress emitting a dissect_type function for the specified type
+
+=item I<PARAM_VALUE> type param
+
+Set parameter to specify to dissector function for given type.
+
+=item I<HF_FIELD> hf title filter ft_type base_type valsstring mask description
+
+Generate a custom header field with specified properties.
+
+=item I<HF_RENAME> old_hf_name new_hf_name
+
+Force the use of new_hf_name when the parser generator was going to
+use old_hf_name.
+
+This can be used in conjunction with HF_FIELD in order to make more then
+one element use the same filter name.
+
+=item I<STRIP_PREFIX> prefix
+
+Remove the specified prefix from all function names (if present).
+
+=item I<PROTOCOL> longname shortname filtername
+
+Change the short-, long- and filter-name for the current interface in
+Ethereal.
+
+=item I<FIELD_DESCRIPTION> field desc
+
+Change description for the specified header field. `field' is the hf name of the field.
+
+=item I<IMPORT> dissector code...
+
+Code to insert when generating the specified dissector. @HF@ and
+@PARAM@ will be substituted.
+
+=back
+
+=head1 EXAMPLE
+
+ INFO_KEY OpenKey.Ke
+
+=cut
+
package Parse::Pidl::Ethereal::Conformance;
require Exporter;
diff --git a/tools/pidl/lib/Parse/Pidl/Ethereal/NDR.pm b/tools/pidl/lib/Parse/Pidl/Ethereal/NDR.pm
index be542638ef..be2e48a686 100644
--- a/tools/pidl/lib/Parse/Pidl/Ethereal/NDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/Ethereal/NDR.pm
@@ -6,18 +6,32 @@
# Portions based on idl2eth.c by Ronnie Sahlberg
# released under the GNU GPL
+=pod
+
+=head1 NAME
+
+Parse::Pidl::Ethereal::NDR - Parser generator for Ethereal
+
+=cut
+
package Parse::Pidl::Ethereal::NDR;
use strict;
use Parse::Pidl::Typelist qw(getType);
use Parse::Pidl::Util qw(has_property ParseExpr property_matches make_str);
-use Parse::Pidl::NDR;
+use Parse::Pidl::NDR qw(ContainsString GetNextLevel);
use Parse::Pidl::Dump qw(DumpTypedef DumpFunction);
use Parse::Pidl::Ethereal::Conformance qw(ReadConformance);
use vars qw($VERSION);
$VERSION = '0.01';
+sub error($$)
+{
+ my ($e,$t) = @_;
+ print "$e->{FILE}:$e->{LINE}: $t\n";
+}
+
my @ett;
my %hf_used = ();
@@ -235,21 +249,26 @@ sub ElementLevel($$$$$)
}
pidl_code "offset = dissect_ndr_$type\_pointer(tvb, offset, pinfo, tree, drep, $myname\_, $ptrtype_mappings{$l->{POINTER_TYPE}}, \"Pointer to ".field2name(StripPrefixes($e->{NAME})) . " ($e->{TYPE})\",$hf);";
} elsif ($l->{TYPE} eq "ARRAY") {
-
if ($l->{IS_INLINE}) {
- warn ("Inline arrays not supported");
- pidl_code "/* FIXME: Handle inline array */";
+ error($e->{ORIGINAL}, "Inline arrays not supported");
} elsif ($l->{IS_FIXED}) {
pidl_code "int i;";
pidl_code "for (i = 0; i < $l->{SIZE_IS}; i++)";
pidl_code "\toffset = $myname\_(tvb, offset, pinfo, tree, drep);";
} else {
- my $af = "";
- ($af = "ucarray") if ($l->{IS_CONFORMANT});
- ($af = "uvarray") if ($l->{IS_VARYING});
- ($af = "ucvarray") if ($l->{IS_CONFORMANT} and $l->{IS_VARYING});
+ my $type = "";
+ $type .= "c" if ($l->{IS_CONFORMANT});
+ $type .= "v" if ($l->{IS_VARYING});
- pidl_code "offset = dissect_ndr_$af(tvb, offset, pinfo, tree, drep, $myname\_);";
+ unless ($l->{IS_ZERO_TERMINATED}) {
+ pidl_code "offset = dissect_ndr_u" . $type . "array(tvb, offset, pinfo, tree, drep, $myname\_);";
+ } else {
+ my $nl = GetNextLevel($e,$l);
+ pidl_code "char *data;";
+ pidl_code "";
+ pidl_code "offset = dissect_ndr_$type" . "string(tvb, offset, pinfo, tree, drep, sizeof(g$nl->{DATA_TYPE}), $hf, FALSE, &data);";
+ pidl_code "proto_item_append_text(tree, \": %s\", data);";
+ }
}
} elsif ($l->{TYPE} eq "DATA") {
if ($l->{DATA_TYPE} eq "string") {
@@ -324,6 +343,15 @@ sub Element($$$)
};
}
+ if (ContainsString($e)) {
+ $type = {
+ MASK => 0,
+ VALSSTRING => "NULL",
+ FT_TYPE => "FT_STRING",
+ BASE_TYPE => "BASE_DEC"
+ };
+ }
+
my $hf = register_hf_field("hf_$ifname\_$pn\_$e->{NAME}", field2name($e->{NAME}), "$ifname.$pn.$e->{NAME}", $type->{FT_TYPE}, $type->{BASE_TYPE}, $type->{VALSSTRING}, $type->{MASK}, "");
$hf_used{$hf} = 1;
@@ -349,6 +377,7 @@ sub Element($$$)
deindent;
pidl_code "}\n";
$add.="_";
+ last if ($_->{TYPE} eq "ARRAY" and $_->{IS_ZERO_TERMINATED});
}
return $call_code;
diff --git a/tools/pidl/lib/Parse/Pidl/IDL.pm b/tools/pidl/lib/Parse/Pidl/IDL.pm
index 1aa4426cd6..59a9aef76a 100644
--- a/tools/pidl/lib/Parse/Pidl/IDL.pm
+++ b/tools/pidl/lib/Parse/Pidl/IDL.pm
@@ -1424,11 +1424,9 @@ sub new {
}
},
{#State 102
- ACTIONS => {
- 'IDENTIFIER' => 9
- },
+ DEFAULT => -52,
GOTOS => {
- 'identifier' => 119
+ 'pointers' => 119
}
},
{#State 103
@@ -1535,17 +1533,17 @@ sub new {
},
{#State 119
ACTIONS => {
- "[" => 130,
- "=" => 132
+ 'IDENTIFIER' => 9,
+ "*" => 131
},
GOTOS => {
- 'array_len' => 131
+ 'identifier' => 130
}
},
{#State 120
DEFAULT => -54,
GOTOS => {
- 'element_list1' => 133
+ 'element_list1' => 132
}
},
{#State 121
@@ -1553,9 +1551,9 @@ sub new {
'IDENTIFIER' => 9
},
GOTOS => {
- 'identifier' => 134,
- 'enum_element' => 135,
- 'enum_elements' => 136
+ 'identifier' => 133,
+ 'enum_element' => 134,
+ 'enum_elements' => 135
}
},
{#State 122
@@ -1563,9 +1561,9 @@ sub new {
'IDENTIFIER' => 9
},
GOTOS => {
- 'identifier' => 139,
- 'bitmap_elements' => 138,
- 'bitmap_element' => 137
+ 'identifier' => 138,
+ 'bitmap_elements' => 137,
+ 'bitmap_element' => 136
}
},
{#State 123
@@ -1621,7 +1619,7 @@ sub new {
},
{#State 126
ACTIONS => {
- "[" => 130
+ "[" => 139
},
DEFAULT => -60,
GOTOS => {
@@ -1658,75 +1656,68 @@ sub new {
},
{#State 130
ACTIONS => {
- 'CONSTANT' => 28,
- 'TEXT' => 22,
- "]" => 149,
- 'IDENTIFIER' => 9
+ "[" => 139,
+ "=" => 150
},
- DEFAULT => -73,
GOTOS => {
- 'identifier' => 23,
- 'anytext' => 150,
- 'text' => 24,
- 'constant' => 27
+ 'array_len' => 149
}
},
{#State 131
- ACTIONS => {
- "=" => 151
- }
+ DEFAULT => -53
},
{#State 132
ACTIONS => {
- 'CONSTANT' => 28,
- 'TEXT' => 22,
- 'IDENTIFIER' => 9
- },
- DEFAULT => -73,
- GOTOS => {
- 'identifier' => 23,
- 'anytext' => 152,
- 'text' => 24,
- 'constant' => 27
- }
- },
- {#State 133
- ACTIONS => {
- "}" => 153
+ "}" => 151
},
DEFAULT => -63,
GOTOS => {
- 'base_element' => 154,
+ 'base_element' => 152,
'property_list' => 145
}
},
- {#State 134
+ {#State 133
ACTIONS => {
- "=" => 155
+ "=" => 153
},
DEFAULT => -37
},
- {#State 135
+ {#State 134
DEFAULT => -35
},
+ {#State 135
+ ACTIONS => {
+ "}" => 154,
+ "," => 155
+ }
+ },
{#State 136
+ DEFAULT => -40
+ },
+ {#State 137
ACTIONS => {
"}" => 156,
"," => 157
}
},
- {#State 137
- DEFAULT => -40
- },
{#State 138
ACTIONS => {
- "}" => 158,
- "," => 159
+ "=" => 158
}
},
{#State 139
ACTIONS => {
- "=" => 160
+ 'CONSTANT' => 28,
+ 'TEXT' => 22,
+ "]" => 159,
+ 'IDENTIFIER' => 9
+ },
+ DEFAULT => -73,
+ GOTOS => {
+ 'identifier' => 23,
+ 'anytext' => 160,
+ 'text' => 24,
+ 'constant' => 27
}
},
{#State 140
@@ -1789,35 +1780,11 @@ sub new {
},
{#State 149
ACTIONS => {
- "[" => 130
- },
- DEFAULT => -60,
- GOTOS => {
- 'array_len' => 169
+ "=" => 169
}
},
{#State 150
ACTIONS => {
- "-" => 35,
- ":" => 34,
- "?" => 36,
- "<" => 37,
- "+" => 39,
- "~" => 38,
- "&" => 41,
- "{" => 40,
- "/" => 42,
- "=" => 43,
- "|" => 45,
- "(" => 44,
- "*" => 46,
- "." => 47,
- "]" => 170,
- ">" => 48
- }
- },
- {#State 151
- ACTIONS => {
'CONSTANT' => 28,
'TEXT' => 22,
'IDENTIFIER' => 9
@@ -1825,40 +1792,20 @@ sub new {
DEFAULT => -73,
GOTOS => {
'identifier' => 23,
- 'anytext' => 171,
+ 'anytext' => 170,
'text' => 24,
'constant' => 27
}
},
- {#State 152
- ACTIONS => {
- "-" => 35,
- ":" => 34,
- "?" => 36,
- "<" => 37,
- ";" => 172,
- "+" => 39,
- "~" => 38,
- "&" => 41,
- "{" => 40,
- "/" => 42,
- "=" => 43,
- "|" => 45,
- "(" => 44,
- "*" => 46,
- "." => 47,
- ">" => 48
- }
- },
- {#State 153
+ {#State 151
DEFAULT => -43
},
- {#State 154
+ {#State 152
ACTIONS => {
- ";" => 173
+ ";" => 171
}
},
- {#State 155
+ {#State 153
ACTIONS => {
'CONSTANT' => 28,
'TEXT' => 22,
@@ -1867,36 +1814,36 @@ sub new {
DEFAULT => -73,
GOTOS => {
'identifier' => 23,
- 'anytext' => 174,
+ 'anytext' => 172,
'text' => 24,
'constant' => 27
}
},
- {#State 156
+ {#State 154
DEFAULT => -34
},
- {#State 157
+ {#State 155
ACTIONS => {
'IDENTIFIER' => 9
},
GOTOS => {
- 'identifier' => 134,
- 'enum_element' => 175
+ 'identifier' => 133,
+ 'enum_element' => 173
}
},
- {#State 158
+ {#State 156
DEFAULT => -39
},
- {#State 159
+ {#State 157
ACTIONS => {
'IDENTIFIER' => 9
},
GOTOS => {
- 'identifier' => 139,
- 'bitmap_element' => 176
+ 'identifier' => 138,
+ 'bitmap_element' => 174
}
},
- {#State 160
+ {#State 158
ACTIONS => {
'CONSTANT' => 28,
'TEXT' => 22,
@@ -1905,11 +1852,40 @@ sub new {
DEFAULT => -73,
GOTOS => {
'identifier' => 23,
- 'anytext' => 177,
+ 'anytext' => 175,
'text' => 24,
'constant' => 27
}
},
+ {#State 159
+ ACTIONS => {
+ "[" => 139
+ },
+ DEFAULT => -60,
+ GOTOS => {
+ 'array_len' => 176
+ }
+ },
+ {#State 160
+ ACTIONS => {
+ "-" => 35,
+ ":" => 34,
+ "?" => 36,
+ "<" => 37,
+ "+" => 39,
+ "~" => 38,
+ "&" => 41,
+ "{" => 40,
+ "/" => 42,
+ "=" => 43,
+ "|" => 45,
+ "(" => 44,
+ "*" => 46,
+ "." => 47,
+ "]" => 177,
+ ">" => 48
+ }
+ },
{#State 161
DEFAULT => -25
},
@@ -1964,18 +1940,20 @@ sub new {
}
},
{#State 169
- DEFAULT => -61
- },
- {#State 170
ACTIONS => {
- "[" => 130
+ 'CONSTANT' => 28,
+ 'TEXT' => 22,
+ 'IDENTIFIER' => 9
},
- DEFAULT => -60,
+ DEFAULT => -73,
GOTOS => {
- 'array_len' => 183
+ 'identifier' => 23,
+ 'anytext' => 183,
+ 'text' => 24,
+ 'constant' => 27
}
},
- {#State 171
+ {#State 170
ACTIONS => {
"-" => 35,
":" => 34,
@@ -1995,13 +1973,10 @@ sub new {
">" => 48
}
},
- {#State 172
- DEFAULT => -17
- },
- {#State 173
+ {#State 171
DEFAULT => -55
},
- {#State 174
+ {#State 172
ACTIONS => {
"-" => 35,
":" => 34,
@@ -2021,13 +1996,13 @@ sub new {
},
DEFAULT => -38
},
- {#State 175
+ {#State 173
DEFAULT => -36
},
- {#State 176
+ {#State 174
DEFAULT => -41
},
- {#State 177
+ {#State 175
ACTIONS => {
"-" => 35,
":" => 34,
@@ -2047,6 +2022,18 @@ sub new {
},
DEFAULT => -42
},
+ {#State 176
+ DEFAULT => -61
+ },
+ {#State 177
+ ACTIONS => {
+ "[" => 139
+ },
+ DEFAULT => -60,
+ GOTOS => {
+ 'array_len' => 185
+ }
+ },
{#State 178
DEFAULT => -45
},
@@ -2056,10 +2043,10 @@ sub new {
{#State 180
ACTIONS => {
'IDENTIFIER' => 9,
- "*" => 186
+ "*" => 131
},
GOTOS => {
- 'identifier' => 185
+ 'identifier' => 186
}
},
{#State 181
@@ -2069,24 +2056,44 @@ sub new {
DEFAULT => -19
},
{#State 183
- DEFAULT => -62
+ ACTIONS => {
+ "-" => 35,
+ ":" => 34,
+ "?" => 36,
+ "<" => 37,
+ ";" => 187,
+ "+" => 39,
+ "~" => 38,
+ "&" => 41,
+ "{" => 40,
+ "/" => 42,
+ "=" => 43,
+ "|" => 45,
+ "(" => 44,
+ "*" => 46,
+ "." => 47,
+ ">" => 48
+ }
},
{#State 184
- DEFAULT => -18
+ DEFAULT => -17
},
{#State 185
+ DEFAULT => -62
+ },
+ {#State 186
ACTIONS => {
- "[" => 130
+ "[" => 139
},
DEFAULT => -60,
GOTOS => {
- 'array_len' => 187
+ 'array_len' => 188
}
},
- {#State 186
- DEFAULT => -53
- },
{#State 187
+ DEFAULT => -18
+ },
+ {#State 188
DEFAULT => -51
}
],
@@ -2183,28 +2190,30 @@ sub
'definition', 1, undef
],
[#Rule 17
- 'const', 6,
+ 'const', 7,
sub
#line 66 "pidl/idl.yp"
{{
"TYPE" => "CONST",
"DTYPE" => $_[2],
- "NAME" => $_[3],
- "VALUE" => $_[5],
+ "POINTERS" => $_[3],
+ "NAME" => $_[4],
+ "VALUE" => $_[6],
"FILE" => $_[0]->YYData->{INPUT_FILENAME},
"LINE" => $_[0]->YYData->{LINE},
}}
],
[#Rule 18
- 'const', 7,
+ 'const', 8,
sub
-#line 75 "pidl/idl.yp"
+#line 76 "pidl/idl.yp"
{{
"TYPE" => "CONST",
"DTYPE" => $_[2],
- "NAME" => $_[3],
- "ARRAY_LEN" => $_[4],
- "VALUE" => $_[6],
+ "POINTERS" => $_[3],
+ "NAME" => $_[4],
+ "ARRAY_LEN" => $_[5],
+ "VALUE" => $_[7],
"FILE" => $_[0]->YYData->{INPUT_FILENAME},
"LINE" => $_[0]->YYData->{LINE},
}}
@@ -2212,7 +2221,7 @@ sub
[#Rule 19
'function', 7,
sub
-#line 88 "pidl/idl.yp"
+#line 90 "pidl/idl.yp"
{{
"TYPE" => "FUNCTION",
"NAME" => $_[3],
@@ -2226,7 +2235,7 @@ sub
[#Rule 20
'declare', 5,
sub
-#line 100 "pidl/idl.yp"
+#line 102 "pidl/idl.yp"
{{
"TYPE" => "DECLARE",
"PROPERTIES" => $_[2],
@@ -2245,7 +2254,7 @@ sub
[#Rule 23
'decl_enum', 1,
sub
-#line 114 "pidl/idl.yp"
+#line 116 "pidl/idl.yp"
{{
"TYPE" => "ENUM"
}}
@@ -2253,7 +2262,7 @@ sub
[#Rule 24
'decl_bitmap', 1,
sub
-#line 120 "pidl/idl.yp"
+#line 122 "pidl/idl.yp"
{{
"TYPE" => "BITMAP"
}}
@@ -2261,7 +2270,7 @@ sub
[#Rule 25
'typedef', 6,
sub
-#line 126 "pidl/idl.yp"
+#line 128 "pidl/idl.yp"
{{
"TYPE" => "TYPEDEF",
"PROPERTIES" => $_[2],
@@ -2287,7 +2296,7 @@ sub
[#Rule 30
'typedecl', 2,
sub
-#line 139 "pidl/idl.yp"
+#line 141 "pidl/idl.yp"
{ $_[1] }
],
[#Rule 31
@@ -2299,13 +2308,13 @@ sub
[#Rule 33
'type', 1,
sub
-#line 142 "pidl/idl.yp"
+#line 144 "pidl/idl.yp"
{ "void" }
],
[#Rule 34
'enum', 5,
sub
-#line 146 "pidl/idl.yp"
+#line 148 "pidl/idl.yp"
{{
"TYPE" => "ENUM",
"NAME" => $_[2],
@@ -2315,13 +2324,13 @@ sub
[#Rule 35
'enum_elements', 1,
sub
-#line 154 "pidl/idl.yp"
+#line 156 "pidl/idl.yp"
{ [ $_[1] ] }
],
[#Rule 36
'enum_elements', 3,
sub
-#line 155 "pidl/idl.yp"
+#line 157 "pidl/idl.yp"
{ push(@{$_[1]}, $_[3]); $_[1] }
],
[#Rule 37
@@ -2330,13 +2339,13 @@ sub
[#Rule 38
'enum_element', 3,
sub
-#line 159 "pidl/idl.yp"
+#line 161 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 39
'bitmap', 5,
sub
-#line 163 "pidl/idl.yp"
+#line 165 "pidl/idl.yp"
{{
"TYPE" => "BITMAP",
"NAME" => $_[2],
@@ -2346,25 +2355,25 @@ sub
[#Rule 40
'bitmap_elements', 1,
sub
-#line 171 "pidl/idl.yp"
+#line 173 "pidl/idl.yp"
{ [ $_[1] ] }
],
[#Rule 41
'bitmap_elements', 3,
sub
-#line 172 "pidl/idl.yp"
+#line 174 "pidl/idl.yp"
{ push(@{$_[1]}, $_[3]); $_[1] }
],
[#Rule 42
'bitmap_element', 3,
sub
-#line 175 "pidl/idl.yp"
+#line 177 "pidl/idl.yp"
{ "$_[1] ( $_[3] )" }
],
[#Rule 43
'struct', 5,
sub
-#line 179 "pidl/idl.yp"
+#line 181 "pidl/idl.yp"
{{
"TYPE" => "STRUCT",
"NAME" => $_[2],
@@ -2374,7 +2383,7 @@ sub
[#Rule 44
'empty_element', 2,
sub
-#line 187 "pidl/idl.yp"
+#line 189 "pidl/idl.yp"
{{
"NAME" => "",
"TYPE" => "EMPTY",
@@ -2394,7 +2403,7 @@ sub
[#Rule 47
'optional_base_element', 2,
sub
-#line 201 "pidl/idl.yp"
+#line 203 "pidl/idl.yp"
{ $_[2]->{PROPERTIES} = Parse::Pidl::Util::FlattenHash([$_[1],$_[2]->{PROPERTIES}]); $_[2] }
],
[#Rule 48
@@ -2403,13 +2412,13 @@ sub
[#Rule 49
'union_elements', 2,
sub
-#line 206 "pidl/idl.yp"
+#line 208 "pidl/idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 50
'union', 5,
sub
-#line 210 "pidl/idl.yp"
+#line 212 "pidl/idl.yp"
{{
"TYPE" => "UNION",
"NAME" => $_[2],
@@ -2419,7 +2428,7 @@ sub
[#Rule 51
'base_element', 5,
sub
-#line 218 "pidl/idl.yp"
+#line 220 "pidl/idl.yp"
{{
"NAME" => $_[4],
"TYPE" => $_[2],
@@ -2433,13 +2442,13 @@ sub
[#Rule 52
'pointers', 0,
sub
-#line 232 "pidl/idl.yp"
+#line 234 "pidl/idl.yp"
{ 0 }
],
[#Rule 53
'pointers', 2,
sub
-#line 233 "pidl/idl.yp"
+#line 235 "pidl/idl.yp"
{ $_[1]+1 }
],
[#Rule 54
@@ -2448,7 +2457,7 @@ sub
[#Rule 55
'element_list1', 3,
sub
-#line 238 "pidl/idl.yp"
+#line 240 "pidl/idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 56
@@ -2460,13 +2469,13 @@ sub
[#Rule 58
'element_list2', 1,
sub
-#line 244 "pidl/idl.yp"
+#line 246 "pidl/idl.yp"
{ [ $_[1] ] }
],
[#Rule 59
'element_list2', 3,
sub
-#line 245 "pidl/idl.yp"
+#line 247 "pidl/idl.yp"
{ push(@{$_[1]}, $_[3]); $_[1] }
],
[#Rule 60
@@ -2475,13 +2484,13 @@ sub
[#Rule 61
'array_len', 3,
sub
-#line 250 "pidl/idl.yp"
+#line 252 "pidl/idl.yp"
{ push(@{$_[3]}, "*"); $_[3] }
],
[#Rule 62
'array_len', 4,
sub
-#line 251 "pidl/idl.yp"
+#line 253 "pidl/idl.yp"
{ push(@{$_[4]}, "$_[2]"); $_[4] }
],
[#Rule 63
@@ -2490,31 +2499,31 @@ sub
[#Rule 64
'property_list', 4,
sub
-#line 257 "pidl/idl.yp"
+#line 259 "pidl/idl.yp"
{ Parse::Pidl::Util::FlattenHash([$_[1],$_[3]]); }
],
[#Rule 65
'properties', 1,
sub
-#line 260 "pidl/idl.yp"
+#line 262 "pidl/idl.yp"
{ $_[1] }
],
[#Rule 66
'properties', 3,
sub
-#line 261 "pidl/idl.yp"
+#line 263 "pidl/idl.yp"
{ Parse::Pidl::Util::FlattenHash([$_[1], $_[3]]); }
],
[#Rule 67
'property', 1,
sub
-#line 264 "pidl/idl.yp"
+#line 266 "pidl/idl.yp"
{{ "$_[1]" => "1" }}
],
[#Rule 68
'property', 4,
sub
-#line 265 "pidl/idl.yp"
+#line 267 "pidl/idl.yp"
{{ "$_[1]" => "$_[3]" }}
],
[#Rule 69
@@ -2523,7 +2532,7 @@ sub
[#Rule 70
'listtext', 3,
sub
-#line 270 "pidl/idl.yp"
+#line 272 "pidl/idl.yp"
{ "$_[1] $_[3]" }
],
[#Rule 71
@@ -2532,13 +2541,13 @@ sub
[#Rule 72
'commalisttext', 3,
sub
-#line 275 "pidl/idl.yp"
+#line 277 "pidl/idl.yp"
{ "$_[1],$_[3]" }
],
[#Rule 73
'anytext', 0,
sub
-#line 279 "pidl/idl.yp"
+#line 281 "pidl/idl.yp"
{ "" }
],
[#Rule 74
@@ -2553,91 +2562,91 @@ sub
[#Rule 77
'anytext', 3,
sub
-#line 281 "pidl/idl.yp"
+#line 283 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 78
'anytext', 3,
sub
-#line 282 "pidl/idl.yp"
+#line 284 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 79
'anytext', 3,
sub
-#line 283 "pidl/idl.yp"
+#line 285 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 80
'anytext', 3,
sub
-#line 284 "pidl/idl.yp"
+#line 286 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 81
'anytext', 3,
sub
-#line 285 "pidl/idl.yp"
+#line 287 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 82
'anytext', 3,
sub
-#line 286 "pidl/idl.yp"
+#line 288 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 83
'anytext', 3,
sub
-#line 287 "pidl/idl.yp"
+#line 289 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 84
'anytext', 3,
sub
-#line 288 "pidl/idl.yp"
+#line 290 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 85
'anytext', 3,
sub
-#line 289 "pidl/idl.yp"
+#line 291 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 86
'anytext', 3,
sub
-#line 290 "pidl/idl.yp"
+#line 292 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 87
'anytext', 3,
sub
-#line 291 "pidl/idl.yp"
+#line 293 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 88
'anytext', 3,
sub
-#line 292 "pidl/idl.yp"
+#line 294 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 89
'anytext', 3,
sub
-#line 293 "pidl/idl.yp"
+#line 295 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 90
'anytext', 5,
sub
-#line 294 "pidl/idl.yp"
+#line 296 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]$_[4]$_[5]" }
],
[#Rule 91
'anytext', 5,
sub
-#line 295 "pidl/idl.yp"
+#line 297 "pidl/idl.yp"
{ "$_[1]$_[2]$_[3]$_[4]$_[5]" }
],
[#Rule 92
@@ -2655,7 +2664,7 @@ sub
[#Rule 96
'text', 1,
sub
-#line 309 "pidl/idl.yp"
+#line 311 "pidl/idl.yp"
{ "\"$_[1]\"" }
],
[#Rule 97
@@ -2669,7 +2678,7 @@ sub
bless($self,$class);
}
-#line 320 "pidl/idl.yp"
+#line 322 "pidl/idl.yp"
use Parse::Pidl::Util;
diff --git a/tools/pidl/lib/Parse/Pidl/NDR.pm b/tools/pidl/lib/Parse/Pidl/NDR.pm
index 64190e87b8..d0b6708bf6 100644
--- a/tools/pidl/lib/Parse/Pidl/NDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/NDR.pm
@@ -5,13 +5,33 @@
# Copyright jelmer@samba.org 2004-2005
# released under the GNU GPL
+=pod
+
+=head1 NAME
+
+Parse::Pidl::NDR - NDR parsing information generator
+
+=head1 DESCRIPTION
+
+#####################################################################
+# return a table describing the order in which the parts of an element
+# should be parsed
+# Possible level types:
+# - POINTER
+# - ARRAY
+# - SUBCONTEXT
+# - SWITCH
+# - DATA
+
+=cut
+
package Parse::Pidl::NDR;
require Exporter;
use vars qw($VERSION);
$VERSION = '0.01';
@ISA = qw(Exporter);
-@EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred);
+@EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsString);
use strict;
use Parse::Pidl::Typelist qw(hasType getType);
@@ -62,15 +82,6 @@ sub fatal($$)
die("$pos->{FILE}:$pos->{LINE}:$s\n");
}
-#####################################################################
-# return a table describing the order in which the parts of an element
-# should be parsed
-# Possible level types:
-# - POINTER
-# - ARRAY
-# - SUBCONTEXT
-# - SWITCH
-# - DATA
sub GetElementLevelTable($)
{
my $e = shift;
@@ -362,7 +373,12 @@ sub ParseStruct($)
foreach my $x (@{$struct->{ELEMENTS}})
{
- push @elements, ParseElement($x);
+ my $e = ParseElement($x);
+ if ($x != $struct->{ELEMENTS}[-1] and
+ $e->{LEVELS}[0]->{IS_SURROUNDING}) {
+ print "$x->{FILE}:$x->{LINE}: error: conformant member not at end of struct\n";
+ }
+ push @elements, $e;
}
my $e = $elements[-1];
@@ -394,6 +410,7 @@ sub ParseUnion($)
if (has_property($e, "nodiscriminant")) { $switch_type = undef; }
+ my $hasdefault = 0;
foreach my $x (@{$e->{ELEMENTS}})
{
my $t;
@@ -404,6 +421,7 @@ sub ParseUnion($)
}
if (has_property($x, "default")) {
$t->{CASE} = "default";
+ $hasdefault = 1;
} elsif (defined($x->{PROPERTIES}->{case})) {
$t->{CASE} = "case $x->{PROPERTIES}->{case}";
} else {
@@ -417,6 +435,7 @@ sub ParseUnion($)
SWITCH_TYPE => $switch_type,
ELEMENTS => \@elements,
PROPERTIES => $e->{PROPERTIES},
+ HAS_DEFAULT => $hasdefault,
ORIGINAL => $e
};
}
@@ -640,6 +659,17 @@ sub GetPrevLevel($$)
return undef;
}
+sub ContainsString($)
+{
+ my ($e) = @_;
+
+ foreach my $l (@{$e->{LEVELS}}) {
+ return 1 if ($l->{TYPE} eq "ARRAY" and $l->{IS_ZERO_TERMINATED});
+ }
+
+ return 0;
+}
+
sub ContainsDeferred($$)
{
my ($e,$l) = @_;
diff --git a/tools/pidl/lib/Parse/Pidl/Samba/NDR/Client.pm b/tools/pidl/lib/Parse/Pidl/Samba/NDR/Client.pm
index 10b8dc71d8..3ec19fa158 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba/NDR/Client.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba/NDR/Client.pm
@@ -40,7 +40,7 @@ NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *
status = dcerpc_ndr_request_recv(req);
- if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
+ if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
NDR_PRINT_OUT_DEBUG($name, r);
}
";
diff --git a/tools/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm b/tools/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm
index 3f08cbb527..0454f90c9a 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm
@@ -292,7 +292,11 @@ sub ParseArrayPushHeader($$$$$)
my $length;
if ($l->{IS_ZERO_TERMINATED}) {
- $size = $length = "ndr_string_length($var_name, sizeof(*$var_name))";
+ if (has_property($e, "charset")) {
+ $size = $length = "ndr_charset_length($var_name, CH_$e->{PROPERTIES}->{charset})";
+ } else {
+ $size = $length = "ndr_string_length($var_name, sizeof(*$var_name))";
+ }
} else {
$size = ParseExpr($l->{SIZE_IS}, $env);
$length = ParseExpr($l->{LENGTH_IS}, $env);
@@ -575,8 +579,7 @@ sub ParseElementPushLevel
my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
- if ($l->{TYPE} eq "ARRAY" and ($l->{IS_CONFORMANT} or $l->{IS_VARYING}
- or is_charset_array($e, $l))) {
+ if ($l->{TYPE} eq "ARRAY" and ($l->{IS_CONFORMANT} or $l->{IS_VARYING})) {
$var_name = get_pointer_to($var_name);
}
@@ -721,8 +724,7 @@ sub ParseElementPrint($$$)
} elsif ($l->{TYPE} eq "ARRAY") {
my $length;
- if ($l->{IS_CONFORMANT} or $l->{IS_VARYING} or
- is_charset_array($e,$l)) {
+ if ($l->{IS_CONFORMANT} or $l->{IS_VARYING}) {
$var_name = get_pointer_to($var_name);
}
@@ -921,14 +923,22 @@ sub ParseMemCtxPullEnd($$)
pidl "NDR_PULL_SET_MEM_CTX(ndr, $mem_r_ctx, $mem_r_flags);";
}
+sub CheckStringTerminator($$$$)
+{
+ my ($ndr,$e,$l,$length) = @_;
+ my $nl = GetNextLevel($e, $l);
+
+ # Make sure last element is zero!
+ pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $length, sizeof($nl->{DATA_TYPE}_t)));";
+}
+
sub ParseElementPullLevel
{
my($e,$l,$ndr,$var_name,$env,$primitives,$deferred) = @_;
my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
- if ($l->{TYPE} eq "ARRAY" and ($l->{IS_VARYING} or $l->{IS_CONFORMANT}
- or is_charset_array($e,$l))) {
+ if ($l->{TYPE} eq "ARRAY" and ($l->{IS_VARYING} or $l->{IS_CONFORMANT})) {
$var_name = get_pointer_to($var_name);
}
@@ -944,14 +954,16 @@ sub ParseElementPullLevel
my $nl = GetNextLevel($e, $l);
if (is_charset_array($e,$l)) {
+ if ($l->{IS_ZERO_TERMINATED}) {
+ CheckStringTerminator($ndr, $e, $l, $length);
+ }
pidl "NDR_CHECK(ndr_pull_charset($ndr, $ndr_flags, ".get_pointer_to($var_name).", $length, sizeof(" . mapType($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));";
return;
} elsif (has_fast_array($e, $l)) {
- pidl "NDR_CHECK(ndr_pull_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));";
if ($l->{IS_ZERO_TERMINATED}) {
- # Make sure last element is zero!
- pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $var_name, $length, sizeof(*$var_name)));";
+ CheckStringTerminator($ndr,$e,$l,$length);
}
+ pidl "NDR_CHECK(ndr_pull_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));";
return;
}
} elsif ($l->{TYPE} eq "POINTER") {
@@ -1001,16 +1013,17 @@ sub ParseElementPullLevel
ParseMemCtxPullStart($e,$l, $array_name);
if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) {
+ my $nl = GetNextLevel($e,$l);
+
+ if ($l->{IS_ZERO_TERMINATED}) {
+ CheckStringTerminator($ndr,$e,$l,$length);
+ }
+
pidl "for ($counter = 0; $counter < $length; $counter++) {";
indent;
- ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 1, 0);
+ ParseElementPullLevel($e, $nl, $ndr, $var_name, $env, 1, 0);
deindent;
pidl "}";
-
- if ($l->{IS_ZERO_TERMINATED}) {
- # Make sure last element is zero!
- pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $var_name, $length, sizeof(*$var_name)));";
- }
}
if ($deferred and ContainsDeferred($e, $l)) {
@@ -1128,13 +1141,22 @@ sub ParseStructPush($$)
# we need to push the conformant length early, as it fits on
# the wire before the structure (and even before the structure
# alignment)
- my $e = $struct->{ELEMENTS}[-1];
if (defined($struct->{SURROUNDING_ELEMENT})) {
my $e = $struct->{SURROUNDING_ELEMENT};
if (defined($e->{LEVELS}[0]) and
$e->{LEVELS}[0]->{TYPE} eq "ARRAY") {
- my $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env);
+ my $size;
+
+ if ($e->{LEVELS}[0]->{IS_ZERO_TERMINATED}) {
+ if (has_property($e, "charset")) {
+ $size = "ndr_charset_length(r->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})";
+ } else {
+ $size = "ndr_string_length(r->$e->{NAME}, sizeof(*r->$e->{NAME}))";
+ }
+ } else {
+ $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env);
+ }
pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));";
} else {
@@ -1627,15 +1649,17 @@ sub ParseUnionPrint($$)
my ($e,$name) = @_;
my $have_default = 0;
- pidl "int level = ndr_print_get_switch_value(ndr, r);";
-
+ pidl "int level;";
foreach my $el (@{$e->{ELEMENTS}}) {
DeclareArrayVariables($el);
}
- pidl "ndr_print_union(ndr, name, level, \"$name\");";
start_flags($e);
+ pidl "level = ndr_print_get_switch_value(ndr, r);";
+
+ pidl "ndr_print_union(ndr, name, level, \"$name\");";
+
pidl "switch (level) {";
indent;
foreach my $el (@{$e->{ELEMENTS}}) {
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/Client.pm b/tools/pidl/lib/Parse/Pidl/Samba3/Client.pm
index ee1ab09324..ceeb81c3d7 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/Client.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/Client.pm
@@ -84,11 +84,12 @@ sub ParseFunction($$)
pidl "/* Return variables */";
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless (grep(/out/, @{$e->{DIRECTION}}));
-
+
if ($e->{LEVELS}[0]->{TYPE} ne "POINTER") {
warning($e->{ORIGINAL}, "First element not a pointer for [out] argument");
next;
}
+
CopyLevel($e, $e->{LEVELS}[1], $e->{NAME}, "r.$e->{NAME}");
}
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/Header.pm b/tools/pidl/lib/Parse/Pidl/Samba3/Header.pm
index 78bd8fe339..b49e64c337 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/Header.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/Header.pm
@@ -9,7 +9,7 @@ use strict;
use Parse::Pidl::Typelist qw(hasType getType);
use Parse::Pidl::Util qw(has_property ParseExpr);
use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
-use Parse::Pidl::Samba3::Types qw(DeclShort);
+use Parse::Pidl::Samba3::Types qw(DeclShort StringType);
use vars qw($VERSION);
$VERSION = '0.01';
@@ -28,12 +28,15 @@ sub ParseElement($)
foreach my $l (@{$e->{LEVELS}}) {
if ($l->{TYPE} eq "POINTER") {
- return if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "top");
+ next if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP");
pidl "\tuint32 ptr$l->{POINTER_INDEX}_$e->{NAME};";
} elsif ($l->{TYPE} eq "SWITCH") {
- pidl "\tuint32 level_$e->{NAME};";
} elsif ($l->{TYPE} eq "DATA") {
pidl "\t" . DeclShort($e) . ";";
+ } elsif ($l->{TYPE} eq "ARRAY" and $l->{IS_ZERO_TERMINATED}) {
+ my ($t,$f) = StringType($e,$l);
+ pidl "\t" . uc($t) . " $e->{NAME};";
+ return;
} elsif ($l->{TYPE} eq "ARRAY") {
if ($l->{IS_CONFORMANT}) {
pidl "\tuint32 size_$e->{NAME};";
@@ -104,32 +107,34 @@ sub ParseUnion($$$)
{
my ($if,$u,$n) = @_;
- my $extra = {};
-
- unless (has_property($u, "nodiscriminant")) {
- $extra->{switch_value} = 1;
+ my $extra = {
+ switch_value => $u->{SWITCH_TYPE}
+ };
+
+ if (not defined($extra->{switch_value})) {
+ $extra->{switch_value} = "uint32";
}
foreach my $e (@{$u->{ELEMENTS}}) {
foreach my $l (@{$e->{LEVELS}}) {
if ($l->{TYPE} eq "ARRAY") {
if ($l->{IS_CONFORMANT}) {
- $extra->{"size"} = 1;
+ $extra->{"size"} = "uint32";
}
if ($l->{IS_VARYING}) {
- $extra->{"length"} = $extra->{"offset"} = 1;
+ $extra->{"length"} = $extra->{"offset"} = "uint32";
}
} elsif ($l->{TYPE} eq "POINTER") {
- $extra->{"ptr$l->{POINTER_INDEX}"} = 1;
+ $extra->{"ptr$l->{POINTER_INDEX}"} = "uint32";
} elsif ($l->{TYPE} eq "SWITCH") {
- $extra->{"level"} = 1;
+ $extra->{"level"} = "uint32";
}
}
}
pidl "typedef struct $if->{NAME}_$n\_ctr {";
indent;
- pidl "uint32 $_;" foreach (keys %$extra);
+ pidl "$extra->{$_} $_;" foreach (keys %$extra);
pidl "union $if->{NAME}_$n {";
indent;
foreach (@{$u->{ELEMENTS}}) {
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm b/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm
index eaab50b553..9ef8f09dc4 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm
@@ -9,7 +9,7 @@ use strict;
use Parse::Pidl::Typelist qw(hasType getType mapType);
use Parse::Pidl::Util qw(has_property ParseExpr);
use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
-use Parse::Pidl::Samba3::Types qw(DeclShort DeclLong InitType DissectType);
+use Parse::Pidl::Samba3::Types qw(DeclShort DeclLong InitType DissectType StringType);
use vars qw($VERSION);
$VERSION = '0.01';
@@ -27,7 +27,7 @@ sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
#TODO:
# - Add some security checks (array sizes, memory alloc == NULL, etc)
# - Don't add seperate _p and _d functions if there is no deferred data
-# - [string]
+# - [string] with non-varying arrays and "surrounding" strings
# - subcontext()
# - DATA_BLOB
@@ -58,7 +58,7 @@ sub DeclareArrayVariables
next if ($l->{IS_DEFERRED} and $what == PRIMITIVES);
next if (not $l->{IS_DEFERRED} and $what == DEFERRED);
}
- if ($l->{TYPE} eq "ARRAY") {
+ if ($l->{TYPE} eq "ARRAY" and not $l->{IS_ZERO_TERMINATED}) {
pidl "uint32 i_$e->{NAME}_$l->{LEVEL_INDEX};";
$output = 1;
}
@@ -71,15 +71,7 @@ sub ParseElementLevelData($$$$$$$)
{
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
- my @args = ($e,$l,$varname,$what,$align);
-
- # See if we need to add a level argument because we're parsing a union
- foreach (@{$e->{LEVELS}}) {
- push (@args, ParseExpr("level_$e->{NAME}", $env))
- if ($_->{TYPE} eq "SWITCH");
- }
-
- my $c = DissectType(@args);
+ my $c = DissectType($e,$l,$varname,$what,$align);
return if not $c;
if (defined($e->{ALIGN})) {
@@ -98,9 +90,16 @@ sub ParseElementLevelArray($$$$$$$)
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
if ($l->{IS_ZERO_TERMINATED}) {
- fatal($e, "[string] attribute not supported for Samba3 yet");
+ return if ($what == DEFERRED);
- #FIXME
+ my ($t,$f) = StringType($e,$l);
+
+ Align($align, 4);
+ pidl "if (!smb_io_$t(\"$e->{NAME}\", &$varname, 1, ps, depth))";
+ pidl "\treturn False;";
+
+ $$align = 0;
+ return;
}
my $len = ParseExpr($l->{LENGTH_IS}, $env);
@@ -236,7 +235,9 @@ sub InitLevel($$$$)
indent;
}
- pidl ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 1;";
+ unless ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP") {
+ pidl ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 1;";
+ }
InitLevel($e, GetNextLevel($e,$l), "*$varname", $env);
if ($l->{POINTER_TYPE} ne "ref") {
@@ -245,12 +246,16 @@ sub InitLevel($$$$)
pidl "\t" . ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 0;";
pidl "}";
}
+ } elsif ($l->{TYPE} eq "ARRAY" and $l->{IS_ZERO_TERMINATED}) {
+ my ($t,$f) = StringType($e,$l);
+ pidl "init_$t(&" . ParseExpr($e->{NAME}, $env) . ", ".substr($varname, 1) . ", $f);";
} elsif ($l->{TYPE} eq "ARRAY") {
pidl ParseExpr($e->{NAME}, $env) . " = $varname;";
} elsif ($l->{TYPE} eq "DATA") {
pidl InitType($e, $l, ParseExpr($e->{NAME}, $env), $varname);
} elsif ($l->{TYPE} eq "SWITCH") {
InitLevel($e, GetNextLevel($e,$l), $varname, $env);
+ pidl ParseExpr($e->{NAME}, $env) . ".switch_value = " . ParseExpr($l->{SWITCH_IS}, $env) . ";";
}
}
@@ -263,8 +268,7 @@ sub GenerateEnvElement($$)
} elsif ($l->{TYPE} eq "POINTER") {
$env->{"ptr$l->{POINTER_INDEX}_$e->{NAME}"} = "v->ptr$l->{POINTER_INDEX}_$e->{NAME}";
} elsif ($l->{TYPE} eq "SWITCH") {
- $env->{"level_$e->{NAME}"} = "v->level_$e->{NAME}";
- } elsif ($l->{TYPE} eq "ARRAY") {
+ } elsif ($l->{TYPE} eq "ARRAY" and not $l->{IS_ZERO_TERMINATED}) {
$env->{"length_$e->{NAME}"} = "v->length_$e->{NAME}";
$env->{"size_$e->{NAME}"} = "v->size_$e->{NAME}";
$env->{"offset_$e->{NAME}"} = "v->offset_$e->{NAME}";
@@ -368,8 +372,7 @@ sub UnionGenerateEnvElement($)
} elsif ($l->{TYPE} eq "POINTER") {
$env->{"ptr$l->{POINTER_INDEX}_$e->{NAME}"} = "v->ptr$l->{POINTER_INDEX}";
} elsif ($l->{TYPE} eq "SWITCH") {
- $env->{"level_$e->{NAME}"} = "v->level";
- } elsif ($l->{TYPE} eq "ARRAY") {
+ } elsif ($l->{TYPE} eq "ARRAY" and not $l->{IS_ZERO_TERMINATED}) {
$env->{"length_$e->{NAME}"} = "v->length";
$env->{"size_$e->{NAME}"} = "v->size";
$env->{"offset_$e->{NAME}"} = "v->offset";
@@ -389,20 +392,20 @@ sub ParseUnion($$$)
my $pfn = "$fn\_p";
my $dfn = "$fn\_d";
- pidl "BOOL $pfn(const char *desc, $sn* v, uint32 level, prs_struct *ps, int depth)";
+ pidl "BOOL $pfn(const char *desc, $sn* v, prs_struct *ps, int depth)";
pidl "{";
indent;
DeclareArrayVariables($u->{ELEMENTS});
- unless (has_property($u, "nodiscriminant")) {
- pidl "if (!prs_uint32(\"switch_value\", ps, depth, &v->switch_value))";
+ if (defined ($u->{SWITCH_TYPE})) {
+ pidl "if (!prs_$u->{SWITCH_TYPE}(\"switch_value\", ps, depth, &v->switch_value))";
pidl "\treturn False;";
pidl "";
}
# Maybe check here that level and v->switch_value are equal?
- pidl "switch (level) {";
+ pidl "switch (v->switch_value) {";
indent;
foreach (@{$u->{ELEMENTS}}) {
@@ -420,19 +423,30 @@ sub ParseUnion($$$)
pidl "";
}
+ unless ($u->{HAS_DEFAULT}) {
+ pidl "default:";
+ pidl "\treturn False;";
+ pidl "";
+ }
+
deindent;
pidl "}";
pidl "";
pidl "return True;";
deindent;
pidl "}";
+ pidl "";
- pidl "BOOL $dfn(const char *desc, $sn* v, uint32 level, prs_struct *ps, int depth)";
+ pidl "BOOL $dfn(const char *desc, $sn* v, prs_struct *ps, int depth)";
pidl "{";
indent;
DeclareArrayVariables($u->{ELEMENTS});
- pidl "switch (level) {";
+ if (defined($u->{SWITCH_TYPE})) {
+ pidl "switch (v->switch_value) {";
+ } else {
+ pidl "switch (level) {";
+ }
indent;
foreach (@{$u->{ELEMENTS}}) {
@@ -459,16 +473,14 @@ sub ParseUnion($$$)
}
-sub CreateFnDirection($$$$)
+sub CreateFnDirection($$$$$)
{
- my ($fn,$ifn, $s,$es) = @_;
+ my ($fn,$ifn,$s,$all,$es) = @_;
my $args = "";
- foreach (@$es) {
- $args .= ", " . DeclLong($_);
- }
+ foreach (@$all) { $args .= ", " . DeclLong($_); }
- my $env = { "this" => "v" };
+ my $env = { };
GenerateEnvElement($_, $env) foreach (@$es);
pidl "BOOL $ifn($s *v$args)";
@@ -515,6 +527,7 @@ sub ParseFunction($$)
my @in = ();
my @out = ();
+ my @all = @{$fn->{ELEMENTS}};
foreach (@{$fn->{ELEMENTS}}) {
push (@in, $_) if (grep(/in/, @{$_->{DIRECTION}}));
@@ -522,7 +535,7 @@ sub ParseFunction($$)
}
if (defined($fn->{RETURN_TYPE})) {
- push (@out, {
+ my $status = {
NAME => "status",
TYPE => $fn->{RETURN_TYPE},
LEVELS => [
@@ -531,17 +544,20 @@ sub ParseFunction($$)
DATA_TYPE => $fn->{RETURN_TYPE}
}
]
- } );
+ };
+
+ push (@out, $status);
+ push (@all, $status);
}
CreateFnDirection("$if->{NAME}_io_q_$fn->{NAME}",
"init_$if->{NAME}_q_$fn->{NAME}",
uc("$if->{NAME}_q_$fn->{NAME}"),
- \@in);
+ \@in, \@in);
CreateFnDirection("$if->{NAME}_io_r_$fn->{NAME}",
"init_$if->{NAME}_r_$fn->{NAME}",
uc("$if->{NAME}_r_$fn->{NAME}"),
- \@out);
+ \@all, \@out);
}
sub ParseInterface($)
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/Server.pm b/tools/pidl/lib/Parse/Pidl/Samba3/Server.pm
index 3f1f4645a1..179ace7dbb 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/Server.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/Server.pm
@@ -36,6 +36,9 @@ sub ParseFunction($$)
pidl "prs_struct *data = &p->in_data.data;";
pidl "prs_struct *rdata = &p->out_data.rdata;";
pidl "";
+ pidl "ZERO_STRUCT(q_u);";
+ pidl "ZERO_STRUCT(r_u);";
+ pidl "";
pidl "if (!$if->{NAME}_io_q_$fn->{NAME}(\"\", &q_u, data, 0))";
pidl "\treturn False;";
pidl "";
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/Types.pm b/tools/pidl/lib/Parse/Pidl/Samba3/Types.pm
index 8cb09343ac..3f7e8ae134 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/Types.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/Types.pm
@@ -7,11 +7,11 @@ package Parse::Pidl::Samba3::Types;
require Exporter;
@ISA = qw(Exporter);
-@EXPORT_OK = qw(DeclShort DeclLong InitType DissectType AddType);
+@EXPORT_OK = qw(DeclShort DeclLong InitType DissectType AddType StringType);
use strict;
use Parse::Pidl::Util qw(has_property ParseExpr property_matches);
-use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsString);
use vars qw($VERSION);
$VERSION = '0.01';
@@ -104,6 +104,20 @@ sub dissect_string($$$$$)
return "smb_io_$t(\"$e->{NAME}\", &$n, 1, ps, depth)";
}
+sub StringType($$)
+{
+ my ($e,$l) = @_;
+ my $nl = GetNextLevel($e,$l);
+
+ if ($l->{IS_VARYING} and $l->{IS_CONFORMANT} and $nl->{DATA_TYPE} eq "uint16") {
+ return ("unistr2", "UNI_FLAGS_NONE");
+ } elsif ($l->{IS_CONFORMANT} and $l->{IS_VARYING} and $nl->{DATA_TYPE} eq "uint8") {
+ return ("string2", 0);
+ } else {
+ fatal($e, "[string] non-varying string not supported for Samba3 yet");
+ }
+}
+
my $known_types =
{
uint8 =>
@@ -205,12 +219,6 @@ sub AddType($$)
$known_types->{$t} = $d;
}
-sub GetType($)
-{
- my $e = shift;
-
-}
-
# Return type without special stuff, as used in
# declarations for internal structs
sub DeclShort($)
@@ -274,7 +282,10 @@ sub DeclLong($)
my $suffixes = "";
foreach my $l (@{$e->{LEVELS}}) {
- if ($l->{TYPE} eq "ARRAY" and not $l->{IS_FIXED}) {
+ if ($l->{TYPE} eq "ARRAY" and $l->{IS_ZERO_TERMINATED}) {
+ $p = "const char";
+ last;
+ } elsif ($l->{TYPE} eq "ARRAY" and not $l->{IS_FIXED}) {
$prefixes = "*$prefixes";
} elsif ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED}) {
$suffixes.="[$l->{SIZE_IS}]";
@@ -305,14 +316,9 @@ sub InitType($$$$)
}
}
-sub DissectType
+sub DissectType($$$$$)
{
- my @args = @_;
- my $e = shift @_;
- my $l = shift @_;
- my $varname = shift @_;
- my $what = shift @_;
- my $align = shift @_;
+ my ($e,$l,$varname,$what,$align) = @_;
my $t = $known_types->{$l->{DATA_TYPE}};
@@ -332,7 +338,7 @@ sub DissectType
# DISSECT can be a function
if (ref($dissect) eq "CODE") {
- return $dissect->(@args);
+ return $dissect->($e,$l,$varname,$what,$align);
} else {
return $dissect;
}
@@ -356,31 +362,18 @@ sub LoadTypes($)
my $dissect_p;
if ($td->{DATA}->{TYPE} eq "UNION") {
$decl.="_CTR";
- $dissect_p = sub {
- my ($e,$l,$n,$w,$a,$s) = @_;
-
- return "$if->{NAME}_io_$td->{NAME}_p(\"$e->{NAME}\", &$n, $s, ps, depth)";
- };
-
- $dissect_d = sub {
- my ($e,$l,$n,$w,$a,$s) = @_;
+ }
- return "$if->{NAME}_io_$td->{NAME}_d(\"$e->{NAME}\", &$n, $s, ps, depth)";
- };
+ $dissect_p = sub {
+ my ($e,$l,$n,$w,$a) = @_;
- } else {
- $dissect_p = sub {
- my ($e,$l,$n,$w,$a) = @_;
-
- return "$if->{NAME}_io_$td->{NAME}_p(\"$e->{NAME}\", &$n, ps, depth)";
- };
- $dissect_d = sub {
- my ($e,$l,$n,$w,$a) = @_;
-
- return "$if->{NAME}_io_$td->{NAME}_d(\"$e->{NAME}\", &$n, ps, depth)";
- };
+ return "$if->{NAME}_io_$td->{NAME}_p(\"$e->{NAME}\", &$n, ps, depth)";
+ };
+ $dissect_d = sub {
+ my ($e,$l,$n,$w,$a) = @_;
- }
+ return "$if->{NAME}_io_$td->{NAME}_d(\"$e->{NAME}\", &$n, ps, depth)";
+ };
AddType($td->{NAME}, {
DECL => $decl,
diff --git a/tools/pidl/pidl b/tools/pidl/pidl
index 07bfefa956..facf5966d7 100755
--- a/tools/pidl/pidl
+++ b/tools/pidl/pidl
@@ -8,13 +8,15 @@
# released under the GNU GPL
=pod
+
=head1 NAME
-pidl - IDL Compiler written in Perl
+pidl - An IDL compiler written in Perl
=head1 SYNOPSIS
pidl --help
+
pidl [--outputdir[=OUTNAME]] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--ndr-header[=OUTPUT]] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--uint-enums] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--eth-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-header=[OUTPUT]] [--tdr-parser[=OUTPUT]] [--samba3-header[=OUTPUT]] [--samba3-parser=[OUTPUT]] [--samba3-server=[OUTPUT]] [--samba3-template[=OUTPUT]] [--samba3-client[=OUTPUT]] [<idlfile>.idl]...
=head1 DESCRIPTION
@@ -95,8 +97,8 @@ packet-dcerpc-OUTNAME.h.
Pidl will read additional data from an ethereal conformance file if present.
Such a file should have the same location as the IDL file but with the
-extension I<cnf> rather then I<idl>. See below for details on the format of
-this file.
+extension I<cnf> rather then I<idl>. See L<Parse::Pidl::Ethereal::Conformance>
+for details on the format of this file.
=item I<--diff>
@@ -273,7 +275,7 @@ Datagram support (ncadg_*)
in, out, ref, length_is, switch_is, size_is, uuid, case, default, string,
unique, ptr, pointer_default, v1_enum, object, helpstring, range, local,
-call_as, endpoint, switch_type, progid, coclass, iid_is.
+call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as.
=head2 PIDL Specific properties
@@ -354,82 +356,26 @@ oleautomation, optional, pragma, propget, propputref, propput, readonly,
requestedit, restricted, retval, source, transmit_as, uidefault,
usesgetlasterror, vararg, vi_progid, wire_marshal.
-=head1 ETHEREAL CONFORMANCE FILES
-
-Pidl needs additional data for ethereal output. This data is read from
-so-called conformance files. This section describes the format of these
-files.
-
-Conformance files are simple text files with a single command on each line.
-Empty lines and lines starting with a '#' character are ignored.
-Arguments to commands are seperated by spaces.
-
-The following commands are currently supported:
-
-=over 4
-
-=item I<TYPE> name dissector ft_type base_type mask valsstring alignment
-
-Register new data type with specified name, what dissector function to call
-and what properties to give header fields for elements of this type.
-
-=item I<NOEMIT> type
-
-Suppress emitting a dissect_type function for the specified type
-
-=item I<PARAM_VALUE> type param
-
-Set parameter to specify to dissector function for given type.
-
-=item I<HF_FIELD> hf title filter ft_type base_type valsstring mask description
-
-Generate a custom header field with specified properties.
-
-=item I<HF_RENAME> old_hf_name new_hf_name
-
-Force the use of new_hf_name when the parser generator was going to
-use old_hf_name.
-
-This can be used in conjunction with HF_FIELD in order to make more then
-one element use the same filter name.
-
-=item I<STRIP_PREFIX> prefix
-
-Remove the specified prefix from all function names (if present).
-
-=item I<PROTOCOL> longname shortname filtername
-
-Change the short-, long- and filter-name for the current interface in
-Ethereal.
-
-=item I<FIELD_DESCRIPTION> field desc
-
-Change description for the specified header field. `field' is the hf name of the field.
-
-=item I<IMPORT> dissector code...
-
-Code to insert when generating the specified dissector. @HF@ and
-@PARAM@ will be substituted.
-
-=back
-
=head1 EXAMPLES
# Generating an ethereal parser
$ ./pidl --eth-parser -- atsvc.idl
- # Generating a TDR parser
+ # Generating a TDR parser and header
$ ./pidl --tdr-parser --tdr-header --header -- regf.idl
-=head1 VERSION
+ # Generating a Samba3 parser, client and server
+ $ ./pidl --samba3-parser --samba3-server --samba3-client -- dfs.idl
-This man page is correct for version 4.0 of the Samba suite. L<http://www.samba.org/>.
+ # Generating a Samba4 NDR parser, client and server
+ $ ./pidl --ndr-parser --ndr-client --ndr-server -- samr.idl
=head1 SEE ALSO
L<http://msdn.microsoft.com/library/en-us/rpc/rpc/field_attributes.asp>,
L<http://wiki.ethereal.com/DCE/RPC>,
-yapp(1)
+L<http://www.samba.org/>,
+L<yapp(1)>
=head1 LICENSE
@@ -438,7 +384,7 @@ pidl is licensed under the GNU General Public License L<http://www.gnu.org/licen
=head1 AUTHOR
pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim Potter and Jelmer
-Vernooij.
+Vernooij. The current maintainer is Jelmer Vernooij.
This manpage was written by Jelmer Vernooij, partially based on the original
pidl README by Andrew Tridgell.
@@ -536,7 +482,8 @@ my($opt_warn_compat) = 0;
sub ShowHelp()
{
print "perl IDL parser and code generator
-Copyright (C) tridge\@samba.org
+Copyright (C) Andrew Tridgell <tridge\@samba.org>
+Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
Usage: pidl [options] [--] <idlfile> [<idlfile>...]