From aba7014e41b120e8c4bac5d5dab91655b46a2175 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 27 May 2005 14:01:22 +0000 Subject: [PATCH] r7022: Add support for parsing definitions of multi-dimension arrays. This will also be required for supporting parsing pointers to arrays and arrays of pointers simultaneously. (This used to be commit a34f848b02a6e8284d62532a792a5136e846fe8f) --- source4/build/pidl/com_header.pm | 8 +- source4/build/pidl/dump.pm | 4 +- source4/build/pidl/eth_header.pm | 2 +- source4/build/pidl/eth_parser.pm | 80 +++------------ source4/build/pidl/idl.pm | 165 +++++++++++++++++-------------- source4/build/pidl/idl.yp | 7 +- source4/build/pidl/ndr.pm | 31 +++--- source4/build/pidl/ndr_header.pm | 6 +- source4/build/pidl/util.pm | 15 --- 9 files changed, 138 insertions(+), 180 deletions(-) diff --git a/source4/build/pidl/com_header.pm b/source4/build/pidl/com_header.pm index 95bbc9c720c..1e5f338828e 100644 --- a/source4/build/pidl/com_header.pm +++ b/source4/build/pidl/com_header.pm @@ -22,14 +22,14 @@ sub GetArgumentProtoList($) $res .= "*"; } - if (defined $a->{ARRAY_LEN} && - !util::is_constant($a->{ARRAY_LEN}) && + if (defined $a->{ARRAY_LEN}[0] && + !util::is_constant($a->{ARRAY_LEN}[0]) && !$a->{POINTERS}) { $res .= "*"; } $res .= $a->{NAME}; - if (defined $a->{ARRAY_LEN} && util::is_constant($a->{ARRAY_LEN})) { - $res .= "[$a->{ARRAY_LEN}]"; + if (defined $a->{ARRAY_LEN}[0] && util::is_constant($a->{ARRAY_LEN}[0])) { + $res .= "[$a->{ARRAY_LEN}[0]]"; } } diff --git a/source4/build/pidl/dump.pm b/source4/build/pidl/dump.pm index 9e896cd2567..2cd0c140a58 100644 --- a/source4/build/pidl/dump.pm +++ b/source4/build/pidl/dump.pm @@ -51,7 +51,9 @@ sub DumpElement($) $res .= "*"; } $res .= "$element->{NAME}"; - (defined $element->{ARRAY_LEN}) && ($res .= "[$element->{ARRAY_LEN}]"); + foreach (@{$element->{ARRAY_LEN}}) { + $res .= "[$_]"; + } return $res; } diff --git a/source4/build/pidl/eth_header.pm b/source4/build/pidl/eth_header.pm index f0a57788544..2e0397df37a 100644 --- a/source4/build/pidl/eth_header.pm +++ b/source4/build/pidl/eth_header.pm @@ -44,7 +44,7 @@ sub HeaderTypedefProto($) sub HeaderConst($) { my($const) = shift; - if (!defined($const->{ARRAY_LEN})) { + if (!defined($const->{ARRAY_LEN}[0])) { pidl "#define $const->{NAME}\t( $const->{VALUE} )\n"; } else { pidl "#define $const->{NAME}\t $const->{VALUE}\n"; diff --git a/source4/build/pidl/eth_parser.pm b/source4/build/pidl/eth_parser.pm index a2e1bf051ce..d0a4ae7c66f 100644 --- a/source4/build/pidl/eth_parser.pm +++ b/source4/build/pidl/eth_parser.pm @@ -29,43 +29,19 @@ sub NeededFunction($$) } # for Ethereal - if (Ndr::is_scalar_type($e->{TYPE})) { - - if (defined($e->{ARRAY_LEN}) or - util::has_property($e, "size_is")) { - - # Array of scalar types - - $needed->{"hf_$fn->{NAME}_$e->{NAME}_array"} = { - 'name' => field2name($e->{NAME}), - 'type' => $e->{TYPE}, - 'ft' => "FT_BYTES", - 'base' => elementbase($e) - }; - - } else { - $needed->{"hf_$fn->{NAME}_$e->{NAME}"} = { - 'name' => field2name($e->{NAME}), - 'type' => $e->{TYPE}, - 'ft' => type2ft($e->{TYPE}), - 'base' => elementbase($e) - }; - } - } else { - $needed->{"hf_$fn->{NAME}_$e->{NAME}"} = { + $needed->{"hf_$fn->{NAME}_$e->{NAME}"} = { 'name' => field2name($e->{NAME}), 'type' => $e->{TYPE}, 'ft' => type2ft($e->{TYPE}), 'base' => elementbase($e) - }; - $needed->{"hf_$e->{TYPE}"} = { + }; + $needed->{"hf_$e->{TYPE}"} = { 'name' => field2name($e->{NAME}), 'type' => $e->{TYPE}, 'ft' => type2ft($e->{TYPE}), 'base' => elementbase($e) - }; - $needed->{"ett_$e->{TYPE}"} = 1; - } + }; + $needed->{"ett_$e->{TYPE}"} = 1; } # Add entry for return value @@ -97,43 +73,13 @@ sub NeededTypedef($$) $needed->{"pull_$e->{TYPE}"} = 1; } - if (Ndr::is_scalar_type($e->{TYPE})) { - if (defined($e->{ARRAY_LEN}) or - util::has_property($e, "size_is")) { - - # Arrays of scalar types are FT_BYTES - - $needed->{"hf_$t->{NAME}_$e->{NAME}_array"} = { - 'name' => field2name($e->{NAME}), - 'type' => $e->{TYPE}, - 'ft' => "FT_BYTES", - 'base' => elementbase($e) - }; - - } else { - $needed->{"hf_$t->{NAME}_$e->{NAME}"} = { - 'name' => field2name($e->{NAME}), - 'type' => $e->{TYPE}, - 'ft' => type2ft($e->{TYPE}), - 'base' => elementbase($e) - }; - } - - $e->{PARENT} = $t->{DATA}; - - if ($needed->{"pull_$t->{NAME}"}) { - $needed->{"pull_$e->{TYPE}"} = 1; - } - - } else { - $needed->{"hf_$t->{NAME}_$e->{NAME}"} = { - 'name' => field2name($e->{NAME}), - 'type' => $e->{TYPE}, - 'ft' => type2ft($e->{TYPE}), - 'base' => elementbase($e) - }; - $needed->{"ett_$e->{TYPE}"} = 1; - } + $needed->{"hf_$t->{NAME}_$e->{NAME}"} = { + 'name' => field2name($e->{NAME}), + 'type' => $e->{TYPE}, + 'ft' => type2ft($e->{TYPE}), + 'base' => elementbase($e) + }; + $needed->{"ett_$e->{TYPE}"} = 1; } } @@ -1319,7 +1265,7 @@ sub RegisterInterfaceHandoff($) indent; pidl "dcerpc_init_uuid(proto_dcerpc_pidl_$x->{NAME}, ett_dcerpc_$x->{NAME},"; pidl "\t&uuid_dcerpc_$x->{NAME}, ver_dcerpc_$x->{NAME},"; - pidl "\tdcerpc_dissectors, hf_opnum);"; + pidl "\tdcerpc_dissectors, hf_$x->{NAME}_opnum);"; deindent; pidl "}"; } diff --git a/source4/build/pidl/idl.pm b/source4/build/pidl/idl.pm index d5100812ed6..1e15db18c8c 100644 --- a/source4/build/pidl/idl.pm +++ b/source4/build/pidl/idl.pm @@ -1622,7 +1622,13 @@ sub new { } }, {#State 143 - DEFAULT => -58 + ACTIONS => { + "[" => 122 + }, + DEFAULT => -57, + GOTOS => { + 'array_len' => 160 + } }, {#State 144 DEFAULT => -24 @@ -1632,7 +1638,7 @@ sub new { }, {#State 146 ACTIONS => { - ";" => 160 + ";" => 161 } }, {#State 147 @@ -1642,7 +1648,7 @@ sub new { ACTIONS => { 'IDENTIFIER' => 9, "union" => 76, - ";" => 161, + ";" => 162, "enum" => 77, "[" => 7, 'void' => 79, @@ -1699,19 +1705,19 @@ sub new { {#State 153 DEFAULT => -49, GOTOS => { - 'pointers' => 162 + 'pointers' => 163 } }, {#State 154 DEFAULT => -60, GOTOS => { - 'base_element' => 163, + 'base_element' => 164, 'property_list' => 134 } }, {#State 155 ACTIONS => { - ";" => 164 + ";" => 165 } }, {#State 156 @@ -1721,7 +1727,7 @@ sub new { ACTIONS => { "-" => 34, "<" => 35, - ";" => 165, + ";" => 166, "+" => 36, "&" => 38, "{" => 37, @@ -1737,45 +1743,57 @@ sub new { DEFAULT => -16 }, {#State 159 - DEFAULT => -59 - }, - {#State 160 - DEFAULT => -42 - }, - {#State 161 - DEFAULT => -41 - }, - {#State 162 - ACTIONS => { - 'IDENTIFIER' => 9, - "*" => 167 - }, - GOTOS => { - 'identifier' => 166 - } - }, - {#State 163 - DEFAULT => -56 - }, - {#State 164 - DEFAULT => -18 - }, - {#State 165 - DEFAULT => -17 - }, - {#State 166 ACTIONS => { "[" => 122 }, DEFAULT => -57, GOTOS => { - 'array_len' => 168 + 'array_len' => 167 } }, + {#State 160 + DEFAULT => -58 + }, + {#State 161 + DEFAULT => -42 + }, + {#State 162 + DEFAULT => -41 + }, + {#State 163 + ACTIONS => { + 'IDENTIFIER' => 9, + "*" => 169 + }, + GOTOS => { + 'identifier' => 168 + } + }, + {#State 164 + DEFAULT => -56 + }, + {#State 165 + DEFAULT => -18 + }, + {#State 166 + DEFAULT => -17 + }, {#State 167 - DEFAULT => -50 + DEFAULT => -59 }, {#State 168 + ACTIONS => { + "[" => 122 + }, + DEFAULT => -57, + GOTOS => { + 'array_len' => 170 + } + }, + {#State 169 + DEFAULT => -50 + }, + {#State 170 DEFAULT => -48 } ], @@ -2054,6 +2072,7 @@ sub "TYPE" => "EMPTY", "PROPERTIES" => $_[1], "POINTERS" => 0, + "ARRAY_LEN" => [], "FILE" => $_[0]->YYData->{INPUT_FILENAME}, "LINE" => $_[0]->YYData->{LINE}, }} @@ -2067,7 +2086,7 @@ sub [#Rule 44 'optional_base_element', 2, sub -#line 194 "build/pidl/idl.yp" +#line 195 "build/pidl/idl.yp" { $_[2]->{PROPERTIES} = util::FlattenHash([$_[1],$_[2]->{PROPERTIES}]); $_[2] } ], [#Rule 45 @@ -2076,13 +2095,13 @@ sub [#Rule 46 'union_elements', 2, sub -#line 199 "build/pidl/idl.yp" +#line 200 "build/pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 47 'union', 4, sub -#line 203 "build/pidl/idl.yp" +#line 204 "build/pidl/idl.yp" {{ "TYPE" => "UNION", "ELEMENTS" => $_[3] @@ -2091,7 +2110,7 @@ sub [#Rule 48 'base_element', 5, sub -#line 210 "build/pidl/idl.yp" +#line 211 "build/pidl/idl.yp" {{ "NAME" => $_[4], "TYPE" => $_[2], @@ -2105,13 +2124,13 @@ sub [#Rule 49 'pointers', 0, sub -#line 224 "build/pidl/idl.yp" +#line 225 "build/pidl/idl.yp" { 0 } ], [#Rule 50 'pointers', 2, sub -#line 225 "build/pidl/idl.yp" +#line 226 "build/pidl/idl.yp" { $_[1]+1 } ], [#Rule 51 @@ -2120,7 +2139,7 @@ sub [#Rule 52 'element_list1', 3, sub -#line 230 "build/pidl/idl.yp" +#line 231 "build/pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 53 @@ -2132,29 +2151,29 @@ sub [#Rule 55 'element_list2', 1, sub -#line 236 "build/pidl/idl.yp" +#line 237 "build/pidl/idl.yp" { [ $_[1] ] } ], [#Rule 56 'element_list2', 3, sub -#line 237 "build/pidl/idl.yp" +#line 238 "build/pidl/idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], [#Rule 57 'array_len', 0, undef ], [#Rule 58 - 'array_len', 2, -sub -#line 242 "build/pidl/idl.yp" -{ "*" } - ], - [#Rule 59 'array_len', 3, sub #line 243 "build/pidl/idl.yp" -{ "$_[2]" } +{ push(@{$_[3]}, "*"); $_[3] } + ], + [#Rule 59 + 'array_len', 4, +sub +#line 244 "build/pidl/idl.yp" +{ push(@{$_[4]}, "$_[2]"); $_[4] } ], [#Rule 60 'property_list', 0, undef @@ -2162,31 +2181,31 @@ sub [#Rule 61 'property_list', 4, sub -#line 249 "build/pidl/idl.yp" +#line 250 "build/pidl/idl.yp" { util::FlattenHash([$_[1],$_[3]]); } ], [#Rule 62 'properties', 1, sub -#line 252 "build/pidl/idl.yp" +#line 253 "build/pidl/idl.yp" { $_[1] } ], [#Rule 63 'properties', 3, sub -#line 253 "build/pidl/idl.yp" +#line 254 "build/pidl/idl.yp" { util::FlattenHash([$_[1], $_[3]]); } ], [#Rule 64 'property', 1, sub -#line 256 "build/pidl/idl.yp" +#line 257 "build/pidl/idl.yp" {{ "$_[1]" => "1" }} ], [#Rule 65 'property', 4, sub -#line 257 "build/pidl/idl.yp" +#line 258 "build/pidl/idl.yp" {{ "$_[1]" => "$_[3]" }} ], [#Rule 66 @@ -2195,7 +2214,7 @@ sub [#Rule 67 'listtext', 3, sub -#line 262 "build/pidl/idl.yp" +#line 263 "build/pidl/idl.yp" { "$_[1] $_[3]" } ], [#Rule 68 @@ -2204,13 +2223,13 @@ sub [#Rule 69 'commalisttext', 3, sub -#line 267 "build/pidl/idl.yp" +#line 268 "build/pidl/idl.yp" { "$_[1],$_[3]" } ], [#Rule 70 'anytext', 0, sub -#line 271 "build/pidl/idl.yp" +#line 272 "build/pidl/idl.yp" { "" } ], [#Rule 71 @@ -2225,67 +2244,67 @@ sub [#Rule 74 'anytext', 3, sub -#line 273 "build/pidl/idl.yp" +#line 274 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 75 'anytext', 3, sub -#line 274 "build/pidl/idl.yp" +#line 275 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 76 'anytext', 3, sub -#line 275 "build/pidl/idl.yp" +#line 276 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 77 'anytext', 3, sub -#line 276 "build/pidl/idl.yp" +#line 277 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 78 'anytext', 3, sub -#line 277 "build/pidl/idl.yp" +#line 278 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 79 'anytext', 3, sub -#line 278 "build/pidl/idl.yp" +#line 279 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 80 'anytext', 3, sub -#line 279 "build/pidl/idl.yp" +#line 280 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 81 'anytext', 3, sub -#line 280 "build/pidl/idl.yp" +#line 281 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 82 'anytext', 3, sub -#line 281 "build/pidl/idl.yp" +#line 282 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 83 'anytext', 5, sub -#line 282 "build/pidl/idl.yp" +#line 283 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]$_[4]$_[5]" } ], [#Rule 84 'anytext', 5, sub -#line 283 "build/pidl/idl.yp" +#line 284 "build/pidl/idl.yp" { "$_[1]$_[2]$_[3]$_[4]$_[5]" } ], [#Rule 85 @@ -2297,7 +2316,7 @@ sub [#Rule 87 'text', 1, sub -#line 292 "build/pidl/idl.yp" +#line 293 "build/pidl/idl.yp" { "\"$_[1]\"" } ], [#Rule 88 @@ -2311,7 +2330,7 @@ sub bless($self,$class); } -#line 303 "build/pidl/idl.yp" +#line 304 "build/pidl/idl.yp" use util; diff --git a/source4/build/pidl/idl.yp b/source4/build/pidl/idl.yp index d58dc9d0233..f81316cd9fe 100644 --- a/source4/build/pidl/idl.yp +++ b/source4/build/pidl/idl.yp @@ -183,6 +183,7 @@ empty_element: property_list ';' "TYPE" => "EMPTY", "PROPERTIES" => $_[1], "POINTERS" => 0, + "ARRAY_LEN" => [], "FILE" => $_[0]->YYData->{INPUT_FILENAME}, "LINE" => $_[0]->YYData->{LINE}, }} @@ -238,9 +239,9 @@ element_list2: ; array_len: - #empty - | '[' ']' { "*" } - | '[' anytext ']' { "$_[2]" } + #empty { [] } + | '[' ']' array_len { push(@{$_[3]}, "*"); $_[3] } + | '[' anytext ']' array_len { push(@{$_[4]}, "$_[2]"); $_[4] } ; diff --git a/source4/build/pidl/ndr.pm b/source4/build/pidl/ndr.pm index 5c39578f404..a350a834eb9 100644 --- a/source4/build/pidl/ndr.pm +++ b/source4/build/pidl/ndr.pm @@ -50,22 +50,27 @@ sub GetElementLevelTable($) # FIXME: Process array here possibly (in case of multi-dimensional arrays, etc) } - if (defined($e->{ARRAY_LEN}) or util::has_property($e, "size_is")) { - my $length = util::has_property($e, "length_is"); - my $size = util::has_property($e, "size_is"); + if ((defined($e->{ARRAY_LEN}) and scalar(@{$e->{ARRAY_LEN}})) or + util::has_property($e, "size_is")) { + my @length; + my @size; - if (not defined($size) and defined($e->{ARRAY_LEN})) { - $size = $e->{ARRAY_LEN}; + if (util::has_property($e, "size_is")) { + @size = split /,/, util::has_property($e, "size_is"); + } elsif (defined($e->{ARRAY_LEN})) { + @size = @{$e->{ARRAY_LEN}}; } - if (not defined($length)) { - $length = $size; + if (util::has_property($e, "length_is")) { + @length = split /,/, util::has_property($e, "length_is"); + } else { + @length = @size; } push (@$order, { TYPE => "ARRAY", - SIZE_IS => $size, - LENGTH_IS => $length, + SIZE_IS => $size[0], + LENGTH_IS => $length[0], IS_DEFERRED => "$is_deferred", # Inline arrays (which are a pidl extension) are never encoded # as surrounding the struct they're part of @@ -169,7 +174,7 @@ sub pointer_type($) sub is_fixed_array($) { my $e = shift; - my $len = $e->{"ARRAY_LEN"}; + my $len = $e->{"ARRAY_LEN"}[0]; return 1 if (defined $len && util::is_constant($len)); return 0; } @@ -186,7 +191,7 @@ sub is_conformant_array($) sub is_inline_array($) { my $e = shift; - my $len = $e->{ARRAY_LEN}; + my $len = $e->{ARRAY_LEN}[0]; if (defined $len && $len ne "*" && !is_fixed_array($e)) { return 1; } @@ -208,8 +213,8 @@ sub is_surrounding_array($) my $e = shift; return ($e->{POINTERS} == 0 - and defined $e->{ARRAY_LEN} - and $e->{ARRAY_LEN} eq "*" + and defined $e->{ARRAY_LEN}[0] + and $e->{ARRAY_LEN}[0] eq "*" and $e == $e->{PARENT}->{ELEMENTS}[-1] and $e->{PARENT}->{TYPE} ne "FUNCTION"); } diff --git a/source4/build/pidl/ndr_header.pm b/source4/build/pidl/ndr_header.pm index bebf6937ae4..05c2f1f55c3 100644 --- a/source4/build/pidl/ndr_header.pm +++ b/source4/build/pidl/ndr_header.pm @@ -77,8 +77,8 @@ sub HeaderElement($) } } - if (defined $element->{ARRAY_LEN} && util::is_constant($element->{ARRAY_LEN})) { - pidl "[$element->{ARRAY_LEN}]"; + if (defined $element->{ARRAY_LEN}[0] && util::is_constant($element->{ARRAY_LEN}[0])) { + pidl "[$element->{ARRAY_LEN}[0]]"; } pidl ";\n"; } @@ -230,7 +230,7 @@ sub HeaderTypedefProto($) sub HeaderConst($) { my($const) = shift; - if (!defined($const->{ARRAY_LEN})) { + if (!defined($const->{ARRAY_LEN}[0])) { pidl "#define $const->{NAME}\t( $const->{VALUE} )\n"; } else { pidl "#define $const->{NAME}\t $const->{VALUE}\n"; diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm index 0037de8713a..537714adf36 100644 --- a/source4/build/pidl/util.pm +++ b/source4/build/pidl/util.pm @@ -212,21 +212,6 @@ sub is_ref_struct($) return 0; } -# determine the array size (size_is() or ARRAY_LEN) -sub array_size($) -{ - my $e = shift; - my $size = has_property($e, "size_is"); - if ($size) { - return $size; - } - $size = $e->{ARRAY_LEN}; - if ($size) { - return $size; - } - return undef; -} - # return 1 if the string is a C constant sub is_constant($) {