diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/pidl/TODO | 13 | ||||
-rw-r--r-- | tools/pidl/idl.yp | 16 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Dump.pm | 14 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Ethereal/Conformance.pm | 75 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Ethereal/NDR.pm | 47 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/IDL.pm | 405 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/NDR.pm | 52 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba/NDR/Client.pm | 2 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm | 66 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba3/Client.pm | 3 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba3/Header.pm | 29 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba3/Parser.pm | 86 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba3/Server.pm | 3 | ||||
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba3/Types.pm | 71 | ||||
-rwxr-xr-x | tools/pidl/pidl | 85 |
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>...] |