diff options
Diffstat (limited to 'tools')
36 files changed, 2342 insertions, 2339 deletions
diff --git a/tools/pidl/TODO b/tools/pidl/TODO index 7cf6a4209a..2d4ca8a265 100644 --- a/tools/pidl/TODO +++ b/tools/pidl/TODO @@ -7,10 +7,11 @@ - strip out pidl-specific properties - support nested elements - - generate names for anonymous tagged types + - allow non-typedef structs + - generate names for anonymous tagged types. Simple MD5Sum of contents? - support typedefs properly - -- improve represent_as(): allow it to be used for arrays and other complex types + - improve represent_as(): allow it to be used for arrays and other complex + types - --explain-ndr option that dumps out parse tree ? @@ -21,3 +22,10 @@ - mem_ctx in the interface rather than as struct ndr member. - real typelibs + +- fix [in,out] handling and allocation for samba3: + - add inout + - make NULL to mean "allocate me" + - remove NDR_AUTO_REF_ALLOC flag + +- automatic test generator based on IDL pointer types diff --git a/tools/pidl/idl.yp b/tools/pidl/idl.yp index 5ef4dca379..3ca02c3872 100644 --- a/tools/pidl/idl.yp +++ b/tools/pidl/idl.yp @@ -160,10 +160,10 @@ decl_union: 'union' }} ; -typedef: 'typedef' property_list type identifier array_len ';' +typedef: property_list 'typedef' type identifier array_len ';' {{ "TYPE" => "TYPEDEF", - "PROPERTIES" => $_[2], + "PROPERTIES" => $_[1], "NAME" => $_[4], "DATA" => $_[3], "ARRAY_LEN" => $_[5], @@ -187,11 +187,12 @@ type: usertype | existingtype | void { "void" } ; enum_body: '{' enum_elements '}' { $_[2] }; opt_enum_body: | enum_body; -enum: 'enum' optional_identifier opt_enum_body +enum: property_list 'enum' optional_identifier opt_enum_body {{ "TYPE" => "ENUM", - "NAME" => $_[2], - "ELEMENTS" => $_[3] + "PROPERTIES" => $_[1], + "NAME" => $_[3], + "ELEMENTS" => $_[4] }} ; @@ -206,11 +207,12 @@ enum_element: identifier bitmap_body: '{' opt_bitmap_elements '}' { $_[2] }; opt_bitmap_body: | bitmap_body; -bitmap: 'bitmap' optional_identifier opt_bitmap_body +bitmap: property_list 'bitmap' optional_identifier opt_bitmap_body {{ "TYPE" => "BITMAP", - "NAME" => $_[2], - "ELEMENTS" => $_[3] + "PROPERTIES" => $_[1], + "NAME" => $_[3], + "ELEMENTS" => $_[4] }} ; @@ -227,11 +229,12 @@ bitmap_element: identifier '=' anytext { "$_[1] ( $_[3] )" } struct_body: '{' element_list1 '}' { $_[2] }; opt_struct_body: | struct_body; -struct: 'struct' optional_identifier opt_struct_body +struct: property_list 'struct' optional_identifier opt_struct_body {{ "TYPE" => "STRUCT", - "NAME" => $_[2], - "ELEMENTS" => $_[3] + "PROPERTIES" => $_[1], + "NAME" => $_[3], + "ELEMENTS" => $_[4] }} ; @@ -261,11 +264,12 @@ union_elements: union_body: '{' union_elements '}' { $_[2] }; opt_union_body: | union_body; -union: 'union' optional_identifier opt_union_body +union: property_list 'union' optional_identifier opt_union_body {{ "TYPE" => "UNION", - "NAME" => $_[2], - "ELEMENTS" => $_[3] + "PROPERTIES" => $_[1], + "NAME" => $_[3], + "ELEMENTS" => $_[4] }} ; diff --git a/tools/pidl/lib/Parse/Pidl/Dump.pm b/tools/pidl/lib/Parse/Pidl/Dump.pm index 88f18de322..bf5811c116 100644 --- a/tools/pidl/lib/Parse/Pidl/Dump.pm +++ b/tools/pidl/lib/Parse/Pidl/Dump.pm @@ -24,7 +24,7 @@ use Exporter; use vars qw($VERSION); $VERSION = '0.01'; @ISA = qw(Exporter); -@EXPORT_OK = qw(DumpTypedef DumpStruct DumpEnum DumpBitmap DumpUnion DumpFunction); +@EXPORT_OK = qw(DumpType DumpTypedef DumpStruct DumpEnum DumpBitmap DumpUnion DumpFunction); use strict; use Parse::Pidl::Util qw(has_property); @@ -87,7 +87,12 @@ sub DumpStruct($) my($struct) = shift; my($res); - $res .= "struct {\n"; + $res .= "struct "; + if ($struct->{NAME}) { + $res.="$struct->{NAME} "; + } + + $res.="{\n"; if (defined $struct->{ELEMENTS}) { foreach (@{$struct->{ELEMENTS}}) { $res .= "\t" . DumpElement($_) . ";\n"; @@ -185,18 +190,15 @@ sub DumpUnion($) sub DumpType($) { my($data) = shift; - my($res); if (ref($data) eq "HASH") { - ($data->{TYPE} eq "STRUCT") && ($res .= DumpStruct($data)); - ($data->{TYPE} eq "UNION") && ($res .= DumpUnion($data)); - ($data->{TYPE} eq "ENUM") && ($res .= DumpEnum($data)); - ($data->{TYPE} eq "BITMAP") && ($res .= DumpBitmap($data)); + return DumpStruct($data) if ($data->{TYPE} eq "STRUCT"); + return DumpUnion($data) if ($data->{TYPE} eq "UNION"); + return DumpEnum($data) if ($data->{TYPE} eq "ENUM"); + return DumpBitmap($data) if ($data->{TYPE} eq "BITMAP"); } else { - $res .= "$data"; + return $data; } - - return $res; } ##################################################################### diff --git a/tools/pidl/lib/Parse/Pidl/Expr.pm b/tools/pidl/lib/Parse/Pidl/Expr.pm index f64db508d6..4e02be0575 100644 --- a/tools/pidl/lib/Parse/Pidl/Expr.pm +++ b/tools/pidl/lib/Parse/Pidl/Expr.pm @@ -1127,7 +1127,7 @@ sub new { [#Rule 2 'exp', 1, sub -#line 22 "expr.yp" +#line 22 "pidl/expr.yp" { "\"$_[1]\"" } ], [#Rule 3 @@ -1139,199 +1139,199 @@ sub [#Rule 5 'exp', 2, sub -#line 25 "expr.yp" +#line 25 "pidl/expr.yp" { "~$_[2]" } ], [#Rule 6 'exp', 3, sub -#line 26 "expr.yp" +#line 26 "pidl/expr.yp" { "$_[1] + $_[3]" } ], [#Rule 7 'exp', 3, sub -#line 27 "expr.yp" +#line 27 "pidl/expr.yp" { "$_[1] - $_[3]" } ], [#Rule 8 'exp', 3, sub -#line 28 "expr.yp" +#line 28 "pidl/expr.yp" { "$_[1] * $_[3]" } ], [#Rule 9 'exp', 3, sub -#line 29 "expr.yp" +#line 29 "pidl/expr.yp" { "$_[1] % $_[3]" } ], [#Rule 10 'exp', 3, sub -#line 30 "expr.yp" +#line 30 "pidl/expr.yp" { "$_[1] < $_[3]" } ], [#Rule 11 'exp', 3, sub -#line 31 "expr.yp" +#line 31 "pidl/expr.yp" { "$_[1] > $_[3]" } ], [#Rule 12 'exp', 3, sub -#line 32 "expr.yp" +#line 32 "pidl/expr.yp" { "$_[1] | $_[3]" } ], [#Rule 13 'exp', 3, sub -#line 33 "expr.yp" +#line 33 "pidl/expr.yp" { "$_[1] == $_[3]" } ], [#Rule 14 'exp', 3, sub -#line 34 "expr.yp" +#line 34 "pidl/expr.yp" { "$_[1] <= $_[3]" } ], [#Rule 15 'exp', 3, sub -#line 35 "expr.yp" +#line 35 "pidl/expr.yp" { "$_[1] => $_[3]" } ], [#Rule 16 'exp', 3, sub -#line 36 "expr.yp" +#line 36 "pidl/expr.yp" { "$_[1] << $_[3]" } ], [#Rule 17 'exp', 3, sub -#line 37 "expr.yp" +#line 37 "pidl/expr.yp" { "$_[1] >> $_[3]" } ], [#Rule 18 'exp', 3, sub -#line 38 "expr.yp" +#line 38 "pidl/expr.yp" { "$_[1] != $_[3]" } ], [#Rule 19 'exp', 3, sub -#line 39 "expr.yp" +#line 39 "pidl/expr.yp" { "$_[1] || $_[3]" } ], [#Rule 20 'exp', 3, sub -#line 40 "expr.yp" +#line 40 "pidl/expr.yp" { "$_[1] && $_[3]" } ], [#Rule 21 'exp', 3, sub -#line 41 "expr.yp" +#line 41 "pidl/expr.yp" { "$_[1] & $_[3]" } ], [#Rule 22 'exp', 5, sub -#line 42 "expr.yp" +#line 42 "pidl/expr.yp" { "$_[1]?$_[3]:$_[5]" } ], [#Rule 23 'exp', 2, sub -#line 43 "expr.yp" +#line 43 "pidl/expr.yp" { "~$_[1]" } ], [#Rule 24 'exp', 2, sub -#line 44 "expr.yp" +#line 44 "pidl/expr.yp" { "not $_[1]" } ], [#Rule 25 'exp', 3, sub -#line 45 "expr.yp" +#line 45 "pidl/expr.yp" { "$_[1] / $_[3]" } ], [#Rule 26 'exp', 2, sub -#line 46 "expr.yp" +#line 46 "pidl/expr.yp" { "-$_[2]" } ], [#Rule 27 'exp', 2, sub -#line 47 "expr.yp" +#line 47 "pidl/expr.yp" { "&$_[2]" } ], [#Rule 28 'exp', 3, sub -#line 48 "expr.yp" +#line 48 "pidl/expr.yp" { "$_[1]^$_[3]" } ], [#Rule 29 'exp', 3, sub -#line 49 "expr.yp" +#line 49 "pidl/expr.yp" { "($_[2])" } ], [#Rule 30 'possible_pointer', 1, sub -#line 53 "expr.yp" +#line 53 "pidl/expr.yp" { $_[0]->_Lookup($_[1]) } ], [#Rule 31 'possible_pointer', 2, sub -#line 54 "expr.yp" +#line 54 "pidl/expr.yp" { $_[0]->_Dereference($_[2]); "*$_[2]" } ], [#Rule 32 'var', 1, sub -#line 57 "expr.yp" +#line 57 "pidl/expr.yp" { $_[0]->_Use($_[1]) } ], [#Rule 33 'var', 3, sub -#line 58 "expr.yp" +#line 58 "pidl/expr.yp" { $_[0]->_Use("$_[1].$_[3]") } ], [#Rule 34 'var', 3, sub -#line 59 "expr.yp" +#line 59 "pidl/expr.yp" { "($_[2])" } ], [#Rule 35 'var', 3, sub -#line 60 "expr.yp" +#line 60 "pidl/expr.yp" { $_[0]->_Use("*$_[1]"); $_[1]."->".$_[3] } ], [#Rule 36 'func', 4, sub -#line 64 "expr.yp" +#line 64 "pidl/expr.yp" { "$_[1]($_[3])" } ], [#Rule 37 'opt_args', 0, sub -#line 65 "expr.yp" +#line 65 "pidl/expr.yp" { "" } ], [#Rule 38 @@ -1349,7 +1349,7 @@ sub [#Rule 42 'args', 3, sub -#line 68 "expr.yp" +#line 68 "pidl/expr.yp" { "$_[1], $_[3]" } ] ], @@ -1357,7 +1357,7 @@ sub bless($self,$class); } -#line 71 "expr.yp" +#line 71 "pidl/expr.yp" package Parse::Pidl::Expr; diff --git a/tools/pidl/lib/Parse/Pidl/IDL.pm b/tools/pidl/lib/Parse/Pidl/IDL.pm index 71c4470870..e547b2caa8 100644 --- a/tools/pidl/lib/Parse/Pidl/IDL.pm +++ b/tools/pidl/lib/Parse/Pidl/IDL.pm @@ -258,29 +258,24 @@ sub new { }, {#State 39 ACTIONS => { - "typedef" => 49, - "union" => 50, - "enum" => 63, - "bitmap" => 64, "declare" => 56, - "const" => 58, - "struct" => 61 + "const" => 60 }, DEFAULT => -91, GOTOS => { - 'typedecl' => 62, - 'function' => 51, - 'bitmap' => 65, + 'typedecl' => 49, + 'function' => 50, 'definitions' => 52, + 'bitmap' => 51, 'definition' => 55, 'property_list' => 54, 'usertype' => 53, - 'declare' => 67, - 'const' => 66, + 'const' => 59, + 'declare' => 58, 'struct' => 57, - 'enum' => 59, - 'typedef' => 60, - 'union' => 68 + 'typedef' => 62, + 'enum' => 61, + 'union' => 63 } }, {#State 40 @@ -288,28 +283,28 @@ sub new { }, {#State 41 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, DEFAULT => -97 }, {#State 42 ACTIONS => { - "," => 84, - ")" => 85 + "," => 79, + ")" => 80 } }, {#State 43 @@ -326,11 +321,11 @@ sub new { }, {#State 47 ACTIONS => { - ";" => 86 + ";" => 82 }, DEFAULT => -125, GOTOS => { - 'optional_semicolon' => 87 + 'optional_semicolon' => 81 } }, {#State 48 @@ -338,81 +333,69 @@ sub new { 'IDENTIFIER' => 22 }, GOTOS => { - 'identifier' => 88 + 'identifier' => 83 } }, {#State 49 - DEFAULT => -91, - GOTOS => { - 'property_list' => 89 - } + DEFAULT => -24 }, {#State 50 - ACTIONS => { - 'IDENTIFIER' => 90 - }, - DEFAULT => -122, - GOTOS => { - 'optional_identifier' => 91 - } + DEFAULT => -20 }, {#State 51 - DEFAULT => -20 + DEFAULT => -39 }, {#State 52 ACTIONS => { - "}" => 92, - "typedef" => 49, - "union" => 50, - "enum" => 63, - "bitmap" => 64, + "}" => 84, "declare" => 56, - "const" => 58, - "struct" => 61 + "const" => 60 }, DEFAULT => -91, GOTOS => { - 'typedecl' => 62, - 'function' => 51, - 'bitmap' => 65, - 'definition' => 93, + 'typedecl' => 49, + 'function' => 50, + 'bitmap' => 51, + 'definition' => 85, 'property_list' => 54, 'usertype' => 53, - 'const' => 66, + 'const' => 59, 'struct' => 57, - 'declare' => 67, - 'enum' => 59, - 'typedef' => 60, - 'union' => 68 + 'declare' => 58, + 'typedef' => 62, + 'enum' => 61, + 'union' => 63 } }, {#State 53 ACTIONS => { - ";" => 94 + ";" => 86 } }, {#State 54 ACTIONS => { + "typedef" => 87, 'IDENTIFIER' => 22, - "signed" => 100, - "union" => 50, - "enum" => 63, - "bitmap" => 64, - 'void' => 95, - "unsigned" => 101, + "signed" => 95, + "union" => 88, + "enum" => 97, + "bitmap" => 98, + 'void' => 89, + "unsigned" => 99, "[" => 17, - "struct" => 61 + "struct" => 94 }, GOTOS => { - 'existingtype' => 99, - 'bitmap' => 65, - 'usertype' => 96, - 'identifier' => 97, + 'existingtype' => 96, + 'bitmap' => 51, + 'usertype' => 91, + 'property_list' => 90, + 'identifier' => 92, 'struct' => 57, - 'enum' => 59, - 'type' => 102, - 'union' => 68, - 'sign' => 98 + 'enum' => 61, + 'type' => 100, + 'union' => 63, + 'sign' => 93 } }, {#State 55 @@ -421,69 +404,36 @@ sub new { {#State 56 DEFAULT => -91, GOTOS => { - 'property_list' => 103 + 'property_list' => 101 } }, {#State 57 DEFAULT => -36 }, {#State 58 - ACTIONS => { - 'IDENTIFIER' => 22 - }, - GOTOS => { - 'identifier' => 104 - } + DEFAULT => -23 }, {#State 59 - DEFAULT => -38 + DEFAULT => -21 }, {#State 60 - DEFAULT => -22 - }, - {#State 61 ACTIONS => { - 'IDENTIFIER' => 90 + 'IDENTIFIER' => 22 }, - DEFAULT => -122, GOTOS => { - 'optional_identifier' => 105 + 'identifier' => 102 } }, + {#State 61 + DEFAULT => -38 + }, {#State 62 - DEFAULT => -24 + DEFAULT => -22 }, {#State 63 - ACTIONS => { - 'IDENTIFIER' => 90 - }, - DEFAULT => -122, - GOTOS => { - 'optional_identifier' => 106 - } - }, - {#State 64 - ACTIONS => { - 'IDENTIFIER' => 90 - }, - DEFAULT => -122, - GOTOS => { - 'optional_identifier' => 107 - } - }, - {#State 65 - DEFAULT => -39 - }, - {#State 66 - DEFAULT => -21 - }, - {#State 67 - DEFAULT => -23 - }, - {#State 68 DEFAULT => -37 }, - {#State 69 + {#State 64 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -492,12 +442,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 108, + 'anytext' => 103, 'text' => 46, 'constant' => 43 } }, - {#State 70 + {#State 65 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -506,12 +456,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 109, + 'anytext' => 104, 'text' => 46, 'constant' => 43 } }, - {#State 71 + {#State 66 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -520,12 +470,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 110, + 'anytext' => 105, 'text' => 46, 'constant' => 43 } }, - {#State 72 + {#State 67 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -534,12 +484,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 111, + 'anytext' => 106, 'text' => 46, 'constant' => 43 } }, - {#State 73 + {#State 68 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -548,12 +498,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 112, + 'anytext' => 107, 'text' => 46, 'constant' => 43 } }, - {#State 74 + {#State 69 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -562,12 +512,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 113, + 'anytext' => 108, 'text' => 46, 'constant' => 43 } }, - {#State 75 + {#State 70 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -576,12 +526,13 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 114, + 'anytext' => 109, 'text' => 46, - 'constant' => 43 + 'constant' => 43, + 'commalisttext' => 110 } }, - {#State 76 + {#State 71 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -590,13 +541,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 115, + 'anytext' => 111, 'text' => 46, - 'constant' => 43, - 'commalisttext' => 116 + 'constant' => 43 } }, - {#State 77 + {#State 72 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -605,12 +555,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 117, + 'anytext' => 112, 'text' => 46, 'constant' => 43 } }, - {#State 78 + {#State 73 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -619,12 +569,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 118, + 'anytext' => 113, 'text' => 46, 'constant' => 43 } }, - {#State 79 + {#State 74 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -633,12 +583,13 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 119, + 'anytext' => 109, 'text' => 46, - 'constant' => 43 + 'constant' => 43, + 'commalisttext' => 114 } }, - {#State 80 + {#State 75 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -649,11 +600,10 @@ sub new { 'identifier' => 45, 'anytext' => 115, 'text' => 46, - 'constant' => 43, - 'commalisttext' => 120 + 'constant' => 43 } }, - {#State 81 + {#State 76 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -662,12 +612,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 121, + 'anytext' => 116, 'text' => 46, 'constant' => 43 } }, - {#State 82 + {#State 77 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -676,12 +626,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 122, + 'anytext' => 117, 'text' => 46, 'constant' => 43 } }, - {#State 83 + {#State 78 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -690,12 +640,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 123, + 'anytext' => 118, 'text' => 46, 'constant' => 43 } }, - {#State 84 + {#State 79 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -704,517 +654,501 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 124, + 'anytext' => 119, 'text' => 46, 'constant' => 43 } }, - {#State 85 + {#State 80 DEFAULT => -96 }, - {#State 86 + {#State 81 + DEFAULT => -12 + }, + {#State 82 DEFAULT => -126 }, - {#State 87 - DEFAULT => -12 + {#State 83 + ACTIONS => { + ";" => 120 + } }, - {#State 88 + {#State 84 ACTIONS => { - ";" => 125 + ";" => 82 + }, + DEFAULT => -125, + GOTOS => { + 'optional_semicolon' => 121 } }, - {#State 89 + {#State 85 + DEFAULT => -19 + }, + {#State 86 + DEFAULT => -40 + }, + {#State 87 ACTIONS => { 'IDENTIFIER' => 22, - "signed" => 100, - "union" => 50, - "enum" => 63, - "bitmap" => 64, - 'void' => 95, - "unsigned" => 101, - "[" => 17, - "struct" => 61 + "signed" => 95, + 'void' => 89, + "unsigned" => 99 }, + DEFAULT => -91, GOTOS => { - 'existingtype' => 99, - 'bitmap' => 65, - 'usertype' => 96, - 'identifier' => 97, + 'existingtype' => 96, + 'bitmap' => 51, + 'usertype' => 91, + 'property_list' => 90, + 'identifier' => 92, 'struct' => 57, - 'enum' => 59, - 'type' => 126, - 'union' => 68, - 'sign' => 98 + 'enum' => 61, + 'type' => 122, + 'union' => 63, + 'sign' => 93 } }, - {#State 90 - DEFAULT => -121 - }, - {#State 91 + {#State 88 ACTIONS => { - "{" => 128 + 'IDENTIFIER' => 123 }, - DEFAULT => -76, + DEFAULT => -122, GOTOS => { - 'union_body' => 129, - 'opt_union_body' => 127 + 'optional_identifier' => 124 + } + }, + {#State 89 + DEFAULT => -47 + }, + {#State 90 + ACTIONS => { + "union" => 88, + "enum" => 97, + "bitmap" => 98, + "[" => 17, + "struct" => 94 } }, + {#State 91 + DEFAULT => -45 + }, {#State 92 + DEFAULT => -44 + }, + {#State 93 ACTIONS => { - ";" => 86 + 'IDENTIFIER' => 22 }, - DEFAULT => -125, GOTOS => { - 'optional_semicolon' => 130 + 'identifier' => 125 } }, - {#State 93 - DEFAULT => -19 - }, {#State 94 - DEFAULT => -40 + ACTIONS => { + 'IDENTIFIER' => 123 + }, + DEFAULT => -122, + GOTOS => { + 'optional_identifier' => 126 + } }, {#State 95 - DEFAULT => -47 + DEFAULT => -41 }, {#State 96 - DEFAULT => -45 + DEFAULT => -46 }, {#State 97 - DEFAULT => -44 + ACTIONS => { + 'IDENTIFIER' => 123 + }, + DEFAULT => -122, + GOTOS => { + 'optional_identifier' => 127 + } }, {#State 98 ACTIONS => { - 'IDENTIFIER' => 22 + 'IDENTIFIER' => 123 }, + DEFAULT => -122, GOTOS => { - 'identifier' => 131 + 'optional_identifier' => 128 } }, {#State 99 - DEFAULT => -46 - }, - {#State 100 - DEFAULT => -41 - }, - {#State 101 DEFAULT => -42 }, - {#State 102 + {#State 100 ACTIONS => { 'IDENTIFIER' => 22 }, GOTOS => { - 'identifier' => 132 + 'identifier' => 129 } }, - {#State 103 + {#State 101 ACTIONS => { - "union" => 133, - "enum" => 138, - "bitmap" => 139, + "union" => 130, + "enum" => 135, + "bitmap" => 136, "[" => 17 }, GOTOS => { - 'decl_enum' => 134, - 'decl_bitmap' => 135, - 'decl_type' => 137, - 'decl_union' => 136 + 'decl_enum' => 131, + 'decl_bitmap' => 132, + 'decl_type' => 134, + 'decl_union' => 133 } }, - {#State 104 + {#State 102 DEFAULT => -80, GOTOS => { - 'pointers' => 140 + 'pointers' => 137 } }, + {#State 103 + ACTIONS => { + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 + }, + DEFAULT => -114 + }, + {#State 104 + ACTIONS => { + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 + }, + DEFAULT => -105 + }, {#State 105 ACTIONS => { - "{" => 142 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -66, - GOTOS => { - 'struct_body' => 141, - 'opt_struct_body' => 143 - } + DEFAULT => -113 }, {#State 106 ACTIONS => { - "{" => 144 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -49, - GOTOS => { - 'opt_enum_body' => 146, - 'enum_body' => 145 - } + DEFAULT => -109 }, {#State 107 ACTIONS => { - "{" => 148 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -57, - GOTOS => { - 'bitmap_body' => 149, - 'opt_bitmap_body' => 147 - } + DEFAULT => -117 }, {#State 108 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 }, - DEFAULT => -114 + DEFAULT => -116 }, {#State 109 ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -105 + DEFAULT => -99 }, {#State 110 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 - }, - DEFAULT => -109 + "}" => 138, + "," => 139 + } }, {#State 111 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 }, - DEFAULT => -117 + DEFAULT => -111 }, {#State 112 ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 }, - DEFAULT => -116 + DEFAULT => -112 }, {#State 113 ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -107 + DEFAULT => -115 }, {#State 114 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 - }, - DEFAULT => -113 + "," => 139, + ")" => 140 + } }, {#State 115 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 }, - DEFAULT => -99 + DEFAULT => -110 }, {#State 116 ACTIONS => { - "}" => 150, - "," => 151 - } + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 + }, + DEFAULT => -107 }, {#State 117 ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 }, - DEFAULT => -111 + DEFAULT => -106 }, {#State 118 ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 }, - DEFAULT => -112 + DEFAULT => -108 }, {#State 119 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -115 + DEFAULT => -98 }, {#State 120 - ACTIONS => { - "," => 151, - ")" => 152 - } + DEFAULT => -14 }, {#State 121 - ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 - }, - DEFAULT => -110 + DEFAULT => -15 }, {#State 122 ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 + 'IDENTIFIER' => 22 }, - DEFAULT => -106 + GOTOS => { + 'identifier' => 141 + } }, {#State 123 - ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 - }, - DEFAULT => -108 + DEFAULT => -121 }, {#State 124 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + "{" => 143 }, - DEFAULT => -98 + DEFAULT => -76, + GOTOS => { + 'union_body' => 144, + 'opt_union_body' => 142 + } }, {#State 125 - DEFAULT => -14 + DEFAULT => -43 }, {#State 126 ACTIONS => { - 'IDENTIFIER' => 22 + "{" => 146 }, + DEFAULT => -66, GOTOS => { - 'identifier' => 153 + 'struct_body' => 145, + 'opt_struct_body' => 147 } }, {#State 127 - DEFAULT => -78 + ACTIONS => { + "{" => 148 + }, + DEFAULT => -49, + GOTOS => { + 'opt_enum_body' => 150, + 'enum_body' => 149 + } }, {#State 128 - DEFAULT => -73, + ACTIONS => { + "{" => 152 + }, + DEFAULT => -57, GOTOS => { - 'union_elements' => 154 + 'bitmap_body' => 153, + 'opt_bitmap_body' => 151 } }, {#State 129 - DEFAULT => -77 - }, - {#State 130 - DEFAULT => -15 - }, - {#State 131 - DEFAULT => -43 - }, - {#State 132 ACTIONS => { - "(" => 155 + "(" => 154 } }, - {#State 133 + {#State 130 DEFAULT => -34 }, - {#State 134 + {#State 131 DEFAULT => -29 }, - {#State 135 + {#State 132 DEFAULT => -30 }, - {#State 136 + {#State 133 DEFAULT => -31 }, - {#State 137 + {#State 134 ACTIONS => { 'IDENTIFIER' => 22 }, GOTOS => { - 'identifier' => 156 + 'identifier' => 155 } }, - {#State 138 + {#State 135 DEFAULT => -32 }, - {#State 139 + {#State 136 DEFAULT => -33 }, - {#State 140 + {#State 137 ACTIONS => { 'IDENTIFIER' => 22, - "*" => 158 - }, - GOTOS => { - 'identifier' => 157 - } - }, - {#State 141 - DEFAULT => -67 - }, - {#State 142 - DEFAULT => -82, - GOTOS => { - 'element_list1' => 159 - } - }, - {#State 143 - DEFAULT => -68 - }, - {#State 144 - ACTIONS => { - 'IDENTIFIER' => 22 + "*" => 157 }, GOTOS => { - 'identifier' => 160, - 'enum_element' => 161, - 'enum_elements' => 162 - } - }, - {#State 145 - DEFAULT => -50 - }, - {#State 146 - DEFAULT => -51 - }, - {#State 147 - DEFAULT => -59 - }, - {#State 148 - ACTIONS => { - 'IDENTIFIER' => 22 - }, - DEFAULT => -62, - GOTOS => { - 'identifier' => 165, - 'bitmap_element' => 164, - 'bitmap_elements' => 163, - 'opt_bitmap_elements' => 166 + 'identifier' => 156 } }, - {#State 149 - DEFAULT => -58 - }, - {#State 150 + {#State 138 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -1223,12 +1157,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 167, + 'anytext' => 158, 'text' => 46, 'constant' => 43 } }, - {#State 151 + {#State 139 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -1237,12 +1171,12 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 168, + 'anytext' => 159, 'text' => 46, 'constant' => 43 } }, - {#State 152 + {#State 140 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -1251,238 +1185,276 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 169, + 'anytext' => 160, 'text' => 46, 'constant' => 43 } }, - {#State 153 + {#State 141 ACTIONS => { - "[" => 170 + "[" => 161 }, DEFAULT => -88, GOTOS => { - 'array_len' => 171 + 'array_len' => 162 } }, - {#State 154 + {#State 142 + DEFAULT => -78 + }, + {#State 143 + DEFAULT => -73, + GOTOS => { + 'union_elements' => 163 + } + }, + {#State 144 + DEFAULT => -77 + }, + {#State 145 + DEFAULT => -67 + }, + {#State 146 + DEFAULT => -82, + GOTOS => { + 'element_list1' => 164 + } + }, + {#State 147 + DEFAULT => -68 + }, + {#State 148 ACTIONS => { - "}" => 172 + 'IDENTIFIER' => 22 }, - DEFAULT => -91, GOTOS => { - 'optional_base_element' => 174, - 'property_list' => 173 + 'identifier' => 165, + 'enum_element' => 166, + 'enum_elements' => 167 } }, - {#State 155 + {#State 149 + DEFAULT => -50 + }, + {#State 150 + DEFAULT => -51 + }, + {#State 151 + DEFAULT => -59 + }, + {#State 152 + ACTIONS => { + 'IDENTIFIER' => 22 + }, + DEFAULT => -62, + GOTOS => { + 'identifier' => 170, + 'bitmap_element' => 169, + 'bitmap_elements' => 168, + 'opt_bitmap_elements' => 171 + } + }, + {#State 153 + DEFAULT => -58 + }, + {#State 154 ACTIONS => { "," => -84, - "void" => 178, + "void" => 175, ")" => -84 }, DEFAULT => -91, GOTOS => { - 'base_element' => 175, - 'element_list2' => 177, - 'property_list' => 176 + 'base_element' => 172, + 'element_list2' => 174, + 'property_list' => 173 } }, - {#State 156 + {#State 155 ACTIONS => { - ";" => 179 + ";" => 176 } }, - {#State 157 + {#State 156 ACTIONS => { - "[" => 170, - "=" => 181 + "[" => 161, + "=" => 178 }, GOTOS => { - 'array_len' => 180 + 'array_len' => 177 } }, - {#State 158 + {#State 157 DEFAULT => -81 }, + {#State 158 + ACTIONS => { + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 + }, + DEFAULT => -119 + }, {#State 159 ACTIONS => { - "}" => 182 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -91, - GOTOS => { - 'base_element' => 183, - 'property_list' => 176 - } + DEFAULT => -100 }, {#State 160 ACTIONS => { - "=" => 184 + ":" => 64, + "<" => 67, + "~" => 68, + "?" => 66, + "{" => 70, + "=" => 73 }, - DEFAULT => -54 + DEFAULT => -118 }, {#State 161 - DEFAULT => -52 + ACTIONS => { + 'CONSTANT' => 44, + 'TEXT' => 13, + "]" => 179, + 'IDENTIFIER' => 22 + }, + DEFAULT => -101, + GOTOS => { + 'identifier' => 45, + 'anytext' => 180, + 'text' => 46, + 'constant' => 43 + } }, {#State 162 ACTIONS => { - "}" => 185, - "," => 186 + ";" => 181 } }, {#State 163 ACTIONS => { - "," => 187 + "}" => 182 }, - DEFAULT => -63 + DEFAULT => -91, + GOTOS => { + 'optional_base_element' => 184, + 'property_list' => 183 + } }, {#State 164 - DEFAULT => -60 + ACTIONS => { + "}" => 185 + }, + DEFAULT => -91, + GOTOS => { + 'base_element' => 186, + 'property_list' => 173 + } }, {#State 165 ACTIONS => { - "=" => 188 - } + "=" => 187 + }, + DEFAULT => -54 }, {#State 166 - ACTIONS => { - "}" => 189 - } + DEFAULT => -52 }, {#State 167 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 - }, - DEFAULT => -119 + "}" => 188, + "," => 189 + } }, {#State 168 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + "," => 190 }, - DEFAULT => -100 + DEFAULT => -63 }, {#State 169 - ACTIONS => { - ":" => 69, - "<" => 71, - "~" => 72, - "?" => 75, - "{" => 76, - "=" => 79 - }, - DEFAULT => -118 + DEFAULT => -60 }, {#State 170 ACTIONS => { - 'CONSTANT' => 44, - 'TEXT' => 13, - "]" => 190, - 'IDENTIFIER' => 22 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 45, - 'anytext' => 191, - 'text' => 46, - 'constant' => 43 + "=" => 191 } }, {#State 171 ACTIONS => { - ";" => 192 + "}" => 192 } }, {#State 172 - DEFAULT => -75 + DEFAULT => -86 }, {#State 173 ACTIONS => { + 'IDENTIFIER' => 22, + "signed" => 95, + 'void' => 89, + "unsigned" => 99, "[" => 17 }, DEFAULT => -91, GOTOS => { - 'base_or_empty' => 193, - 'base_element' => 194, - 'empty_element' => 195, - 'property_list' => 196 - } - }, - {#State 174 - DEFAULT => -74 - }, - {#State 175 - DEFAULT => -86 - }, - {#State 176 - ACTIONS => { - 'IDENTIFIER' => 22, - "signed" => 100, - "union" => 50, - "enum" => 63, - "bitmap" => 64, - 'void' => 95, - "unsigned" => 101, - "[" => 17, - "struct" => 61 - }, - GOTOS => { - 'existingtype' => 99, - 'bitmap' => 65, - 'usertype' => 96, - 'identifier' => 97, + 'existingtype' => 96, + 'bitmap' => 51, + 'usertype' => 91, + 'property_list' => 90, + 'identifier' => 92, 'struct' => 57, - 'enum' => 59, - 'type' => 197, - 'union' => 68, - 'sign' => 98 + 'enum' => 61, + 'type' => 193, + 'union' => 63, + 'sign' => 93 } }, - {#State 177 + {#State 174 ACTIONS => { - "," => 198, - ")" => 199 + "," => 194, + ")" => 195 } }, - {#State 178 + {#State 175 DEFAULT => -85 }, - {#State 179 + {#State 176 DEFAULT => -28 }, - {#State 180 + {#State 177 ACTIONS => { - "=" => 200 + "=" => 196 } }, - {#State 181 + {#State 178 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -1491,20 +1463,70 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 201, + 'anytext' => 197, 'text' => 46, 'constant' => 43 } }, + {#State 179 + ACTIONS => { + "[" => 161 + }, + DEFAULT => -88, + GOTOS => { + 'array_len' => 198 + } + }, + {#State 180 + ACTIONS => { + "-" => 65, + ":" => 64, + "?" => 66, + "<" => 67, + "+" => 69, + "~" => 68, + "&" => 71, + "{" => 70, + "/" => 72, + "=" => 73, + "|" => 75, + "(" => 74, + "*" => 76, + "." => 77, + "]" => 199, + ">" => 78 + } + }, + {#State 181 + DEFAULT => -35 + }, {#State 182 - DEFAULT => -65 + DEFAULT => -75 }, {#State 183 ACTIONS => { - ";" => 202 + "[" => 17 + }, + DEFAULT => -91, + GOTOS => { + 'base_or_empty' => 200, + 'base_element' => 201, + 'empty_element' => 202, + 'property_list' => 203 } }, {#State 184 + DEFAULT => -74 + }, + {#State 185 + DEFAULT => -65 + }, + {#State 186 + ACTIONS => { + ";" => 204 + } + }, + {#State 187 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -1513,33 +1535,33 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 203, + 'anytext' => 205, 'text' => 46, 'constant' => 43 } }, - {#State 185 + {#State 188 DEFAULT => -48 }, - {#State 186 + {#State 189 ACTIONS => { 'IDENTIFIER' => 22 }, GOTOS => { - 'identifier' => 160, - 'enum_element' => 204 + 'identifier' => 165, + 'enum_element' => 206 } }, - {#State 187 + {#State 190 ACTIONS => { 'IDENTIFIER' => 22 }, GOTOS => { - 'identifier' => 165, - 'bitmap_element' => 205 + 'identifier' => 170, + 'bitmap_element' => 207 } }, - {#State 188 + {#State 191 ACTIONS => { 'CONSTANT' => 44, 'TEXT' => 13, @@ -1548,245 +1570,211 @@ sub new { DEFAULT => -101, GOTOS => { 'identifier' => 45, - 'anytext' => 206, + 'anytext' => 208, 'text' => 46, 'constant' => 43 } }, - {#State 189 + {#State 192 DEFAULT => -56 }, - {#State 190 - ACTIONS => { - "[" => 170 - }, - DEFAULT => -88, + {#State 193 + DEFAULT => -80, GOTOS => { - 'array_len' => 207 - } - }, - {#State 191 - ACTIONS => { - "-" => 70, - ":" => 69, - "?" => 75, - "<" => 71, - "+" => 73, - "~" => 72, - "&" => 77, - "{" => 76, - "/" => 78, - "=" => 79, - "|" => 81, - "(" => 80, - "*" => 74, - "." => 82, - "]" => 208, - ">" => 83 + 'pointers' => 209 } }, - {#State 192 - DEFAULT => -35 - }, - {#State 193 - DEFAULT => -72 - }, {#State 194 - ACTIONS => { - ";" => 209 + DEFAULT => -91, + GOTOS => { + 'base_element' => 210, + 'property_list' => 173 } }, {#State 195 - DEFAULT => -71 + ACTIONS => { + ";" => 211 + } }, {#State 196 ACTIONS => { - 'IDENTIFIER' => 22, - "signed" => 100, - "union" => 50, - ";" => 210, - "enum" => 63, - "bitmap" => 64, - 'void' => 95, - "unsigned" => 101, - "[" => 17, - "struct" => 61 + 'CONSTANT' => 44, + 'TEXT' => 13, + 'IDENTIFIER' => 22 }, + DEFAULT => -101, GOTOS => { - 'existingtype' => 99, - 'bitmap' => 65, - 'usertype' => 96, - 'identifier' => 97, - 'struct' => 57, - 'enum' => 59, - 'type' => 197, - 'union' => 68, - 'sign' => 98 + 'identifier' => 45, + 'anytext' => 212, + 'text' => 46, + 'constant' => 43 } }, {#State 197 - DEFAULT => -80, - GOTOS => { - 'pointers' => 211 + ACTIONS => { + "-" => 65, + ":" => 64, + "?" => 66, + "<" => 67, + ";" => 213, + "+" => 69, + "~" => 68, + "&" => 71, + "{" => 70, + "/" => 72, + "=" => 73, + "|" => 75, + "(" => 74, + "*" => 76, + "." => 77, + ">" => 78 } }, {#State 198 - DEFAULT => -91, - GOTOS => { - 'base_element' => 212, - 'property_list' => 176 - } + DEFAULT => -89 }, {#State 199 ACTIONS => { - ";" => 213 - } - }, - {#State 200 - ACTIONS => { - 'CONSTANT' => 44, - 'TEXT' => 13, - 'IDENTIFIER' => 22 + "[" => 161 }, - DEFAULT => -101, + DEFAULT => -88, GOTOS => { - 'identifier' => 45, - 'anytext' => 214, - 'text' => 46, - 'constant' => 43 + 'array_len' => 214 } }, + {#State 200 + DEFAULT => -72 + }, {#State 201 ACTIONS => { - "-" => 70, - ":" => 69, - "?" => 75, - "<" => 71, - ";" => 215, - "+" => 73, - "~" => 72, - "&" => 77, - "{" => 76, - "/" => 78, - "=" => 79, - "|" => 81, - "(" => 80, - "*" => 74, - "." => 82, - ">" => 83 + ";" => 215 } }, {#State 202 - DEFAULT => -83 + DEFAULT => -71 }, {#State 203 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + 'IDENTIFIER' => 22, + "signed" => 95, + ";" => 216, + 'void' => 89, + "unsigned" => 99, + "[" => 17 }, - DEFAULT => -55 + DEFAULT => -91, + GOTOS => { + 'existingtype' => 96, + 'bitmap' => 51, + 'usertype' => 91, + 'property_list' => 90, + 'identifier' => 92, + 'struct' => 57, + 'enum' => 61, + 'type' => 193, + 'union' => 63, + 'sign' => 93 + } }, {#State 204 - DEFAULT => -53 + DEFAULT => -83 }, {#State 205 - DEFAULT => -61 - }, - {#State 206 ACTIONS => { - "-" => 70, - ":" => 69, - "<" => 71, - "+" => 73, - "~" => 72, - "*" => 74, - "?" => 75, - "{" => 76, - "&" => 77, - "/" => 78, - "=" => 79, - "(" => 80, - "|" => 81, - "." => 82, - ">" => 83 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -64 + DEFAULT => -55 + }, + {#State 206 + DEFAULT => -53 }, {#State 207 - DEFAULT => -89 + DEFAULT => -61 }, {#State 208 ACTIONS => { - "[" => 170 + "-" => 65, + ":" => 64, + "<" => 67, + "+" => 69, + "~" => 68, + "*" => 76, + "?" => 66, + "{" => 70, + "&" => 71, + "/" => 72, + "=" => 73, + "(" => 74, + "|" => 75, + "." => 77, + ">" => 78 }, - DEFAULT => -88, - GOTOS => { - 'array_len' => 216 - } + DEFAULT => -64 }, {#State 209 - DEFAULT => -70 - }, - {#State 210 - DEFAULT => -69 - }, - {#State 211 ACTIONS => { 'IDENTIFIER' => 22, - "*" => 158 + "*" => 157 }, GOTOS => { 'identifier' => 217 } }, - {#State 212 + {#State 210 DEFAULT => -87 }, - {#State 213 + {#State 211 DEFAULT => -27 }, - {#State 214 + {#State 212 ACTIONS => { - "-" => 70, - ":" => 69, - "?" => 75, - "<" => 71, + "-" => 65, + ":" => 64, + "?" => 66, + "<" => 67, ";" => 218, - "+" => 73, - "~" => 72, - "&" => 77, - "{" => 76, - "/" => 78, - "=" => 79, - "|" => 81, - "(" => 80, - "*" => 74, - "." => 82, - ">" => 83 + "+" => 69, + "~" => 68, + "&" => 71, + "{" => 70, + "/" => 72, + "=" => 73, + "|" => 75, + "(" => 74, + "*" => 76, + "." => 77, + ">" => 78 } }, - {#State 215 + {#State 213 DEFAULT => -25 }, - {#State 216 + {#State 214 DEFAULT => -90 }, + {#State 215 + DEFAULT => -70 + }, + {#State 216 + DEFAULT => -69 + }, {#State 217 ACTIONS => { - "[" => 170 + "[" => 161 }, DEFAULT => -88, GOTOS => { @@ -1811,37 +1799,37 @@ sub new { [#Rule 2 'idl', 2, sub -#line 19 "pidl/idl.yp" +#line 19 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 3 'idl', 2, sub -#line 20 "pidl/idl.yp" +#line 20 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 4 'idl', 2, sub -#line 21 "pidl/idl.yp" +#line 21 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 5 'idl', 2, sub -#line 22 "pidl/idl.yp" +#line 22 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 6 'idl', 2, sub -#line 23 "pidl/idl.yp" +#line 23 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 7 'import', 3, sub -#line 26 "pidl/idl.yp" +#line 26 "idl.yp" {{ "TYPE" => "IMPORT", "PATHS" => $_[2], @@ -1852,7 +1840,7 @@ sub [#Rule 8 'include', 3, sub -#line 33 "pidl/idl.yp" +#line 33 "idl.yp" {{ "TYPE" => "INCLUDE", "PATHS" => $_[2], @@ -1863,7 +1851,7 @@ sub [#Rule 9 'importlib', 3, sub -#line 40 "pidl/idl.yp" +#line 40 "idl.yp" {{ "TYPE" => "IMPORTLIB", "PATHS" => $_[2], @@ -1874,19 +1862,19 @@ sub [#Rule 10 'commalist', 1, sub -#line 49 "pidl/idl.yp" +#line 49 "idl.yp" { [ $_[1] ] } ], [#Rule 11 'commalist', 3, sub -#line 50 "pidl/idl.yp" +#line 50 "idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], [#Rule 12 'coclass', 7, sub -#line 54 "pidl/idl.yp" +#line 54 "idl.yp" {{ "TYPE" => "COCLASS", "PROPERTIES" => $_[1], @@ -1902,13 +1890,13 @@ sub [#Rule 14 'interface_names', 4, sub -#line 66 "pidl/idl.yp" +#line 66 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 15 'interface', 8, sub -#line 70 "pidl/idl.yp" +#line 70 "idl.yp" {{ "TYPE" => "INTERFACE", "PROPERTIES" => $_[1], @@ -1925,19 +1913,19 @@ sub [#Rule 17 'base_interface', 2, sub -#line 83 "pidl/idl.yp" +#line 83 "idl.yp" { $_[2] } ], [#Rule 18 'definitions', 1, sub -#line 87 "pidl/idl.yp" +#line 87 "idl.yp" { [ $_[1] ] } ], [#Rule 19 'definitions', 2, sub -#line 88 "pidl/idl.yp" +#line 88 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 20 @@ -1958,7 +1946,7 @@ sub [#Rule 25 'const', 7, sub -#line 96 "pidl/idl.yp" +#line 96 "idl.yp" {{ "TYPE" => "CONST", "DTYPE" => $_[2], @@ -1972,7 +1960,7 @@ sub [#Rule 26 'const', 8, sub -#line 106 "pidl/idl.yp" +#line 106 "idl.yp" {{ "TYPE" => "CONST", "DTYPE" => $_[2], @@ -1987,7 +1975,7 @@ sub [#Rule 27 'function', 7, sub -#line 120 "pidl/idl.yp" +#line 120 "idl.yp" {{ "TYPE" => "FUNCTION", "NAME" => $_[3], @@ -2001,7 +1989,7 @@ sub [#Rule 28 'declare', 5, sub -#line 132 "pidl/idl.yp" +#line 132 "idl.yp" {{ "TYPE" => "DECLARE", "PROPERTIES" => $_[2], @@ -2023,7 +2011,7 @@ sub [#Rule 32 'decl_enum', 1, sub -#line 146 "pidl/idl.yp" +#line 146 "idl.yp" {{ "TYPE" => "ENUM" }} @@ -2031,7 +2019,7 @@ sub [#Rule 33 'decl_bitmap', 1, sub -#line 152 "pidl/idl.yp" +#line 152 "idl.yp" {{ "TYPE" => "BITMAP" }} @@ -2039,7 +2027,7 @@ sub [#Rule 34 'decl_union', 1, sub -#line 158 "pidl/idl.yp" +#line 158 "idl.yp" {{ "TYPE" => "UNION" }} @@ -2047,10 +2035,10 @@ sub [#Rule 35 'typedef', 6, sub -#line 164 "pidl/idl.yp" +#line 164 "idl.yp" {{ "TYPE" => "TYPEDEF", - "PROPERTIES" => $_[2], + "PROPERTIES" => $_[1], "NAME" => $_[4], "DATA" => $_[3], "ARRAY_LEN" => $_[5], @@ -2073,7 +2061,7 @@ sub [#Rule 40 'typedecl', 2, sub -#line 177 "pidl/idl.yp" +#line 177 "idl.yp" { $_[1] } ], [#Rule 41 @@ -2085,7 +2073,7 @@ sub [#Rule 43 'existingtype', 2, sub -#line 182 "pidl/idl.yp" +#line 182 "idl.yp" { ($_[1]?$_[1]:"signed") ." $_[2]" } ], [#Rule 44 @@ -2100,13 +2088,13 @@ sub [#Rule 47 'type', 1, sub -#line 186 "pidl/idl.yp" +#line 186 "idl.yp" { "void" } ], [#Rule 48 'enum_body', 3, sub -#line 188 "pidl/idl.yp" +#line 188 "idl.yp" { $_[2] } ], [#Rule 49 @@ -2116,25 +2104,26 @@ sub 'opt_enum_body', 1, undef ], [#Rule 51 - 'enum', 3, + 'enum', 4, sub -#line 191 "pidl/idl.yp" +#line 191 "idl.yp" {{ "TYPE" => "ENUM", - "NAME" => $_[2], - "ELEMENTS" => $_[3] + "PROPERTIES" => $_[1], + "NAME" => $_[3], + "ELEMENTS" => $_[4] }} ], [#Rule 52 'enum_elements', 1, sub -#line 199 "pidl/idl.yp" +#line 200 "idl.yp" { [ $_[1] ] } ], [#Rule 53 'enum_elements', 3, sub -#line 200 "pidl/idl.yp" +#line 201 "idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], [#Rule 54 @@ -2143,13 +2132,13 @@ sub [#Rule 55 'enum_element', 3, sub -#line 204 "pidl/idl.yp" +#line 205 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 56 'bitmap_body', 3, sub -#line 207 "pidl/idl.yp" +#line 208 "idl.yp" { $_[2] } ], [#Rule 57 @@ -2159,25 +2148,26 @@ sub 'opt_bitmap_body', 1, undef ], [#Rule 59 - 'bitmap', 3, + 'bitmap', 4, sub -#line 210 "pidl/idl.yp" +#line 211 "idl.yp" {{ "TYPE" => "BITMAP", - "NAME" => $_[2], - "ELEMENTS" => $_[3] + "PROPERTIES" => $_[1], + "NAME" => $_[3], + "ELEMENTS" => $_[4] }} ], [#Rule 60 'bitmap_elements', 1, sub -#line 218 "pidl/idl.yp" +#line 220 "idl.yp" { [ $_[1] ] } ], [#Rule 61 'bitmap_elements', 3, sub -#line 219 "pidl/idl.yp" +#line 221 "idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], [#Rule 62 @@ -2189,13 +2179,13 @@ sub [#Rule 64 'bitmap_element', 3, sub -#line 224 "pidl/idl.yp" +#line 226 "idl.yp" { "$_[1] ( $_[3] )" } ], [#Rule 65 'struct_body', 3, sub -#line 227 "pidl/idl.yp" +#line 229 "idl.yp" { $_[2] } ], [#Rule 66 @@ -2205,19 +2195,20 @@ sub 'opt_struct_body', 1, undef ], [#Rule 68 - 'struct', 3, + 'struct', 4, sub -#line 231 "pidl/idl.yp" +#line 233 "idl.yp" {{ "TYPE" => "STRUCT", - "NAME" => $_[2], - "ELEMENTS" => $_[3] + "PROPERTIES" => $_[1], + "NAME" => $_[3], + "ELEMENTS" => $_[4] }} ], [#Rule 69 'empty_element', 2, sub -#line 239 "pidl/idl.yp" +#line 242 "idl.yp" {{ "NAME" => "", "TYPE" => "EMPTY", @@ -2237,7 +2228,7 @@ sub [#Rule 72 'optional_base_element', 2, sub -#line 253 "pidl/idl.yp" +#line 256 "idl.yp" { $_[2]->{PROPERTIES} = FlattenHash([$_[1],$_[2]->{PROPERTIES}]); $_[2] } ], [#Rule 73 @@ -2246,13 +2237,13 @@ sub [#Rule 74 'union_elements', 2, sub -#line 258 "pidl/idl.yp" +#line 261 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 75 'union_body', 3, sub -#line 261 "pidl/idl.yp" +#line 264 "idl.yp" { $_[2] } ], [#Rule 76 @@ -2262,19 +2253,20 @@ sub 'opt_union_body', 1, undef ], [#Rule 78 - 'union', 3, + 'union', 4, sub -#line 265 "pidl/idl.yp" +#line 268 "idl.yp" {{ "TYPE" => "UNION", - "NAME" => $_[2], - "ELEMENTS" => $_[3] + "PROPERTIES" => $_[1], + "NAME" => $_[3], + "ELEMENTS" => $_[4] }} ], [#Rule 79 'base_element', 5, sub -#line 273 "pidl/idl.yp" +#line 277 "idl.yp" {{ "NAME" => $_[4], "TYPE" => $_[2], @@ -2288,13 +2280,13 @@ sub [#Rule 80 'pointers', 0, sub -#line 287 "pidl/idl.yp" +#line 291 "idl.yp" { 0 } ], [#Rule 81 'pointers', 2, sub -#line 288 "pidl/idl.yp" +#line 292 "idl.yp" { $_[1]+1 } ], [#Rule 82 @@ -2303,7 +2295,7 @@ sub [#Rule 83 'element_list1', 3, sub -#line 293 "pidl/idl.yp" +#line 297 "idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 84 @@ -2315,13 +2307,13 @@ sub [#Rule 86 'element_list2', 1, sub -#line 299 "pidl/idl.yp" +#line 303 "idl.yp" { [ $_[1] ] } ], [#Rule 87 'element_list2', 3, sub -#line 300 "pidl/idl.yp" +#line 304 "idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], [#Rule 88 @@ -2330,13 +2322,13 @@ sub [#Rule 89 'array_len', 3, sub -#line 305 "pidl/idl.yp" +#line 309 "idl.yp" { push(@{$_[3]}, "*"); $_[3] } ], [#Rule 90 'array_len', 4, sub -#line 306 "pidl/idl.yp" +#line 310 "idl.yp" { push(@{$_[4]}, "$_[2]"); $_[4] } ], [#Rule 91 @@ -2345,31 +2337,31 @@ sub [#Rule 92 'property_list', 4, sub -#line 312 "pidl/idl.yp" +#line 316 "idl.yp" { FlattenHash([$_[1],$_[3]]); } ], [#Rule 93 'properties', 1, sub -#line 315 "pidl/idl.yp" +#line 319 "idl.yp" { $_[1] } ], [#Rule 94 'properties', 3, sub -#line 316 "pidl/idl.yp" +#line 320 "idl.yp" { FlattenHash([$_[1], $_[3]]); } ], [#Rule 95 'property', 1, sub -#line 319 "pidl/idl.yp" +#line 323 "idl.yp" {{ "$_[1]" => "1" }} ], [#Rule 96 'property', 4, sub -#line 320 "pidl/idl.yp" +#line 324 "idl.yp" {{ "$_[1]" => "$_[3]" }} ], [#Rule 97 @@ -2378,7 +2370,7 @@ sub [#Rule 98 'listtext', 3, sub -#line 325 "pidl/idl.yp" +#line 329 "idl.yp" { "$_[1] $_[3]" } ], [#Rule 99 @@ -2387,13 +2379,13 @@ sub [#Rule 100 'commalisttext', 3, sub -#line 330 "pidl/idl.yp" +#line 334 "idl.yp" { "$_[1],$_[3]" } ], [#Rule 101 'anytext', 0, sub -#line 334 "pidl/idl.yp" +#line 338 "idl.yp" { "" } ], [#Rule 102 @@ -2408,91 +2400,91 @@ sub [#Rule 105 'anytext', 3, sub -#line 336 "pidl/idl.yp" +#line 340 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 106 'anytext', 3, sub -#line 337 "pidl/idl.yp" +#line 341 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 107 'anytext', 3, sub -#line 338 "pidl/idl.yp" +#line 342 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 108 'anytext', 3, sub -#line 339 "pidl/idl.yp" +#line 343 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 109 'anytext', 3, sub -#line 340 "pidl/idl.yp" +#line 344 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 110 'anytext', 3, sub -#line 341 "pidl/idl.yp" +#line 345 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 111 'anytext', 3, sub -#line 342 "pidl/idl.yp" +#line 346 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 112 'anytext', 3, sub -#line 343 "pidl/idl.yp" +#line 347 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 113 'anytext', 3, sub -#line 344 "pidl/idl.yp" +#line 348 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 114 'anytext', 3, sub -#line 345 "pidl/idl.yp" +#line 349 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 115 'anytext', 3, sub -#line 346 "pidl/idl.yp" +#line 350 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 116 'anytext', 3, sub -#line 347 "pidl/idl.yp" +#line 351 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 117 'anytext', 3, sub -#line 348 "pidl/idl.yp" +#line 352 "idl.yp" { "$_[1]$_[2]$_[3]" } ], [#Rule 118 'anytext', 5, sub -#line 349 "pidl/idl.yp" +#line 353 "idl.yp" { "$_[1]$_[2]$_[3]$_[4]$_[5]" } ], [#Rule 119 'anytext', 5, sub -#line 350 "pidl/idl.yp" +#line 354 "idl.yp" { "$_[1]$_[2]$_[3]$_[4]$_[5]" } ], [#Rule 120 @@ -2510,7 +2502,7 @@ sub [#Rule 124 'text', 1, sub -#line 364 "pidl/idl.yp" +#line 368 "idl.yp" { "\"$_[1]\"" } ], [#Rule 125 @@ -2524,7 +2516,7 @@ sub bless($self,$class); } -#line 375 "pidl/idl.yp" +#line 379 "idl.yp" use Parse::Pidl qw(error); diff --git a/tools/pidl/lib/Parse/Pidl/NDR.pm b/tools/pidl/lib/Parse/Pidl/NDR.pm index 2ba8461e4a..a921e5cbe5 100644 --- a/tools/pidl/lib/Parse/Pidl/NDR.pm +++ b/tools/pidl/lib/Parse/Pidl/NDR.pm @@ -257,8 +257,6 @@ sub GetElementLevelTable($) push (@$order, { TYPE => "DATA", - CONVERT_TO => has_property($e, ""), - CONVERT_FROM => has_property($e, ""), DATA_TYPE => $e->{TYPE}, IS_DEFERRED => $is_deferred, CONTAINS_DEFERRED => can_contain_deferred($e), @@ -360,18 +358,22 @@ sub align_type($) die("Unknown data type type $dt->{TYPE}"); } -sub ParseElement($) +sub ParseElement($$) { - my $e = shift; + my ($e, $pointer_default) = @_; $e->{TYPE} = expandAlias($e->{TYPE}); + if (ref($e->{TYPE}) eq "HASH") { + $e->{TYPE} = ParseType($e->{TYPE}, $pointer_default); + } + return { NAME => $e->{NAME}, TYPE => $e->{TYPE}, PROPERTIES => $e->{PROPERTIES}, LEVELS => GetElementLevelTable($e), - REPRESENTATION_TYPE => $e->{PROPERTIES}->{represent_as}, + REPRESENTATION_TYPE => ($e->{PROPERTIES}->{represent_as} or $e->{TYPE}), ALIGN => align_type($e->{TYPE}), ORIGINAL => $e }; @@ -379,16 +381,16 @@ sub ParseElement($) sub ParseStruct($$) { - my ($ndr,$struct) = @_; + my ($struct, $pointer_default) = @_; my @elements = (); my $surrounding = undef; foreach my $x (@{$struct->{ELEMENTS}}) { - my $e = ParseElement($x); + my $e = ParseElement($x, $pointer_default); 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"; + fatal($x, "conformant member not at end of struct"); } push @elements, $e; } @@ -403,19 +405,26 @@ sub ParseStruct($$) && property_matches($e, "flag", ".*LIBNDR_FLAG_STR_CONFORMANT.*")) { $surrounding = $struct->{ELEMENTS}[-1]; } + + my $align = undef; + if ($struct->{NAME}) { + $align = align_type($struct->{NAME}); + } return { TYPE => "STRUCT", + NAME => $struct->{NAME}, SURROUNDING_ELEMENT => $surrounding, ELEMENTS => \@elements, PROPERTIES => $struct->{PROPERTIES}, - ORIGINAL => $struct + ORIGINAL => $struct, + ALIGN => $align }; } sub ParseUnion($$) { - my ($ndr,$e) = @_; + my ($e, $pointer_default) = @_; my @elements = (); my $switch_type = has_property($e, "switch_type"); unless (defined($switch_type)) { $switch_type = "uint32"; } @@ -429,7 +438,7 @@ sub ParseUnion($$) if ($x->{TYPE} eq "EMPTY") { $t = { TYPE => "EMPTY" }; } else { - $t = ParseElement($x); + $t = ParseElement($x, $pointer_default); } if (has_property($x, "default")) { $t->{CASE} = "default"; @@ -444,6 +453,7 @@ sub ParseUnion($$) return { TYPE => "UNION", + NAME => $e->{NAME}, SWITCH_TYPE => $switch_type, ELEMENTS => \@elements, PROPERTIES => $e->{PROPERTIES}, @@ -454,10 +464,11 @@ sub ParseUnion($$) sub ParseEnum($$) { - my ($ndr,$e) = @_; + my ($e, $pointer_default) = @_; return { TYPE => "ENUM", + NAME => $e->{NAME}, BASE_TYPE => Parse::Pidl::Typelist::enum_type_fn($e), ELEMENTS => $e->{ELEMENTS}, PROPERTIES => $e->{PROPERTIES}, @@ -467,10 +478,11 @@ sub ParseEnum($$) sub ParseBitmap($$) { - my ($ndr,$e) = @_; + my ($e, $pointer_default) = @_; return { TYPE => "BITMAP", + NAME => $e->{NAME}, BASE_TYPE => Parse::Pidl::Typelist::bitmap_type_fn($e), ELEMENTS => $e->{ELEMENTS}, PROPERTIES => $e->{PROPERTIES}, @@ -480,10 +492,10 @@ sub ParseBitmap($$) sub ParseType($$) { - my ($ndr, $d) = @_; + my ($d, $pointer_default) = @_; if ($d->{TYPE} eq "STRUCT" or $d->{TYPE} eq "UNION") { - CheckPointerTypes($d, $ndr->{PROPERTIES}->{pointer_default}); + CheckPointerTypes($d, $pointer_default); } my $data = { @@ -492,20 +504,20 @@ sub ParseType($$) ENUM => \&ParseEnum, BITMAP => \&ParseBitmap, TYPEDEF => \&ParseTypedef, - }->{$d->{TYPE}}->($ndr, $d); + }->{$d->{TYPE}}->($d, $pointer_default); return $data; } sub ParseTypedef($$) { - my ($ndr,$d) = @_; + my ($d, $pointer_default) = @_; - if (defined($d->{PROPERTIES}) && !defined($d->{DATA}->{PROPERTIES})) { - $d->{DATA}->{PROPERTIES} = $d->{PROPERTIES}; + if (defined($d->{DATA}->{PROPERTIES}) && !defined($d->{PROPERTIES})) { + $d->{PROPERTIES} = $d->{DATA}->{PROPERTIES}; } - my $data = ParseType($ndr, $d->{DATA}); + my $data = ParseType($d->{DATA}, $pointer_default); $data->{ALIGN} = align_type($d->{NAME}); return { @@ -539,7 +551,7 @@ sub ParseFunction($$$) } foreach my $x (@{$d->{ELEMENTS}}) { - my $e = ParseElement($x); + my $e = ParseElement($x, $ndr->{PROPERTIES}->{pointer_default}); push (@{$e->{DIRECTION}}, "in") if (has_property($x, "in")); push (@{$e->{DIRECTION}}, "out") if (has_property($x, "out")); @@ -607,7 +619,7 @@ sub ParseInterface($) } elsif ($d->{TYPE} eq "CONST") { push (@consts, ParseConst($idl, $d)); } else { - push (@types, ParseType($idl, $d)); + push (@types, ParseType($d, $idl->{PROPERTIES}->{pointer_default})); } } @@ -865,7 +877,7 @@ sub mapToScalar($) } ##################################################################### -# parse a struct +# validate an element sub ValidElement($) { my $e = shift; @@ -881,8 +893,8 @@ sub ValidElement($) fatal($e, el_name($e) . ": switch_is() used on non-union type $e->{TYPE} which is a $type->{DATA}->{TYPE}"); } - if (!has_property($type, "nodiscriminant") and defined($e2)) { - my $discriminator_type = has_property($type, "switch_type"); + if (not has_property($type->{DATA}, "nodiscriminant") and defined($e2)) { + my $discriminator_type = has_property($type->{DATA}, "switch_type"); $discriminator_type = "uint32" unless defined ($discriminator_type); my $t1 = mapToScalar($discriminator_type); @@ -940,12 +952,30 @@ sub ValidElement($) } ##################################################################### -# parse a struct +# validate an enum +sub ValidEnum($) +{ + my ($enum) = @_; + + ValidProperties($enum, "ENUM"); +} + +##################################################################### +# validate a bitmap +sub ValidBitmap($) +{ + my ($bitmap) = @_; + + ValidProperties($bitmap, "BITMAP"); +} + +##################################################################### +# validate a struct sub ValidStruct($) { my($struct) = shift; - ValidProperties($struct,"STRUCT"); + ValidProperties($struct, "STRUCT"); foreach my $e (@{$struct->{ELEMENTS}}) { $e->{PARENT} = $struct; @@ -994,23 +1024,15 @@ sub ValidTypedef($) my($typedef) = shift; my $data = $typedef->{DATA}; - ValidProperties($typedef,"TYPEDEF"); + ValidProperties($typedef, "TYPEDEF"); $data->{PARENT} = $typedef; - if (ref($data) eq "HASH") { - if ($data->{TYPE} eq "STRUCT") { - ValidStruct($data); - } - - if ($data->{TYPE} eq "UNION") { - ValidUnion($data); - } - } + ValidType($data) if (ref($data) eq "HASH"); } ##################################################################### -# parse a function +# validate a function sub ValidFunction($) { my($fn) = shift; @@ -1027,6 +1049,21 @@ sub ValidFunction($) } ##################################################################### +# validate a type +sub ValidType($) +{ + my ($t) = @_; + + { + TYPEDEF => \&ValidTypedef, + STRUCT => \&ValidStruct, + UNION => \&ValidUnion, + ENUM => \&ValidEnum, + BITMAP => \&ValidBitmap + }->{$t->{TYPE}}->($t); +} + +##################################################################### # parse the interface definitions sub ValidInterface($) { @@ -1059,10 +1096,12 @@ sub ValidInterface($) } foreach my $d (@{$data}) { - ($d->{TYPE} eq "TYPEDEF") && - ValidTypedef($d); - ($d->{TYPE} eq "FUNCTION") && - ValidFunction($d); + ($d->{TYPE} eq "FUNCTION") && ValidFunction($d); + ($d->{TYPE} eq "TYPEDEF" or + $d->{TYPE} eq "STRUCT" or + $d->{TYPE} eq "UNION" or + $d->{TYPE} eq "ENUM" or + $d->{TYPE} eq "BITMAP") && ValidType($d); } } diff --git a/tools/pidl/lib/Parse/Pidl/ODL.pm b/tools/pidl/lib/Parse/Pidl/ODL.pm deleted file mode 100644 index ee8d030a37..0000000000 --- a/tools/pidl/lib/Parse/Pidl/ODL.pm +++ /dev/null @@ -1,102 +0,0 @@ -########################################## -# Converts ODL stuctures to IDL structures -# (C) 2004-2005 Jelmer Vernooij <jelmer@samba.org> - -package Parse::Pidl::ODL; - -use Parse::Pidl::Util qw(has_property); -use Parse::Pidl::Typelist qw(hasType getType); -use strict; - -use vars qw($VERSION); -$VERSION = '0.01'; - -##################################################################### -# find an interface in an array of interfaces -sub get_interface($$) -{ - my($if,$n) = @_; - - foreach(@$if) { - next if ($_->{TYPE} ne "INTERFACE"); - return $_ if($_->{NAME} eq $n); - } - - return 0; -} - -sub FunctionAddObjArgs($) -{ - my $e = shift; - - unshift(@{$e->{ELEMENTS}}, { - 'NAME' => 'ORPCthis', - 'POINTERS' => 0, - 'PROPERTIES' => { 'in' => '1' }, - 'TYPE' => 'ORPCTHIS', - 'FILE' => $e->{FILE}, - 'LINE' => $e->{LINE} - }); - unshift(@{$e->{ELEMENTS}}, { - 'NAME' => 'ORPCthat', - 'POINTERS' => 1, - 'PROPERTIES' => { 'out' => '1', 'ref' => '1' }, - 'TYPE' => 'ORPCTHAT', - 'FILE' => $e->{FILE}, - 'LINE' => $e->{LINE} - }); -} - -sub ReplaceInterfacePointers($) -{ - my $e = shift; - - foreach my $x (@{$e->{ELEMENTS}}) { - next unless (hasType($x->{TYPE})); - next unless getType($x->{TYPE})->{DATA}->{TYPE} eq "INTERFACE"; - - $x->{TYPE} = "MInterfacePointer"; - } -} - -# Add ORPC specific bits to an interface. -sub ODL2IDL($) -{ - my $odl = shift; - my $addedorpc = 0; - - foreach my $x (@$odl) { - next if ($x->{TYPE} ne "INTERFACE"); - # Add [in] ORPCTHIS *this, [out] ORPCTHAT *that - # and replace interfacepointers with MInterfacePointer - # for 'object' interfaces - if (has_property($x, "object")) { - foreach my $e (@{$x->{DATA}}) { - ($e->{TYPE} eq "FUNCTION") && FunctionAddObjArgs($e); - ReplaceInterfacePointers($e); - } - $addedorpc = 1; - } - - if ($x->{BASE}) { - my $base = get_interface($odl, $x->{BASE}); - - foreach my $fn (reverse @{$base->{DATA}}) { - next unless ($fn->{TYPE} eq "FUNCTION"); - unshift (@{$x->{DATA}}, $fn); - push (@{$x->{INHERITED_FUNCTIONS}}, $fn->{NAME}); - } - } - } - - unshift (@$odl, { - TYPE => "IMPORT", - PATHS => [ "\"orpc.idl\"" ], - FILE => undef, - LINE => undef - }) if ($addedorpc); - - return $odl; -} - -1; diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm index ade2711d85..8fa37ca300 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm @@ -6,18 +6,22 @@ package Parse::Pidl::Samba3::ClientNDR; +use Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(GenerateFunctionInEnv ParseFunction $res $res_hdr); + use strict; use Parse::Pidl qw(fatal warning); -use Parse::Pidl::Typelist qw(hasType getType mapType scalar_is_reference); -use Parse::Pidl::Util qw(has_property is_constant); +use Parse::Pidl::Typelist qw(hasType getType mapTypeName scalar_is_reference); +use Parse::Pidl::Util qw(has_property is_constant ParseExpr); use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); use Parse::Pidl::Samba4 qw(DeclLong); use vars qw($VERSION); $VERSION = '0.01'; -my $res; -my $res_hdr; +our $res; +our $res_hdr; my $tabs = ""; sub indent() { $tabs.="\t"; } sub deindent() { $tabs = substr($tabs, 1); } @@ -25,13 +29,26 @@ sub pidl($) { $res .= $tabs.(shift)."\n"; } sub pidl_hdr($) { $res_hdr .= (shift)."\n"; } sub fn_declare($) { my ($n) = @_; pidl $n; pidl_hdr "$n;"; } +sub GenerateFunctionInEnv($) +{ + my $fn = shift; + my %env; + + foreach my $e (@{$fn->{ELEMENTS}}) { + if (grep (/in/, @{$e->{DIRECTION}})) { + $env{$e->{NAME}} = "r.in.$e->{NAME}"; + } + } + + return \%env; +} + sub ParseFunction($$) { - my ($if,$fn) = @_; + my ($uif, $fn) = @_; my $inargs = ""; my $defargs = ""; - my $uif = uc($if->{NAME}); my $ufn = "DCERPC_".uc($fn->{NAME}); foreach (@{$fn->{ELEMENTS}}) { @@ -58,7 +75,7 @@ sub ParseFunction($$) pidl "status = cli_do_rpc_ndr(cli, mem_ctx, PI_$uif, $ufn, &r, (ndr_pull_flags_fn_t)ndr_pull_$fn->{NAME}, (ndr_push_flags_fn_t)ndr_push_$fn->{NAME});"; pidl ""; - pidl "if ( !NT_STATUS_IS_OK(status) ) {"; + pidl "if (!NT_STATUS_IS_OK(status)) {"; indent; pidl "return status;"; deindent; @@ -78,16 +95,29 @@ sub ParseFunction($$) fatal($e, "[out] argument is not a pointer or array") if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY"); - if ( ($e->{LEVELS}[0]->{TYPE} eq "POINTER") && ($e->{LEVELS}[0]->{POINTER_TYPE} eq "unique") ) { + if ( ($e->{LEVELS}[0]->{TYPE} eq "POINTER") and + ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") ) { pidl "if ( $e->{NAME} ) {"; indent; + } + + if ($e->{LEVELS}[0]->{TYPE} eq "ARRAY") { + # This is a call to GenerateFunctionInEnv intentionally. + # Since the data is being copied into a user-provided data + # structure, the user should be able to know the size beforehand + # to allocate a structure of the right size. + my $env = GenerateFunctionInEnv($fn); + my $size_is = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e); + pidl "memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is);"; + } else { pidl "*$e->{NAME} = *r.out.$e->{NAME};"; + } + + if ( ($e->{LEVELS}[0]->{TYPE} eq "POINTER") and + ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") ) { deindent; pidl "}"; - } else { - pidl "*$e->{NAME} = *r.out.$e->{NAME};"; } - } pidl""; @@ -99,7 +129,7 @@ sub ParseFunction($$) } elsif ($fn->{RETURN_TYPE} eq "WERROR") { pidl "return werror_to_ntstatus(r.out.result);"; } else { - pidl "/* Sorry, don't know how to convert $fn->{RETURN_TYPE} to NTSTATUS */"; + warning($fn->{ORIGINAL}, "Unable to convert $fn->{RETURN_TYPE} to NTSTATUS"); pidl "return NT_STATUS_OK;"; } @@ -116,7 +146,7 @@ sub ParseInterface($) pidl_hdr "#ifndef __CLI_$uif\__"; pidl_hdr "#define __CLI_$uif\__"; - ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}}); + ParseFunction(uc($if->{NAME}), $_) foreach (@{$if->{FUNCTIONS}}); pidl_hdr "#endif /* __CLI_$uif\__ */"; } diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm index 52e384814d..aa4f3dd1ce 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm @@ -8,7 +8,7 @@ package Parse::Pidl::Samba3::ServerNDR; use strict; use Parse::Pidl qw(warning fatal); -use Parse::Pidl::Typelist qw(mapType scalar_is_reference); +use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference); use Parse::Pidl::Util qw(ParseExpr has_property is_constant); use Parse::Pidl::NDR qw(GetNextLevel); use Parse::Pidl::Samba4 qw(DeclLong); @@ -35,7 +35,7 @@ sub DeclLevel($$) if (has_property($e, "charset")) { $ret.="const char"; } else { - $ret.=mapType($e->{TYPE}); + $ret.=mapTypeName($e->{TYPE}); } my $numstar = $e->{ORIGINAL}->{POINTERS}; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4.pm b/tools/pidl/lib/Parse/Pidl/Samba4.pm index 4ef2daa591..f0c6ae38e8 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4.pm @@ -10,7 +10,7 @@ require Exporter; @EXPORT = qw(is_intree choose_header DeclLong); use Parse::Pidl::Util qw(has_property is_constant); -use Parse::Pidl::Typelist qw(mapType scalar_is_reference); +use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference); use strict; use vars qw($VERSION); @@ -38,12 +38,12 @@ sub DeclLong($) my $ret = ""; if (has_property($element, "represent_as")) { - $ret.=mapType($element->{PROPERTIES}->{represent_as})." "; + $ret.=mapTypeName($element->{PROPERTIES}->{represent_as})." "; } else { if (has_property($element, "charset")) { $ret.="const char"; } else { - $ret.=mapType($element->{TYPE}); + $ret.=mapTypeName($element->{TYPE}); } $ret.=" "; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm deleted file mode 100644 index 85dab37246..0000000000 --- a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm +++ /dev/null @@ -1,142 +0,0 @@ -# COM Header generation -# (C) 2005 Jelmer Vernooij <jelmer@samba.org> - -package Parse::Pidl::Samba4::COM::Header; - -use Parse::Pidl::Typelist qw(mapType); -use Parse::Pidl::Util qw(has_property is_constant); - -use vars qw($VERSION); -$VERSION = '0.01'; - -use strict; - -sub GetArgumentProtoList($) -{ - my $f = shift; - my $res = ""; - - foreach my $a (@{$f->{ELEMENTS}}) { - - $res .= ", " . mapType($a->{TYPE}) . " "; - - my $l = $a->{POINTERS}; - $l-- if (Parse::Pidl::Typelist::scalar_is_reference($a->{TYPE})); - foreach my $i (1..$l) { - $res .= "*"; - } - - if (defined $a->{ARRAY_LEN}[0] && !is_constant($a->{ARRAY_LEN}[0]) && - !$a->{POINTERS}) { - $res .= "*"; - } - $res .= $a->{NAME}; - if (defined $a->{ARRAY_LEN}[0] && is_constant($a->{ARRAY_LEN}[0])) { - $res .= "[$a->{ARRAY_LEN}[0]]"; - } - } - - return $res; -} - -sub GetArgumentList($) -{ - my $f = shift; - my $res = ""; - - foreach (@{$f->{ELEMENTS}}) { $res .= ", $_->{NAME}"; } - - return $res; -} - -##################################################################### -# generate vtable structure for COM interface -sub HeaderVTable($) -{ - my $interface = shift; - my $res; - $res .= "#define " . uc($interface->{NAME}) . "_METHODS \\\n"; - if (defined($interface->{BASE})) { - $res .= "\t" . uc($interface->{BASE} . "_METHODS") . "\\\n"; - } - - my $data = $interface->{DATA}; - foreach my $d (@{$data}) { - $res .= "\t" . mapType($d->{RETURN_TYPE}) . " (*$d->{NAME}) (struct $interface->{NAME} *d, TALLOC_CTX *mem_ctx" . GetArgumentProtoList($d) . ");\\\n" if ($d->{TYPE} eq "FUNCTION"); - } - $res .= "\n"; - $res .= "struct $interface->{NAME}_vtable {\n"; - $res .= "\tstruct GUID iid;\n"; - $res .= "\t" . uc($interface->{NAME}) . "_METHODS\n"; - $res .= "};\n\n"; - - return $res; -} - -sub ParseInterface($) -{ - my $if = shift; - my $res; - - $res .="\n\n/* $if->{NAME} */\n"; - - $res .="#define COM_" . uc($if->{NAME}) . "_UUID $if->{PROPERTIES}->{uuid}\n\n"; - - $res .="struct $if->{NAME}_vtable;\n\n"; - - $res .="struct $if->{NAME} { - struct com_context *ctx; - struct $if->{NAME}_vtable *vtable; - void *object_data; -};\n\n"; - - $res.=HeaderVTable($if); - - foreach my $d (@{$if->{DATA}}) { - next if ($d->{TYPE} ne "FUNCTION"); - - $res .= "#define $if->{NAME}_$d->{NAME}(interface, mem_ctx" . GetArgumentList($d) . ") "; - - $res .= "((interface)->vtable->$d->{NAME}(interface, mem_ctx" . GetArgumentList($d) . "))"; - - $res .="\n"; - } - - return $res; -} - -sub ParseCoClass($) -{ - my $c = shift; - my $res = ""; - $res .= "#define CLSID_" . uc($c->{NAME}) . " $c->{PROPERTIES}->{uuid}\n"; - if (has_property($c, "progid")) { - $res .= "#define PROGID_" . uc($c->{NAME}) . " $c->{PROPERTIES}->{progid}\n"; - } - $res .= "\n"; - return $res; -} - -sub Parse($$) -{ - my ($idl,$ndr_header) = @_; - my $res = ""; - - $res .= "#include \"librpc/gen_ndr/orpc.h\"\n" . - "#include \"$ndr_header\"\n\n"; - - foreach (@{$idl}) - { - if ($_->{TYPE} eq "INTERFACE" && has_property($_, "object")) { - $res.=ParseInterface($_); - } - - if ($_->{TYPE} eq "COCLASS") { - $res.=ParseCoClass($_); - } - } - - return $res; -} - -1; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm deleted file mode 100644 index e6366f0f3d..0000000000 --- a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm +++ /dev/null @@ -1,219 +0,0 @@ -################################################### -# DCOM parser for Samba -# Basically the glue between COM and DCE/RPC with NDR -# Copyright jelmer@samba.org 2003-2005 -# released under the GNU GPL - -package Parse::Pidl::Samba4::COM::Proxy; - -use Parse::Pidl::Samba4::COM::Header; -use Parse::Pidl::Util qw(has_property); - -use vars qw($VERSION); -$VERSION = '0.01'; - -use strict; - -my($res); - -sub ParseVTable($$) -{ - my $interface = shift; - my $name = shift; - - # Generate the vtable - $res .="\tstruct $interface->{NAME}_vtable $name = {"; - - if (defined($interface->{BASE})) { - $res .= "\n\t\t{},"; - } - - my $data = $interface->{DATA}; - - foreach my $d (@{$data}) { - if ($d->{TYPE} eq "FUNCTION") { - $res .= "\n\t\tdcom_proxy_$interface->{NAME}_$d->{NAME}"; - $res .= ","; - } - } - - $res .= "\n\t};\n\n"; -} - -sub ParseRegFunc($) -{ - my $interface = shift; - - $res .= "static NTSTATUS dcom_proxy_$interface->{NAME}_init(void) -{ - struct GUID base_iid; - struct $interface->{NAME}_vtable *proxy_vtable = talloc(talloc_autofree_context(), struct $interface->{NAME}_vtable); -"; - - if (defined($interface->{BASE})) { - $res.= " - const void *base_vtable; - - base_iid = dcerpc_table_$interface->{BASE}.uuid; - - base_vtable = dcom_proxy_vtable_by_iid(&base_iid); - if (base_vtable == NULL) { - DEBUG(0, (\"No proxy registered for base interface '$interface->{BASE}'\\n\")); - return NT_STATUS_FOOBAR; - } - - memcpy(&proxy_vtable, base_vtable, sizeof(struct $interface->{BASE}_vtable)); - -"; - } - foreach my $x (@{$interface->{DATA}}) { - next unless ($x->{TYPE} eq "FUNCTION"); - - $res .= "\tproxy_vtable.$x->{NAME} = dcom_proxy_$interface->{NAME}_$x->{NAME};\n"; - } - - $res.= " - proxy_vtable.iid = dcerpc_table_$interface->{NAME}.uuid; - - return dcom_register_proxy(&proxy_vtable); -}\n\n"; -} - -##################################################################### -# parse a function -sub ParseFunction($$) -{ - my $interface = shift; - my $fn = shift; - my $name = $fn->{NAME}; - my $uname = uc $name; - - $res.=" -static $fn->{RETURN_TYPE} dcom_proxy_$interface->{NAME}_$name(struct $interface->{NAME} *d, TALLOC_CTX *mem_ctx" . Parse::Pidl::Samba4::COM::Header::GetArgumentProtoList($fn) . ") -{ - struct dcerpc_pipe *p; - NTSTATUS status = dcom_get_pipe(d, &p); - struct $name r; - struct rpc_request *req; - - if (NT_STATUS_IS_ERR(status)) { - return status; - } - - ZERO_STRUCT(r.in.ORPCthis); - r.in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION; - r.in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION; -"; - - # Put arguments into r - foreach my $a (@{$fn->{ELEMENTS}}) { - next unless (has_property($a, "in")); - if (Parse::Pidl::Typelist::typeIs($a->{TYPE}, "INTERFACE")) { - $res .="\tNDR_CHECK(dcom_OBJREF_from_IUnknown(&r.in.$a->{NAME}.obj, $a->{NAME}));\n"; - } else { - $res .= "\tr.in.$a->{NAME} = $a->{NAME};\n"; - } - } - - $res .=" - if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) { - NDR_PRINT_IN_DEBUG($name, &r); - } - - status = dcerpc_ndr_request(p, &d->ipid, &dcerpc_table_$interface->{NAME}, DCERPC_$uname, mem_ctx, &r); - - if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) { - NDR_PRINT_OUT_DEBUG($name, r); - } - -"; - - # Put r info back into arguments - foreach my $a (@{$fn->{ELEMENTS}}) { - next unless (has_property($a, "out")); - - if (Parse::Pidl::Typelist::typeIs($a->{TYPE}, "INTERFACE")) { - $res .="\tNDR_CHECK(dcom_IUnknown_from_OBJREF(d->ctx, &$a->{NAME}, r.out.$a->{NAME}.obj));\n"; - } else { - $res .= "\t*$a->{NAME} = r.out.$a->{NAME};\n"; - } - - } - - if ($fn->{RETURN_TYPE} eq "NTSTATUS") { - $res .= "\tif (NT_STATUS_IS_OK(status)) status = r.out.result;\n"; - } - - $res .= - " - return r.out.result; -}\n\n"; -} - -##################################################################### -# parse the interface definitions -sub ParseInterface($) -{ - my($interface) = shift; - my($data) = $interface->{DATA}; - $res = "/* DCOM proxy for $interface->{NAME} generated by pidl */\n\n"; - foreach my $d (@{$data}) { - ($d->{TYPE} eq "FUNCTION") && - ParseFunction($interface, $d); - } - - ParseRegFunc($interface); -} - -sub RegistrationFunction($$) -{ - my $idl = shift; - my $basename = shift; - - my $res = "\n\nNTSTATUS dcom_$basename\_init(void)\n"; - $res .= "{\n"; - $res .="\tNTSTATUS status = NT_STATUS_OK;\n"; - foreach my $interface (@{$idl}) { - next if $interface->{TYPE} ne "INTERFACE"; - next if not has_property($interface, "object"); - - my $data = $interface->{DATA}; - my $count = 0; - foreach my $d (@{$data}) { - if ($d->{TYPE} eq "FUNCTION") { $count++; } - } - - next if ($count == 0); - - $res .= "\tstatus = dcom_$interface->{NAME}_init();\n"; - $res .= "\tif (NT_STATUS_IS_ERR(status)) {\n"; - $res .= "\t\treturn status;\n"; - $res .= "\t}\n\n"; - } - $res .= "\treturn status;\n"; - $res .= "}\n\n"; - - return $res; -} - -sub Parse($$) -{ - my ($pidl,$comh_filename) = @_; - my $res = ""; - - $res .= "#include \"includes.h\"\n" . - "#include \"lib/com/dcom/dcom.h\"\n" . - "#include \"$comh_filename\"\n"; - - foreach (@{$pidl}) { - next if ($_->{TYPE} ne "INTERFACE"); - next if has_property($_, "local"); - next unless has_property($_, "object"); - - $res .= ParseInterface($_); - } - - return $res; -} - -1; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm deleted file mode 100644 index 150acbfde9..0000000000 --- a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm +++ /dev/null @@ -1,327 +0,0 @@ -################################################### -# DCOM stub boilerplate generator -# Copyright jelmer@samba.org 2004-2005 -# Copyright tridge@samba.org 2003 -# Copyright metze@samba.org 2004 -# released under the GNU GPL - -package Parse::Pidl::Samba4::COM::Stub; - -use Parse::Pidl::Util qw(has_property); -use strict; - -use vars qw($VERSION); -$VERSION = '0.01'; - -my($res); - -sub pidl($) -{ - $res .= shift; -} - -##################################################### -# generate the switch statement for function dispatch -sub gen_dispatch_switch($) -{ - my $data = shift; - - my $count = 0; - foreach my $d (@{$data}) { - next if ($d->{TYPE} ne "FUNCTION"); - - pidl "\tcase $count: {\n"; - if ($d->{RETURN_TYPE} && $d->{RETURN_TYPE} ne "void") { - pidl "\t\tNTSTATUS result;\n"; - } - pidl "\t\tstruct $d->{NAME} *r2 = r;\n"; - pidl "\t\tif (DEBUGLEVEL > 10) {\n"; - pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($d->{NAME}, NDR_IN, r2);\n"; - pidl "\t\t}\n"; - if ($d->{RETURN_TYPE} && $d->{RETURN_TYPE} ne "void") { - pidl "\t\tresult = vtable->$d->{NAME}(iface, mem_ctx, r2);\n"; - } else { - pidl "\t\tvtable->$d->{NAME}(iface, mem_ctx, r2);\n"; - } - pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n"; - pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} will reply async\\n\"));\n"; - pidl "\t\t}\n"; - pidl "\t\tbreak;\n\t}\n"; - $count++; - } -} - -##################################################### -# generate the switch statement for function reply -sub gen_reply_switch($) -{ - my $data = shift; - - my $count = 0; - foreach my $d (@{$data}) { - next if ($d->{TYPE} ne "FUNCTION"); - - pidl "\tcase $count: {\n"; - pidl "\t\tstruct $d->{NAME} *r2 = r;\n"; - pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n"; - pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} replied async\\n\"));\n"; - pidl "\t\t}\n"; - pidl "\t\tif (DEBUGLEVEL > 10 && dce_call->fault_code == 0) {\n"; - pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($d->{NAME}, NDR_OUT | NDR_SET_VALUES, r2);\n"; - pidl "\t\t}\n"; - pidl "\t\tif (dce_call->fault_code != 0) {\n"; - pidl "\t\t\tDEBUG(2,(\"dcerpc_fault %s in $d->{NAME}\\n\", dcerpc_errstr(mem_ctx, dce_call->fault_code)));\n"; - pidl "\t\t}\n"; - pidl "\t\tbreak;\n\t}\n"; - $count++; - } -} - -##################################################################### -# produce boilerplate code for a interface -sub Boilerplate_Iface($) -{ - my($interface) = shift; - my($data) = $interface->{DATA}; - my $name = $interface->{NAME}; - my $uname = uc $name; - my $uuid = Parse::Pidl::Util::make_str($interface->{PROPERTIES}->{uuid}); - my $if_version = $interface->{PROPERTIES}->{version}; - - pidl " -static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) -{ -#ifdef DCESRV_INTERFACE_$uname\_BIND - return DCESRV_INTERFACE_$uname\_BIND(dce_call,iface); -#else - return NT_STATUS_OK; -#endif -} - -static void $name\__op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) -{ -#ifdef DCESRV_INTERFACE_$uname\_UNBIND - DCESRV_INTERFACE_$uname\_UNBIND(context, iface); -#else - return; -#endif -} - -static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r) -{ - NTSTATUS status; - uint16_t opnum = dce_call->pkt.u.request.opnum; - - dce_call->fault_code = 0; - - if (opnum >= dcerpc_table_$name.num_calls) { - dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; - return NT_STATUS_NET_WRITE_FAULT; - } - - *r = talloc_size(mem_ctx, dcerpc_table_$name.calls[opnum].struct_size); - NT_STATUS_HAVE_NO_MEMORY(*r); - - /* unravel the NDR for the packet */ - status = dcerpc_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r); - if (!NT_STATUS_IS_OK(status)) { - dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN, - &dce_call->pkt.u.request.stub_and_verifier); - dce_call->fault_code = DCERPC_FAULT_NDR; - return NT_STATUS_NET_WRITE_FAULT; - } - - return NT_STATUS_OK; -} - -static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) -{ - uint16_t opnum = dce_call->pkt.u.request.opnum; - struct GUID ipid = dce_call->pkt.u.request.object.object; - struct dcom_interface_p *iface = dcom_get_local_iface_p(&ipid); - const struct dcom_$name\_vtable *vtable = iface->vtable; - - switch (opnum) { -"; - gen_dispatch_switch($data); - -pidl " - default: - dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; - break; - } - - if (dce_call->fault_code != 0) { - dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN, - &dce_call->pkt.u.request.stub_and_verifier); - return NT_STATUS_NET_WRITE_FAULT; - } - - return NT_STATUS_OK; -} - -static NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) -{ - uint16_t opnum = dce_call->pkt.u.request.opnum; - - switch (opnum) { -"; - gen_reply_switch($data); - -pidl " - default: - dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; - break; - } - - if (dce_call->fault_code != 0) { - dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN, - &dce_call->pkt.u.request.stub_and_verifier); - return NT_STATUS_NET_WRITE_FAULT; - } - - return NT_STATUS_OK; -} - -static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r) -{ - NTSTATUS status; - uint16_t opnum = dce_call->pkt.u.request.opnum; - - status = dcerpc_table_$name.calls[opnum].ndr_push(push, NDR_OUT, r); - if (!NT_STATUS_IS_OK(status)) { - dce_call->fault_code = DCERPC_FAULT_NDR; - return NT_STATUS_NET_WRITE_FAULT; - } - - return NT_STATUS_OK; -} - -static const struct dcesrv_interface $name\_interface = { - .name = \"$name\", - .uuid = $uuid, - .if_version = $if_version, - .bind = $name\__op_bind, - .unbind = $name\__op_unbind, - .ndr_pull = $name\__op_ndr_pull, - .dispatch = $name\__op_dispatch, - .reply = $name\__op_reply, - .ndr_push = $name\__op_ndr_push -}; - -"; -} - -##################################################################### -# produce boilerplate code for an endpoint server -sub Boilerplate_Ep_Server($) -{ - my($interface) = shift; - my $name = $interface->{NAME}; - my $uname = uc $name; - - pidl " -static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) -{ - int i; - - for (i=0;i<dcerpc_table_$name.endpoints->count;i++) { - NTSTATUS ret; - const char *name = dcerpc_table_$name.endpoints->names[i]; - - ret = dcesrv_interface_register(dce_ctx, name, &$name\_interface, NULL); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(1,(\"$name\_op_init_server: failed to register endpoint \'%s\'\\n\",name)); - return ret; - } - } - - return NT_STATUS_OK; -} - -static BOOL $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32_t if_version) -{ - if (dcerpc_table_$name.if_version == if_version && - strcmp(dcerpc_table_$name.uuid, uuid)==0) { - memcpy(iface,&dcerpc_table_$name, sizeof(*iface)); - return True; - } - - return False; -} - -static BOOL $name\__op_interface_by_name(struct dcesrv_interface *iface, const char *name) -{ - if (strcmp(dcerpc_table_$name.name, name)==0) { - memcpy(iface,&dcerpc_table_$name, sizeof(*iface)); - return True; - } - - return False; -} - -NTSTATUS dcerpc_server_$name\_init(void) -{ - NTSTATUS ret; - struct dcesrv_endpoint_server ep_server; - - /* fill in our name */ - ep_server.name = \"$name\"; - - /* fill in all the operations */ - ep_server.init_server = $name\__op_init_server; - - ep_server.interface_by_uuid = $name\__op_interface_by_uuid; - ep_server.interface_by_name = $name\__op_interface_by_name; - - /* register ourselves with the DCERPC subsystem. */ - ret = dcerpc_register_ep_server(&ep_server); - - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,(\"Failed to register \'$name\' endpoint server!\\n\")); - return ret; - } - - return ret; -} - -"; -} - -##################################################################### -# dcom interface stub from a parsed IDL structure -sub ParseInterface($) -{ - my($interface) = shift; - - return "" if has_property($interface, "local"); - - my($data) = $interface->{DATA}; - my $count = 0; - - $res = ""; - - if (!defined $interface->{PROPERTIES}->{uuid}) { - return $res; - } - - if (!defined $interface->{PROPERTIES}->{version}) { - $interface->{PROPERTIES}->{version} = "0.0"; - } - - foreach my $d (@{$data}) { - if ($d->{TYPE} eq "FUNCTION") { $count++; } - } - - if ($count == 0) { - return $res; - } - - $res = "/* dcom interface stub generated by pidl */\n\n"; - Boilerplate_Iface($interface); - Boilerplate_Ep_Server($interface); - - return $res; -} - -1; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/EJS.pm b/tools/pidl/lib/Parse/Pidl/Samba4/EJS.pm index 1ce22d5180..59dc5f001d 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/EJS.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/EJS.pm @@ -380,7 +380,7 @@ sub EjsBitmapPull($$) my $name = shift; my $d = shift; my $type_fn = $d->{BASE_TYPE}; - my($type_decl) = Parse::Pidl::Typelist::mapType($d->{BASE_TYPE}); + my($type_decl) = Parse::Pidl::Typelist::mapTypeName($d->{BASE_TYPE}); fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, $type_decl *r)"); pidl "{"; indent; @@ -648,7 +648,7 @@ sub EjsBitmapPush($$) my $name = shift; my $d = shift; my $type_fn = $d->{BASE_TYPE}; - my($type_decl) = Parse::Pidl::Typelist::mapType($d->{BASE_TYPE}); + my($type_decl) = Parse::Pidl::Typelist::mapTypeName($d->{BASE_TYPE}); # put the bitmap elements in the constants array foreach my $e (@{$d->{ELEMENTS}}) { if ($e =~ /^(\w*)\s*(.*)\s*$/) { diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm b/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm index 96f695d1cd..7e52dbc2ee 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -7,9 +7,8 @@ package Parse::Pidl::Samba4::Header; use strict; -use Parse::Pidl::Typelist qw(mapType); +use Parse::Pidl::Typelist qw(mapTypeName); use Parse::Pidl::Util qw(has_property is_constant); -use Parse::Pidl::NDR qw(GetNextLevel GetPrevLevel); use Parse::Pidl::Samba4 qw(is_intree); use vars qw($VERSION); @@ -56,7 +55,7 @@ sub HeaderElement($) pidl tabs(); if (has_property($element, "represent_as")) { - pidl mapType($element->{PROPERTIES}->{represent_as})." "; + pidl mapTypeName($element->{PROPERTIES}->{represent_as})." "; } else { HeaderType($element, $element->{TYPE}, ""); pidl " "; @@ -210,7 +209,7 @@ sub HeaderType($$$) if (has_property($e, "charset")) { pidl "const char"; } else { - pidl mapType($e->{TYPE}); + pidl mapTypeName($e->{TYPE}); } } @@ -220,8 +219,6 @@ sub HeaderTypedef($) { my($typedef) = shift; HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME}); - pidl ";\n\n" unless ($typedef->{DATA}->{TYPE} eq "BITMAP" or - $typedef->{DATA}->{TYPE} eq "ENUM"); } ##################################################################### @@ -236,15 +233,25 @@ sub HeaderConst($) } } +sub ElementDirection($) +{ + my ($e) = @_; + + return "inout" if (has_property($e, "in") and has_property($e, "out")); + return "in" if (has_property($e, "in")); + return "out" if (has_property($e, "out")); + return "inout"; +} + ##################################################################### # parse a function sub HeaderFunctionInOut($$) { my($fn,$prop) = @_; - foreach (@{$fn->{ELEMENTS}}) { - HeaderElement($_) if (has_property($_, $prop)); - } + foreach (@{$fn->{ELEMENTS}}) { + HeaderElement($_) if (ElementDirection($_) eq $prop); + } } ##################################################################### @@ -255,8 +262,8 @@ sub HeaderFunctionInOut_needed($$) return 1 if ($prop eq "out" && $fn->{RETURN_TYPE} ne "void"); - foreach (@{$fn->{ELEMENTS}}) { - return 1 if (has_property($_, $prop)); + foreach (@{$fn->{ELEMENTS}}) { + return 1 if (ElementDirection($_) eq $prop); } return undef; @@ -278,28 +285,32 @@ sub HeaderFunction($) $tab_depth++; my $needed = 0; - if (HeaderFunctionInOut_needed($fn, "in")) { + if (HeaderFunctionInOut_needed($fn, "in") or + HeaderFunctionInOut_needed($fn, "inout")) { pidl tabs()."struct {\n"; $tab_depth++; HeaderFunctionInOut($fn, "in"); + HeaderFunctionInOut($fn, "inout"); $tab_depth--; pidl tabs()."} in;\n\n"; $needed++; } - if (HeaderFunctionInOut_needed($fn, "out")) { + if (HeaderFunctionInOut_needed($fn, "out") or + HeaderFunctionInOut_needed($fn, "inout")) { pidl tabs()."struct {\n"; $tab_depth++; HeaderFunctionInOut($fn, "out"); + HeaderFunctionInOut($fn, "inout"); if ($fn->{RETURN_TYPE} ne "void") { - pidl tabs().mapType($fn->{RETURN_TYPE}) . " result;\n"; + pidl tabs().mapTypeName($fn->{RETURN_TYPE}) . " result;\n"; } $tab_depth--; pidl tabs()."} out;\n\n"; $needed++; } - if (! $needed) { + if (!$needed) { # sigh - some compilers don't like empty structures pidl tabs()."int _dummy_element;\n"; } @@ -341,8 +352,12 @@ sub HeaderInterface($) } foreach my $d (@{$interface->{DATA}}) { - next if ($d->{TYPE} ne "TYPEDEF"); - HeaderTypedef($d); + HeaderTypedef($d) if ($d->{TYPE} eq "TYPEDEF"); + HeaderStruct($d, $d->{NAME}) if ($d->{TYPE} eq "STRUCT"); + HeaderUnion($d, $d->{NAME}) if ($d->{TYPE} eq "UNION"); + HeaderEnum($d, $d->{NAME}) if ($d->{TYPE} eq "ENUM"); + HeaderBitmap($d, $d->{NAME}) if ($d->{TYPE} eq "BITMAP"); + pidl ";\n\n"; } foreach my $d (@{$interface->{DATA}}) { @@ -365,8 +380,10 @@ sub Parse($) %headerstructs = (); pidl "/* header auto-generated by pidl */\n\n"; if (!is_intree()) { - pidl "#include <core.h>\n\n"; + pidl "#include <core.h>\n"; } + pidl "#include <stdint.h>\n"; + pidl "\n"; foreach (@{$idl}) { ($_->{TYPE} eq "INTERFACE") && HeaderInterface($_); diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index 1e199ba62b..4566279009 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -10,10 +10,12 @@ package Parse::Pidl::Samba4::NDR::Parser; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(is_charset_array); -@EXPORT_OK = qw(check_null_pointer); +@EXPORT_OK = qw(check_null_pointer GenerateFunctionInEnv + GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv NeededFunction + NeededElement NeededType $res); use strict; -use Parse::Pidl::Typelist qw(hasType getType mapType); +use Parse::Pidl::Typelist qw(hasType getType mapTypeName); use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid); use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); use Parse::Pidl::Samba4 qw(is_intree choose_header); @@ -108,7 +110,7 @@ sub get_value_of($) } } -my $res; +our $res; my $deferred = []; my $tabs = ""; @@ -214,16 +216,16 @@ sub end_flags($) } } -sub GenerateStructEnv($) +sub GenerateStructEnv($$) { - my $x = shift; + my ($x, $v) = @_; my %env; foreach my $e (@{$x->{ELEMENTS}}) { - $env{$e->{NAME}} = "r->$e->{NAME}"; + $env{$e->{NAME}} = "$v->$e->{NAME}"; } - $env{"this"} = "r"; + $env{"this"} = $v; return \%env; } @@ -234,7 +236,7 @@ sub EnvSubstituteValue($$) # Substitute the value() values in the env foreach my $e (@{$s->{ELEMENTS}}) { - next unless (my $v = has_property($e, "value")); + next unless (defined(my $v = has_property($e, "value"))); $env->{$e->{NAME}} = ParseExpr($v, $env, $e); } @@ -451,7 +453,9 @@ sub ParseArrayPullHeader($$$$$) if ($l->{IS_VARYING} and not $l->{IS_ZERO_TERMINATED}) { defer "if ($var_name) {"; defer_indent; - my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env)); + my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL}, + check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"), + check_fully_dereferenced($e, $env)); defer "NDR_CHECK(ndr_check_array_length(ndr, (void*)" . get_pointer_to($var_name) . ", $length));"; defer_deindent; defer "}" @@ -632,16 +636,16 @@ sub ParseElementPushLevel # Allow speedups for arrays of scalar types if (is_charset_array($e,$l)) { - pidl "NDR_CHECK(ndr_push_charset($ndr, $ndr_flags, $var_name, $length, sizeof(" . mapType($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));"; + pidl "NDR_CHECK(ndr_push_charset($ndr, $ndr_flags, $var_name, $length, sizeof(" . mapTypeName($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));"; return; } elsif (has_fast_array($e,$l)) { pidl "NDR_CHECK(ndr_push_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));"; return; } } elsif ($l->{TYPE} eq "SWITCH") { - ParseSwitchPush($e, $l, $ndr, $var_name, $ndr_flags, $env); + ParseSwitchPush($e, $l, $ndr, $var_name, $env); } elsif ($l->{TYPE} eq "DATA") { - ParseDataPush($e, $l, $ndr, $var_name, $ndr_flags); + ParseDataPush($e, $l, $ndr, $var_name, $primitives, $deferred); } } @@ -689,21 +693,21 @@ sub ParseElementPushLevel ##################################################################### # parse scalars in a structure element -sub ParseElementPush($$$$$$) +sub ParseElementPush($$$$$) { - my ($e,$ndr,$var_prefix,$env,$primitives,$deferred) = @_; + my ($e,$ndr,$env,$primitives,$deferred) = @_; my $subndr = undef; - my $var_name = $var_prefix.$e->{NAME}; + my $var_name = $env->{$e->{NAME}}; return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0])); # Representation type is different from transmit_as - if ($e->{REPRESENTATION_TYPE}) { + if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { pidl "{"; indent; my $transmit_name = "_transmit_$e->{NAME}"; - pidl mapType($e->{TYPE}) ." $transmit_name;"; + pidl mapTypeName($e->{TYPE}) ." $transmit_name;"; pidl "NDR_CHECK(ndr_$e->{REPRESENTATION_TYPE}_to_$e->{TYPE}($var_name, " . get_pointer_to($transmit_name) . "));"; $var_name = $transmit_name; } @@ -712,7 +716,7 @@ sub ParseElementPush($$$$$$) start_flags($e); - if (my $value = has_property($e, "value")) { + if (defined(my $value = has_property($e, "value"))) { $var_name = ParseExpr($value, $env, $e->{ORIGINAL}); } @@ -720,7 +724,7 @@ sub ParseElementPush($$$$$$) end_flags($e); - if ($e->{REPRESENTATION_TYPE}) { + if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { deindent; pidl "}"; } @@ -748,6 +752,28 @@ sub ParsePtrPush($$$) } } +sub ParseDataPrint($$$) +{ + my ($e, $l, $var_name) = @_; + + if (not ref($l->{DATA_TYPE}) or + defined($l->{DATA_TYPE}->{NAME})) { + my $t; + if (ref($l->{DATA_TYPE})) { + $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}"; + } else { + $t = $l->{DATA_TYPE}; + } + if (not Parse::Pidl::Typelist::is_scalar($t) or + Parse::Pidl::Typelist::scalar_is_reference($t)) { + $var_name = get_pointer_to($var_name); + } + pidl "ndr_print_$t(ndr, \"$e->{NAME}\", $var_name);"; + } else { + ParseTypePrint($l->{DATA_TYPE}, $var_name); + } +} + ##################################################################### # print scalars in a structure element sub ParseElementPrint($$$) @@ -756,14 +782,14 @@ sub ParseElementPrint($$$) return if (has_property($e, "noprint")); - if ($e->{REPRESENTATION_TYPE}) { + if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { pidl "ndr_print_$e->{REPRESENTATION_TYPE}(ndr, \"$e->{NAME}\", $var_name);"; return; } $var_name = append_prefix($e, $var_name); - if (my $value = has_property($e, "value")) { + if (defined(my $value = has_property($e, "value"))) { $var_name = "(ndr->flags & LIBNDR_PRINT_SET_VALUES)?" . ParseExpr($value,$env, $e->{ORIGINAL}) . ":$var_name"; } @@ -812,10 +838,7 @@ sub ParseElementPrint($$$) $var_name = $var_name . "[$counter]"; } } elsif ($l->{TYPE} eq "DATA") { - if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { - $var_name = get_pointer_to($var_name); - } - pidl "ndr_print_$l->{DATA_TYPE}(ndr, \"$e->{NAME}\", $var_name);"; + ParseDataPrint($e, $l, $var_name); } elsif ($l->{TYPE} eq "SWITCH") { my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&pidl, "return;"), check_fully_dereferenced($e, $env)); @@ -845,9 +868,9 @@ sub ParseElementPrint($$$) ##################################################################### # parse scalars in a structure element - pull size -sub ParseSwitchPull($$$$$$) +sub ParseSwitchPull($$$$$) { - my($e,$l,$ndr,$var_name,$ndr_flags,$env) = @_; + my($e,$l,$ndr,$var_name,$env) = @_; my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env)); @@ -857,9 +880,9 @@ sub ParseSwitchPull($$$$$$) ##################################################################### # push switch element -sub ParseSwitchPush($$$$$$) +sub ParseSwitchPush($$$$$) { - my($e,$l,$ndr,$var_name,$ndr_flags,$env) = @_; + my($e,$l,$ndr,$var_name,$env) = @_; my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env)); @@ -867,37 +890,64 @@ sub ParseSwitchPush($$$$$$) pidl "NDR_CHECK(ndr_push_set_switch_value($ndr, $var_name, $switch_var));"; } -sub ParseDataPull($$$$$) +sub ParseDataPull($$$$$$) { - my ($e,$l,$ndr,$var_name,$ndr_flags) = @_; + my ($e,$l,$ndr,$var_name,$primitives,$deferred) = @_; - if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { - $var_name = get_pointer_to($var_name); - } + if (not ref($l->{DATA_TYPE}) or + defined($l->{DATA_TYPE}->{NAME})) { - $var_name = get_pointer_to($var_name); + my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred); + my $t; + if (ref($l->{DATA_TYPE}) eq "HASH") { + $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}"; + } else { + $t = $l->{DATA_TYPE}; + } - pidl "NDR_CHECK(ndr_pull_$l->{DATA_TYPE}($ndr, $ndr_flags, $var_name));"; + if (Parse::Pidl::Typelist::scalar_is_reference($t)) { + $var_name = get_pointer_to($var_name); + } - if (my $range = has_property($e, "range")) { - $var_name = get_value_of($var_name); - my ($low, $high) = split(/ /, $range, 2); - pidl "if ($var_name < $low || $var_name > $high) {"; - pidl "\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");"; - pidl "}"; + $var_name = get_pointer_to($var_name); + + pidl "NDR_CHECK(ndr_pull_$t($ndr, $ndr_flags, $var_name));"; + + if (my $range = has_property($e, "range")) { + $var_name = get_value_of($var_name); + my ($low, $high) = split(/ /, $range, 2); + pidl "if ($var_name < $low || $var_name > $high) {"; + pidl "\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");"; + pidl "}"; + } + } else { + ParseTypePull($l->{DATA_TYPE}, $var_name, $primitives, $deferred); } } -sub ParseDataPush($$$$$) +sub ParseDataPush($$$$$$) { - my ($e,$l,$ndr,$var_name,$ndr_flags) = @_; + my ($e,$l,$ndr,$var_name,$primitives,$deferred) = @_; - # strings are passed by value rather than reference - if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { - $var_name = get_pointer_to($var_name); - } + if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) { + my $t; + if (ref($l->{DATA_TYPE}) eq "HASH") { + $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}"; + } else { + $t = $l->{DATA_TYPE}; + } + + # strings are passed by value rather than reference + if (not Parse::Pidl::Typelist::is_scalar($t) or + Parse::Pidl::Typelist::scalar_is_reference($t)) { + $var_name = get_pointer_to($var_name); + } - pidl "NDR_CHECK(ndr_push_$l->{DATA_TYPE}($ndr, $ndr_flags, $var_name));"; + my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred); + pidl "NDR_CHECK(ndr_push_$t($ndr, $ndr_flags, $var_name));"; + } else { + ParseTypePush($l->{DATA_TYPE}, $var_name, $primitives, $deferred); + } } sub CalcNdrFlags($$$) @@ -1010,7 +1060,7 @@ sub ParseElementPullLevel 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}));"; + pidl "NDR_CHECK(ndr_pull_charset($ndr, $ndr_flags, ".get_pointer_to($var_name).", $length, sizeof(" . mapTypeName($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));"; return; } elsif (has_fast_array($e, $l)) { if ($l->{IS_ZERO_TERMINATED}) { @@ -1022,9 +1072,9 @@ sub ParseElementPullLevel } elsif ($l->{TYPE} eq "POINTER") { ParsePtrPull($e, $l, $ndr, $var_name); } elsif ($l->{TYPE} eq "SWITCH") { - ParseSwitchPull($e, $l, $ndr, $var_name, $ndr_flags, $env); + ParseSwitchPull($e, $l, $ndr, $var_name, $env); } elsif ($l->{TYPE} eq "DATA") { - ParseDataPull($e, $l, $ndr, $var_name, $ndr_flags); + ParseDataPull($e, $l, $ndr, $var_name, $primitives, $deferred); } } @@ -1096,23 +1146,23 @@ sub ParseElementPullLevel ##################################################################### # parse scalars in a structure element - pull size -sub ParseElementPull($$$$$$) +sub ParseElementPull($$$$$) { - my($e,$ndr,$var_prefix,$env,$primitives,$deferred) = @_; + my($e,$ndr,$env,$primitives,$deferred) = @_; - my $var_name = $var_prefix.$e->{NAME}; + my $var_name = $env->{$e->{NAME}}; my $represent_name; my $transmit_name; return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0])); - if ($e->{REPRESENTATION_TYPE}) { + if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { pidl "{"; indent; $represent_name = $var_name; $transmit_name = "_transmit_$e->{NAME}"; $var_name = $transmit_name; - pidl mapType($e->{TYPE})." $var_name;"; + pidl mapTypeName($e->{TYPE})." $var_name;"; } $var_name = append_prefix($e, $var_name); @@ -1124,7 +1174,7 @@ sub ParseElementPull($$$$$$) end_flags($e); # Representation type is different from transmit_as - if ($e->{REPRESENTATION_TYPE}) { + if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { pidl "NDR_CHECK(ndr_$e->{TYPE}_to_$e->{REPRESENTATION_TYPE}($transmit_name, ".get_pointer_to($represent_name)."));"; deindent; pidl "}"; @@ -1186,26 +1236,9 @@ sub ParsePtrPull($$$$) pidl "}"; } -##################################################################### -# parse a struct -sub ParseStructPush($$) +sub ParseStructPushPrimitives($$$) { - my($struct,$name) = @_; - - return unless defined($struct->{ELEMENTS}); - - my $env = GenerateStructEnv($struct); - - EnvSubstituteValue($env, $struct); - - # save the old relative_base_offset - pidl "uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);" if defined($struct->{PROPERTIES}{relative_base}); - - foreach my $e (@{$struct->{ELEMENTS}}) { - DeclareArrayVariables($e); - } - - start_flags($struct); + my ($struct, $varname, $env) = @_; # see if the structure contains a conformant array. If it # does, then it must be the last element of the structure, and @@ -1221,9 +1254,9 @@ sub ParseStructPush($$) if ($e->{LEVELS}[0]->{IS_ZERO_TERMINATED}) { if (has_property($e, "charset")) { - $size = "ndr_charset_length(r->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})"; + $size = "ndr_charset_length($varname->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})"; } else { - $size = "ndr_string_length(r->$e->{NAME}, sizeof(*r->$e->{NAME}))"; + $size = "ndr_string_length($varname->$e->{NAME}, sizeof(*$varname->$e->{NAME}))"; } } else { $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL}); @@ -1231,56 +1264,72 @@ sub ParseStructPush($$) pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));"; } else { - pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, r->$e->{NAME})));"; + pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, $varname->$e->{NAME})));"; } } - pidl "if (ndr_flags & NDR_SCALARS) {"; - indent; - pidl "NDR_CHECK(ndr_push_align(ndr, $struct->{ALIGN}));"; if (defined($struct->{PROPERTIES}{relative_base})) { # set the current offset as base for relative pointers # and store it based on the toplevel struct/union - pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));"; + pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, $varname, ndr->offset));"; } - foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPush($e, "ndr", "r->", $env, 1, 0); - } - - deindent; - pidl "}"; + ParseElementPush($_, "ndr", $env, 1, 0) foreach (@{$struct->{ELEMENTS}}); +} - pidl "if (ndr_flags & NDR_BUFFERS) {"; - indent; +sub ParseStructPushDeferred($$$) +{ + my ($struct, $varname, $env) = @_; if (defined($struct->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union - pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));"; - } - foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPush($e, "ndr", "r->", $env, 0, 1); + pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, $varname));"; } + ParseElementPush($_, "ndr", $env, 0, 1) foreach (@{$struct->{ELEMENTS}}); +} + +##################################################################### +# parse a struct +sub ParseStructPush($$) +{ + my ($struct, $varname) = @_; + + return unless defined($struct->{ELEMENTS}); + + my $env = GenerateStructEnv($struct, $varname); + EnvSubstituteValue($env, $struct); + + DeclareArrayVariables($_) foreach (@{$struct->{ELEMENTS}}); + + start_flags($struct); + + pidl "if (ndr_flags & NDR_SCALARS) {"; + indent; + ParseStructPushPrimitives($struct, $varname, $env); + deindent; + pidl "}"; + + pidl "if (ndr_flags & NDR_BUFFERS) {"; + indent; + ParseStructPushDeferred($struct, $varname, $env); deindent; pidl "}"; end_flags($struct); - # restore the old relative_base_offset - pidl "ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($struct->{PROPERTIES}{relative_base}); } ##################################################################### # generate a push function for an enum sub ParseEnumPush($$) { - my($enum,$name) = @_; + my($enum,$varname) = @_; my($type_fn) = $enum->{BASE_TYPE}; start_flags($enum); - pidl "NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, r));"; + pidl "NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, $varname));"; end_flags($enum); } @@ -1288,30 +1337,30 @@ sub ParseEnumPush($$) # generate a pull function for an enum sub ParseEnumPull($$) { - my($enum,$name) = @_; + my($enum,$varname) = @_; my($type_fn) = $enum->{BASE_TYPE}; - my($type_v_decl) = mapType($type_fn); + my($type_v_decl) = mapTypeName($type_fn); pidl "$type_v_decl v;"; start_flags($enum); pidl "NDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));"; - pidl "*r = v;"; + pidl "*$varname = v;"; end_flags($enum); } ##################################################################### # generate a print function for an enum -sub ParseEnumPrint($$) +sub ParseEnumPrint($$$) { - my($enum,$name) = @_; + my($enum,$name,$varname) = @_; pidl "const char *val = NULL;"; pidl ""; start_flags($enum); - pidl "switch (r) {"; + pidl "switch ($varname) {"; indent; my $els = \@{$enum->{ELEMENTS}}; foreach my $i (0 .. $#{$els}) { @@ -1326,16 +1375,16 @@ sub ParseEnumPrint($$) deindent; pidl "}"; - pidl "ndr_print_enum(ndr, name, \"$enum->{TYPE}\", val, r);"; + pidl "ndr_print_enum(ndr, name, \"$enum->{TYPE}\", val, $varname);"; end_flags($enum); } -sub DeclEnum($) +sub DeclEnum($$$$) { - my ($e,$t) = @_; - return "enum $e->{NAME} " . - ($t eq "pull"?"*":"") . "r"; + my ($e,$t,$name,$varname) = @_; + return "enum $name " . + ($t eq "pull"?"*":"") . $varname; } $typefamily{ENUM} = { @@ -1349,12 +1398,12 @@ $typefamily{ENUM} = { # generate a push function for a bitmap sub ParseBitmapPush($$) { - my($bitmap,$name) = @_; + my($bitmap,$varname) = @_; my($type_fn) = $bitmap->{BASE_TYPE}; start_flags($bitmap); - pidl "NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, r));"; + pidl "NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, $varname));"; end_flags($bitmap); } @@ -1363,24 +1412,24 @@ sub ParseBitmapPush($$) # generate a pull function for an bitmap sub ParseBitmapPull($$) { - my($bitmap,$name) = @_; + my($bitmap,$varname) = @_; my $type_fn = $bitmap->{BASE_TYPE}; - my($type_decl) = mapType($bitmap->{BASE_TYPE}); + my($type_decl) = mapTypeName($bitmap->{BASE_TYPE}); pidl "$type_decl v;"; start_flags($bitmap); pidl "NDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));"; - pidl "*r = v;"; + pidl "*$varname = v;"; end_flags($bitmap); } ##################################################################### # generate a print function for an bitmap -sub ParseBitmapPrintElement($$$) +sub ParseBitmapPrintElement($$$$) { - my($e,$bitmap,$name) = @_; - my($type_decl) = mapType($bitmap->{BASE_TYPE}); + my($e,$bitmap,$name,$varname) = @_; + my($type_decl) = mapTypeName($bitmap->{BASE_TYPE}); my($type_fn) = $bitmap->{BASE_TYPE}; my($flag); @@ -1390,35 +1439,35 @@ sub ParseBitmapPrintElement($$$) die "Bitmap: \"$name\" invalid Flag: \"$e\""; } - pidl "ndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, r);"; + pidl "ndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, $varname);"; } ##################################################################### # generate a print function for an bitmap -sub ParseBitmapPrint($$) +sub ParseBitmapPrint($$$) { - my($bitmap,$name) = @_; - my($type_decl) = mapType($bitmap->{TYPE}); + my($bitmap,$name,$varname) = @_; + my($type_decl) = mapTypeName($bitmap->{TYPE}); my($type_fn) = $bitmap->{BASE_TYPE}; start_flags($bitmap); - pidl "ndr_print_$type_fn(ndr, name, r);"; + pidl "ndr_print_$type_fn(ndr, name, $varname);"; pidl "ndr->depth++;"; foreach my $e (@{$bitmap->{ELEMENTS}}) { - ParseBitmapPrintElement($e, $bitmap, $name); + ParseBitmapPrintElement($e, $bitmap, $name, $varname); } pidl "ndr->depth--;"; end_flags($bitmap); } -sub DeclBitmap($$) +sub DeclBitmap($$$$) { - my ($e,$t) = @_; - return mapType(Parse::Pidl::Typelist::bitmap_type_fn($e->{DATA})) . - ($t eq "pull"?" *":" ") . "r"; + my ($e,$t,$name,$varname) = @_; + return mapTypeName(Parse::Pidl::Typelist::bitmap_type_fn($e)) . + ($t eq "pull"?" *":" ") . $varname; } $typefamily{BITMAP} = { @@ -1430,13 +1479,13 @@ $typefamily{BITMAP} = { ##################################################################### # generate a struct print function -sub ParseStructPrint($$) +sub ParseStructPrint($$$) { - my($struct,$name) = @_; + my($struct,$name,$varname) = @_; return unless defined $struct->{ELEMENTS}; - my $env = GenerateStructEnv($struct); + my $env = GenerateStructEnv($struct, $varname); EnvSubstituteValue($env, $struct); @@ -1448,7 +1497,8 @@ sub ParseStructPrint($$) pidl "ndr->depth++;"; - ParseElementPrint($_, "r->$_->{NAME}", $env) foreach (@{$struct->{ELEMENTS}}); + ParseElementPrint($_, $env->{$_->{NAME}}, $env) + foreach (@{$struct->{ELEMENTS}}); pidl "ndr->depth--;"; end_flags($struct); @@ -1509,33 +1559,12 @@ sub DeclareMemCtxVariables($) } } -##################################################################### -# parse a struct - pull side -sub ParseStructPull($$) +sub ParseStructPullPrimitives($$$) { - my($struct,$name) = @_; - - return unless defined $struct->{ELEMENTS}; - - my $env = GenerateStructEnv($struct); - - # declare any internal pointers we need - foreach my $e (@{$struct->{ELEMENTS}}) { - DeclarePtrVariables($e); - DeclareArrayVariables($e); - DeclareMemCtxVariables($e); - } - - # save the old relative_base_offset - pidl "uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);" if defined($struct->{PROPERTIES}{relative_base}); - - start_flags($struct); - - pidl "if (ndr_flags & NDR_SCALARS) {"; - indent; + my($struct,$varname,$env) = @_; if (defined $struct->{SURROUNDING_ELEMENT}) { - pidl "NDR_CHECK(ndr_pull_array_size(ndr, &r->$struct->{SURROUNDING_ELEMENT}->{NAME}));"; + pidl "NDR_CHECK(ndr_pull_array_size(ndr, &$varname->$struct->{SURROUNDING_ELEMENT}->{NAME}));"; } pidl "NDR_CHECK(ndr_pull_align(ndr, $struct->{ALIGN}));"; @@ -1543,61 +1572,86 @@ sub ParseStructPull($$) if (defined($struct->{PROPERTIES}{relative_base})) { # set the current offset as base for relative pointers # and store it based on the toplevel struct/union - pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));"; + pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, $varname, ndr->offset));"; } - foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPull($e, "ndr", "r->", $env, 1, 0); - } + ParseElementPull($_, "ndr", $env, 1, 0) foreach (@{$struct->{ELEMENTS}}); add_deferred(); +} + +sub ParseStructPullDeferred($$$) +{ + my ($struct,$varname,$env) = @_; - deindent; - pidl "}"; - pidl "if (ndr_flags & NDR_BUFFERS) {"; - indent; if (defined($struct->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union - pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));"; + pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, $varname));"; } foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPull($e, "ndr", "r->", $env, 0, 1); + ParseElementPull($e, "ndr", $env, 0, 1); } add_deferred(); +} + +##################################################################### +# parse a struct - pull side +sub ParseStructPull($$) +{ + my($struct,$varname) = @_; + + return unless defined $struct->{ELEMENTS}; + # declare any internal pointers we need + foreach my $e (@{$struct->{ELEMENTS}}) { + DeclarePtrVariables($e); + DeclareArrayVariables($e); + DeclareMemCtxVariables($e); + } + + start_flags($struct); + + my $env = GenerateStructEnv($struct, $varname); + + pidl "if (ndr_flags & NDR_SCALARS) {"; + indent; + ParseStructPullPrimitives($struct,$varname,$env); + deindent; + pidl "}"; + pidl "if (ndr_flags & NDR_BUFFERS) {"; + indent; + ParseStructPullDeferred($struct,$varname,$env); deindent; pidl "}"; end_flags($struct); - # restore the old relative_base_offset - pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($struct->{PROPERTIES}{relative_base}); } ##################################################################### # calculate size of ndr struct -sub ParseStructNdrSize($) +sub ParseStructNdrSize($$$) { - my $t = shift; + my ($t, $name, $varname) = @_; my $sizevar; if (my $flags = has_property($t, "flag")) { pidl "flags |= $flags;"; } - pidl "return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_$t->{NAME});"; + pidl "return ndr_size_struct($varname, flags, (ndr_push_flags_fn_t)ndr_push_$name);"; } -sub DeclStruct($) +sub DeclStruct($$$$) { - my ($e,$t) = @_; - return ($t ne "pull"?"const ":"") . "struct $e->{NAME} *r"; + my ($e,$t,$name,$varname) = @_; + return ($t ne "pull"?"const ":"") . "struct $name *$varname"; } -sub ArgsStructNdrSize($) +sub ArgsStructNdrSize($$$) { - my $d = shift; - return "const struct $d->{NAME} *r, int flags"; + my ($d, $name, $varname) = @_; + return "const struct $name *$varname, int flags"; } $typefamily{STRUCT} = { @@ -1611,35 +1665,25 @@ $typefamily{STRUCT} = { ##################################################################### # calculate size of ndr struct -sub ParseUnionNdrSize($) +sub ParseUnionNdrSize($$$) { - my $t = shift; + my ($t, $name, $varname) = @_; my $sizevar; if (my $flags = has_property($t, "flag")) { pidl "flags |= $flags;"; } - pidl "return ndr_size_union(r, flags, level, (ndr_push_flags_fn_t)ndr_push_$t->{NAME});"; + pidl "return ndr_size_union($varname, flags, level, (ndr_push_flags_fn_t)ndr_push_$name);"; } -##################################################################### -# parse a union - push side -sub ParseUnionPush($$) +sub ParseUnionPushPrimitives($$) { - my ($e,$name) = @_; - my $have_default = 0; + my ($e, $varname) = @_; - # save the old relative_base_offset - pidl "uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);" if defined($e->{PROPERTIES}{relative_base}); - pidl "int level;"; - - start_flags($e); - - pidl "level = ndr_push_get_switch_value(ndr, r);"; + my $have_default = 0; - pidl "if (ndr_flags & NDR_SCALARS) {"; - indent; + pidl "int level = ndr_push_get_switch_value(ndr, $varname);"; if (defined($e->{SWITCH_TYPE})) { pidl "NDR_CHECK(ndr_push_$e->{SWITCH_TYPE}(ndr, NDR_SCALARS, level));"; @@ -1659,10 +1703,10 @@ sub ParseUnionPush($$) pidl "NDR_CHECK(ndr_push_align(ndr, $el->{ALIGN}));"; # set the current offset as base for relative pointers # and store it based on the toplevel struct/union - pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));"; + pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, $varname, ndr->offset));"; } DeclareArrayVariables($el); - ParseElementPush($el, "ndr", "r->", {}, 1, 0); + ParseElementPush($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0); deindent; } pidl "break;"; @@ -1674,22 +1718,31 @@ sub ParseUnionPush($$) } deindent; pidl "}"; - deindent; - pidl "}"; - pidl "if (ndr_flags & NDR_BUFFERS) {"; - indent; +} + +sub ParseUnionPushDeferred($$) +{ + my ($e, $varname) = @_; + + my $have_default = 0; + + pidl "int level = ndr_push_get_switch_value(ndr, $varname);"; if (defined($e->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union - pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));"; + pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, $varname));"; } pidl "switch (level) {"; indent; foreach my $el (@{$e->{ELEMENTS}}) { + if ($el->{CASE} eq "default") { + $have_default = 1; + } + pidl "$el->{CASE}:"; if ($el->{TYPE} ne "EMPTY") { indent; - ParseElementPush($el, "ndr", "r->", {}, 0, 1); + ParseElementPush($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1); deindent; } pidl "break;"; @@ -1701,19 +1754,35 @@ sub ParseUnionPush($$) } deindent; pidl "}"; +} +##################################################################### +# parse a union - push side +sub ParseUnionPush($$) +{ + my ($e,$varname) = @_; + my $have_default = 0; + + start_flags($e); + + pidl "if (ndr_flags & NDR_SCALARS) {"; + indent; + ParseUnionPushPrimitives($e, $varname); + deindent; + pidl "}"; + pidl "if (ndr_flags & NDR_BUFFERS) {"; + indent; + ParseUnionPushDeferred($e, $varname); deindent; pidl "}"; end_flags($e); - # restore the old relative_base_offset - pidl "ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($e->{PROPERTIES}{relative_base}); } ##################################################################### # print a union -sub ParseUnionPrint($$) +sub ParseUnionPrint($$$) { - my ($e,$name) = @_; + my ($e,$name,$varname) = @_; my $have_default = 0; pidl "int level;"; @@ -1723,7 +1792,7 @@ sub ParseUnionPrint($$) start_flags($e); - pidl "level = ndr_print_get_switch_value(ndr, r);"; + pidl "level = ndr_print_get_switch_value(ndr, $varname);"; pidl "ndr_print_union(ndr, name, level, \"$name\");"; @@ -1736,7 +1805,7 @@ sub ParseUnionPrint($$) pidl "$el->{CASE}:"; if ($el->{TYPE} ne "EMPTY") { indent; - ParseElementPrint($el, "r->$el->{NAME}", {}); + ParseElementPrint($el, "$varname->$el->{NAME}", {}); deindent; } pidl "break;"; @@ -1752,43 +1821,15 @@ sub ParseUnionPrint($$) end_flags($e); } -##################################################################### -# parse a union - pull side -sub ParseUnionPull($$) +sub ParseUnionPullPrimitives($$$) { - my ($e,$name) = @_; + my ($e,$varname,$switch_type) = @_; my $have_default = 0; - my $switch_type = $e->{SWITCH_TYPE}; - - # save the old relative_base_offset - pidl "uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);" if defined($e->{PROPERTIES}{relative_base}); - pidl "int level;"; - if (defined($switch_type)) { - if (Parse::Pidl::Typelist::typeIs($switch_type, "ENUM")) { - $switch_type = Parse::Pidl::Typelist::enum_type_fn(getType($switch_type)->{DATA}); - } - pidl mapType($switch_type) . " _level;"; - } - - my %double_cases = (); - foreach my $el (@{$e->{ELEMENTS}}) { - next if ($el->{TYPE} eq "EMPTY"); - next if ($double_cases{"$el->{NAME}"}); - DeclareMemCtxVariables($el); - $double_cases{"$el->{NAME}"} = 1; - } - - start_flags($e); - - pidl "level = ndr_pull_get_switch_value(ndr, r);"; - - pidl "if (ndr_flags & NDR_SCALARS) {"; - indent; if (defined($switch_type)) { pidl "NDR_CHECK(ndr_pull_$switch_type(ndr, NDR_SCALARS, &_level));"; pidl "if (_level != level) {"; - pidl "\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $name\", _level);"; + pidl "\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $varname\", _level);"; pidl "}"; } @@ -1808,9 +1849,9 @@ sub ParseUnionPull($$) pidl "NDR_CHECK(ndr_pull_align(ndr, $el->{ALIGN}));"; # set the current offset as base for relative pointers # and store it based on the toplevel struct/union - pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));"; + pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, $varname, ndr->offset));"; } - ParseElementPull($el, "ndr", "r->", {}, 1, 0); + ParseElementPull($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0); deindent; } pidl "break; }"; @@ -1822,22 +1863,29 @@ sub ParseUnionPull($$) } deindent; pidl "}"; - deindent; - pidl "}"; - pidl "if (ndr_flags & NDR_BUFFERS) {"; - indent; +} + +sub ParseUnionPullDeferred($$) +{ + my ($e,$varname) = @_; + my $have_default = 0; + if (defined($e->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union - pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));"; + pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, $varname));"; } pidl "switch (level) {"; indent; foreach my $el (@{$e->{ELEMENTS}}) { + if ($el->{CASE} eq "default") { + $have_default = 1; + } + pidl "$el->{CASE}:"; if ($el->{TYPE} ne "EMPTY") { indent; - ParseElementPull($el, "ndr", "r->", {}, 0, 1); + ParseElementPull($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1); deindent; } pidl "break;"; @@ -1850,26 +1898,63 @@ sub ParseUnionPull($$) deindent; pidl "}"; + +} + +##################################################################### +# parse a union - pull side +sub ParseUnionPull($$) +{ + my ($e,$varname) = @_; + my $switch_type = $e->{SWITCH_TYPE}; + + pidl "int level;"; + if (defined($switch_type)) { + if (Parse::Pidl::Typelist::typeIs($switch_type, "ENUM")) { + $switch_type = Parse::Pidl::Typelist::enum_type_fn(getType($switch_type)->{DATA}); + } + pidl mapTypeName($switch_type) . " _level;"; + } + + my %double_cases = (); + foreach my $el (@{$e->{ELEMENTS}}) { + next if ($el->{TYPE} eq "EMPTY"); + next if ($double_cases{"$el->{NAME}"}); + DeclareMemCtxVariables($el); + $double_cases{"$el->{NAME}"} = 1; + } + + start_flags($e); + + pidl "level = ndr_pull_get_switch_value(ndr, $varname);"; + + pidl "if (ndr_flags & NDR_SCALARS) {"; + indent; + ParseUnionPullPrimitives($e,$varname,$switch_type); + deindent; + pidl "}"; + + pidl "if (ndr_flags & NDR_BUFFERS) {"; + indent; + ParseUnionPullDeferred($e,$varname); deindent; pidl "}"; add_deferred(); end_flags($e); - # restore the old relative_base_offset - pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($e->{PROPERTIES}{relative_base}); } -sub DeclUnion($$) +sub DeclUnion($$$$) { - my ($e,$t) = @_; - return ($t ne "pull"?"const ":"") . "union $e->{NAME} *r"; + my ($e,$t,$name,$varname) = @_; + return ($t ne "pull"?"const ":"") . "union $name *$varname"; } -sub ArgsUnionNdrSize($) +sub ArgsUnionNdrSize($$) { - my $d = shift; - return "const union $d->{NAME} *r, uint32_t level, int flags"; + my ($d,$name) = @_; + return "const union $name *r, uint32_t level, int flags"; } $typefamily{UNION} = { @@ -1883,81 +1968,62 @@ $typefamily{UNION} = { ##################################################################### # parse a typedef - push side -sub ParseTypedefPush($) +sub ParseTypedefPush($$) { - my($e) = shift; - - my $args = $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e,"push"); - fn_declare("push", $e, "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, $args)") or return; + my($e,$varname) = @_; - pidl "{"; - indent; - $typefamily{$e->{DATA}->{TYPE}}->{PUSH_FN_BODY}->($e->{DATA}, $e->{NAME}); - pidl "return NT_STATUS_OK;"; - deindent; - pidl "}"; - pidl "";; + $typefamily{$e->{DATA}->{TYPE}}->{PUSH_FN_BODY}->($e->{DATA}, $varname); } ##################################################################### # parse a typedef - pull side -sub ParseTypedefPull($) +sub ParseTypedefPull($$) { - my($e) = shift; + my($e,$varname) = @_; - my $args = $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e,"pull"); - - fn_declare("pull", $e, "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, $args)") or return; - - pidl "{"; - indent; - $typefamily{$e->{DATA}->{TYPE}}->{PULL_FN_BODY}->($e->{DATA}, $e->{NAME}); - pidl "return NT_STATUS_OK;"; - deindent; - pidl "}"; - pidl ""; + $typefamily{$e->{DATA}->{TYPE}}->{PULL_FN_BODY}->($e->{DATA}, $varname); } ##################################################################### # parse a typedef - print side -sub ParseTypedefPrint($) +sub ParseTypedefPrint($$$) { - my($e) = shift; - - my $args = $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e,"print"); - - pidl_hdr "void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args);"; + my($e,$name,$varname) = @_; - return if (has_property($e, "noprint")); - - pidl "_PUBLIC_ void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args)"; - pidl "{"; - indent; - $typefamily{$e->{DATA}->{TYPE}}->{PRINT_FN_BODY}->($e->{DATA}, $e->{NAME}); - deindent; - pidl "}"; - pidl ""; + $typefamily{$e->{DATA}->{TYPE}}->{PRINT_FN_BODY}->($e->{DATA}, $name, $varname); } ##################################################################### ## calculate the size of a structure -sub ParseTypedefNdrSize($) +sub ParseTypedefNdrSize($$$) { - my($t) = shift; + my($t,$name,$varname) = @_; - my $tf = $typefamily{$t->{DATA}->{TYPE}}; - my $args = $tf->{SIZE_FN_ARGS}->($t); + $typefamily{$t->{DATA}->{TYPE}}->{SIZE_FN_BODY}->($t->{DATA}, $name, $varname); +} - fn_declare("size", $t, "size_t ndr_size_$t->{NAME}($args)") or return; +sub DeclTypedef($$$$) +{ + my ($e, $t, $name, $varname) = @_; + + return $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e->{DATA}, $t, $name, $varname); +} - pidl "{"; - indent; - $typefamily{$t->{DATA}->{TYPE}}->{SIZE_FN_BODY}->($t); - deindent; - pidl "}"; - pidl ""; +sub ArgsTypedefNdrSize($$$) +{ + my ($d, $name, $varname) = @_; + return $typefamily{$d->{DATA}->{TYPE}}->{SIZE_FN_ARGS}->($d->{DATA}, $name, $varname); } +$typefamily{TYPEDEF} = { + PUSH_FN_BODY => \&ParseTypedefPush, + DECL => \&DeclTypedef, + PULL_FN_BODY => \&ParseTypedefPull, + PRINT_FN_BODY => \&ParseTypedefPrint, + SIZE_FN_ARGS => \&ArgsTypedefNdrSize, + SIZE_FN_BODY => \&ParseTypedefNdrSize, +}; + ##################################################################### # parse a function - print side sub ParseFunctionPrint($) @@ -1993,7 +2059,7 @@ sub ParseFunctionPrint($) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - ParseElementPrint($e, "r->in.$e->{NAME}", $env); + ParseElementPrint($e, $env->{$e->{NAME}}, $env); } } pidl "ndr->depth--;"; @@ -2008,7 +2074,7 @@ sub ParseFunctionPrint($) $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - ParseElementPrint($e, "r->out.$e->{NAME}", $env); + ParseElementPrint($e, $env->{$e->{NAME}}, $env); } } if ($fn->{RETURN_TYPE}) { @@ -2050,7 +2116,7 @@ sub ParseFunctionPush($) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - ParseElementPush($e, "ndr", "r->in.", $env, 1, 1); + ParseElementPush($e, "ndr", $env, 1, 1); } } @@ -2063,7 +2129,7 @@ sub ParseFunctionPush($) $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - ParseElementPush($e, "ndr", "r->out.", $env, 1, 1); + ParseElementPush($e, "ndr", $env, 1, 1); } } @@ -2147,7 +2213,7 @@ sub ParseFunctionPull($) foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/in/, @{$e->{DIRECTION}})); - ParseElementPull($e, "ndr", "r->in.", $env, 1, 1); + ParseElementPull($e, "ndr", $env, 1, 1); } # allocate the "simple" out ref variables. FIXME: Shouldn't this have it's @@ -2194,7 +2260,7 @@ sub ParseFunctionPull($) $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { next unless grep(/out/, @{$e->{DIRECTION}}); - ParseElementPull($e, "ndr", "r->out.", $env, 1, 1); + ParseElementPull($e, "ndr", $env, 1, 1); } if ($fn->{RETURN_TYPE}) { @@ -2375,6 +2441,105 @@ sub HeaderInterface($) } +sub ParseTypePush($$$$) +{ + my ($e, $varname, $primitives, $deferred) = @_; + + # save the old relative_base_offset + pidl "uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);" if defined(has_property($e, "relative_base")); + $typefamily{$e->{TYPE}}->{PUSH_FN_BODY}->($e, $varname); + # restore the old relative_base_offset + pidl "ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined(has_property($e, "relative_base")); +} + +sub ParseTypePushFunction($$) +{ + my ($e, $varname) = @_; + + my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "push", $e->{NAME}, $varname); + fn_declare("push", $e, "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, $args)") or return; + + pidl "{"; + indent; + ParseTypePush($e, $varname, 1, 1); + pidl "return NT_STATUS_OK;"; + deindent; + pidl "}"; + pidl "";; +} + +sub ParseTypePull($$$$) +{ + my ($e, $varname, $primitives, $deferred) = @_; + + # save the old relative_base_offset + pidl "uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);" if defined(has_property($e, "relative_base")); + $typefamily{$e->{TYPE}}->{PULL_FN_BODY}->($e, $varname); + # restore the old relative_base_offset + pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined(has_property($e, "relative_base")); +} + + +sub ParseTypePullFunction($$) +{ + my ($e, $varname) = @_; + + my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "pull", $e->{NAME}, $varname); + + fn_declare("pull", $e, "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, $args)") or return; + + pidl "{"; + indent; + ParseTypePull($e, $varname, 1, 1); + pidl "return NT_STATUS_OK;"; + deindent; + pidl "}"; + pidl ""; +} + +sub ParseTypePrint($$) +{ + my ($e, $varname) = @_; + + $typefamily{$e->{TYPE}}->{PRINT_FN_BODY}->($e, $e->{NAME}, $varname); +} + +sub ParseTypePrintFunction($$) +{ + my ($e, $varname) = @_; + my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "print", $e->{NAME}, $varname); + + pidl_hdr "void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args);"; + + return if (has_property($e, "noprint")); + + pidl "_PUBLIC_ void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args)"; + pidl "{"; + indent; + ParseTypePrint($e, $varname); + deindent; + pidl "}"; + pidl ""; +} + +sub ParseTypeNdrSize($) +{ + my ($t) = @_; + + my $varname = "r"; + my $tf = $typefamily{$t->{TYPE}}; + my $args = $tf->{SIZE_FN_ARGS}->($t, $t->{NAME}, $varname); + + fn_declare("size", $t, "size_t ndr_size_$t->{NAME}($args)") or return; + + pidl "{"; + indent; + $typefamily{$t->{TYPE}}->{SIZE_FN_BODY}->($t, $t->{NAME}, $varname); + deindent; + pidl "}"; + pidl ""; +} + ##################################################################### # parse the interface definitions sub ParseInterface($$) @@ -2394,15 +2559,15 @@ sub ParseInterface($$) # Typedefs foreach my $d (@{$interface->{TYPES}}) { - ($needed->{"push_$d->{NAME}"}) && ParseTypedefPush($d); - ($needed->{"pull_$d->{NAME}"}) && ParseTypedefPull($d); - ($needed->{"print_$d->{NAME}"}) && ParseTypedefPrint($d); + ($needed->{"push_$d->{NAME}"}) && ParseTypePushFunction($d, "r"); + ($needed->{"pull_$d->{NAME}"}) && ParseTypePullFunction($d, "r"); + ($needed->{"print_$d->{NAME}"}) && ParseTypePrintFunction($d, "r"); # Make sure we don't generate a function twice... $needed->{"push_$d->{NAME}"} = $needed->{"pull_$d->{NAME}"} = $needed->{"print_$d->{NAME}"} = 0; - ($needed->{"ndr_size_$d->{NAME}"}) && ParseTypedefNdrSize($d); + ($needed->{"ndr_size_$d->{NAME}"}) && ParseTypeNdrSize($d); } # Functions @@ -2480,6 +2645,34 @@ sub Parse($$$) return ($res_hdr, $res); } +sub NeededElement($$$) +{ + my ($e, $dir, $needed) = @_; + + return if ($e->{TYPE} eq "EMPTY"); + + my @fn = (); + if ($dir eq "print") { + push(@fn, "print_$e->{REPRESENTATION_TYPE}"); + } elsif ($dir eq "pull") { + push (@fn, "pull_$e->{TYPE}"); + push (@fn, "ndr_$e->{TYPE}_to_$e->{REPRESENTATION_TYPE}") + if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}); + } elsif ($dir eq "push") { + push (@fn, "push_$e->{TYPE}"); + push (@fn, "ndr_$e->{REPRESENTATION_TYPE}_to_$e->{TYPE}") + if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}); + } else { + die("invalid direction `$dir'"); + } + + foreach (@fn) { + unless (defined($needed->{$_})) { + $needed->{$_} = 1; + } + } +} + sub NeededFunction($$) { my ($fn,$needed) = @_; @@ -2488,19 +2681,11 @@ sub NeededFunction($$) $needed->{"print_$fn->{NAME}"} = 1; foreach my $e (@{$fn->{ELEMENTS}}) { $e->{PARENT} = $fn; - unless(defined($needed->{"pull_$e->{TYPE}"})) { - $needed->{"pull_$e->{TYPE}"} = 1; - } - unless(defined($needed->{"push_$e->{TYPE}"})) { - $needed->{"push_$e->{TYPE}"} = 1; - } - unless(defined($needed->{"print_$e->{TYPE}"})) { - $needed->{"print_$e->{TYPE}"} = 1; - } + NeededElement($e, $_, $needed) foreach ("pull", "push", "print"); } } -sub NeededTypedef($$) +sub NeededType($$) { my ($t,$needed) = @_; if (has_property($t, "public")) { @@ -2519,18 +2704,9 @@ sub NeededTypedef($$) if (has_property($e, "compression")) { $needed->{"compression"} = 1; } - if ($needed->{"pull_$t->{NAME}"} and - not defined($needed->{"pull_$e->{TYPE}"})) { - $needed->{"pull_$e->{TYPE}"} = 1; - } - if ($needed->{"push_$t->{NAME}"} and - not defined($needed->{"push_$e->{TYPE}"})) { - $needed->{"push_$e->{TYPE}"} = 1; - } - if ($needed->{"print_$t->{NAME}"} and - not defined($needed->{"print_$e->{TYPE}"})) { - $needed->{"print_$e->{TYPE}"} = 1; - } + NeededElement($e, "pull", $needed) if ($needed->{"pull_$t->{NAME}"}); + NeededElement($e, "push", $needed) if ($needed->{"push_$t->{NAME}"}); + NeededElement($e, "print", $needed) if ($needed->{"print_$t->{NAME}"}); } } } @@ -2541,7 +2717,7 @@ sub NeededInterface($$) { my ($interface,$needed) = @_; NeededFunction($_, $needed) foreach (@{$interface->{FUNCTIONS}}); - NeededTypedef($_, $needed) foreach (reverse @{$interface->{TYPES}}); + NeededType($_, $needed) foreach (reverse @{$interface->{TYPES}}); } 1; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm b/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm index 57ff007d1b..d541f318ee 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/SWIG.pm @@ -8,7 +8,7 @@ package Parse::Pidl::Samba4::SWIG; use vars qw($VERSION); use Parse::Pidl::Samba4 qw(DeclLong); -use Parse::Pidl::Typelist qw(mapType); +use Parse::Pidl::Typelist qw(mapTypeName); use Parse::Pidl::Util qw(has_property); $VERSION = '0.01'; @@ -77,7 +77,7 @@ sub ParseInterface($$) $name =~ s/^$if->{NAME}_//g; $name =~ s/^$basename\_//g; $args .= "TALLOC_CTX *mem_ctx = NULL"; - pidl mapType($fn->{RETURN_TYPE}) . " $name($args)"; + pidl mapTypeName($fn->{RETURN_TYPE}) . " $name($args)"; pidl "{"; indent; pidl "struct $fn->{NAME} r;"; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm b/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm index a3e8d3470b..f1f23bf84b 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm @@ -1,6 +1,6 @@ ################################################### # Trivial Parser Generator -# Copyright jelmer@samba.org 2005 +# Copyright jelmer@samba.org 2005-2007 # released under the GNU GPL package Parse::Pidl::Samba4::TDR; @@ -8,13 +8,17 @@ use Parse::Pidl qw(fatal); use Parse::Pidl::Util qw(has_property ParseExpr is_constant); use Parse::Pidl::Samba4 qw(is_intree choose_header); +use Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(ParserType $ret $ret_hdr); + use vars qw($VERSION); $VERSION = '0.01'; use strict; -my $ret; -my $ret_hdr; +our $ret; +our $ret_hdr; my $tabs = ""; sub indent() { $tabs.="\t"; } @@ -117,14 +121,14 @@ sub ParserElement($$$) sub ParserStruct($$$$) { - my ($e,$n,$t,$p) = @_; + my ($e,$t,$p) = @_; - fn_declare($p,,"NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".typearg($t).", struct $n *v)"); + fn_declare($p,"NTSTATUS tdr_$t\_$e->{NAME} (struct tdr_$t *tdr".typearg($t).", struct $e->{NAME} *v)"); pidl "{"; indent; pidl "int i;" if (ContainsArray($e)); if ($t eq "print") { - pidl "tdr->print(tdr, \"\%-25s: struct $n\", name);"; + pidl "tdr->print(tdr, \"\%-25s: struct $e->{NAME}\", name);"; pidl "tdr->level++;"; } @@ -141,16 +145,16 @@ sub ParserStruct($$$$) deindent; pidl "}"; } -sub ParserUnion($$$$) +sub ParserUnion($$$) { - my ($e,$n,$t,$p) = @_; + my ($e,$t,$p) = @_; - fn_declare($p,"NTSTATUS tdr_$t\_$n(struct tdr_$t *tdr".typearg($t).", int level, union $n *v)"); + fn_declare($p,"NTSTATUS tdr_$t\_$e->{NAME}(struct tdr_$t *tdr".typearg($t).", int level, union $e->{NAME} *v)"); pidl "{"; indent; pidl "int i;" if (ContainsArray($e)); if ($t eq "print") { - pidl "tdr->print(tdr, \"\%-25s: union $n\", name);"; + pidl "tdr->print(tdr, \"\%-25s: union $e->{NAME}\", name);"; pidl "tdr->level++;"; } @@ -174,19 +178,19 @@ sub ParserUnion($$$$) deindent; pidl "}"; } -sub ParserBitmap($$$$) +sub ParserBitmap($$$) { - my ($e,$n,$t,$p) = @_; + my ($e,$t,$p) = @_; return if ($p); - pidl "#define tdr_$t\_$n tdr_$t\_" . Parse::Pidl::Typelist::bitmap_type_fn($e); + pidl "#define tdr_$t\_$e->{NAME} tdr_$t\_" . Parse::Pidl::Typelist::bitmap_type_fn($e); } -sub ParserEnum($$$$) +sub ParserEnum($$$) { - my ($e,$n,$t,$p) = @_; + my ($e,$t,$p) = @_; my $bt = ($e->{PROPERTIES}->{base_type} or "uint8"); - fn_declare($p, "NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".typearg($t).", enum $n *v)"); + fn_declare($p, "NTSTATUS tdr_$t\_$e->{NAME} (struct tdr_$t *tdr".typearg($t).", enum $e->{NAME} *v)"); pidl "{"; if ($t eq "pull") { pidl "\t$bt\_t r;"; @@ -201,17 +205,27 @@ sub ParserEnum($$$$) pidl "}"; } -sub ParserTypedef($$) +sub ParserTypedef($$$) +{ + my ($e,$t,$p) = @_; + + ParserType($e->{DATA},$t); +} + +sub ParserType($$) { my ($e,$t) = @_; return if (has_property($e, "no$t")); - $e->{DATA}->{PROPERTIES} = $e->{PROPERTIES}; - - { STRUCT => \&ParserStruct, UNION => \&ParserUnion, - ENUM => \&ParserEnum, BITMAP => \&ParserBitmap - }->{$e->{DATA}->{TYPE}}->($e->{DATA}, $e->{NAME}, $t, has_property($e, "public")); + my $handlers = { + STRUCT => \&ParserStruct, UNION => \&ParserUnion, + ENUM => \&ParserEnum, BITMAP => \&ParserBitmap, + TYPEDEF => \&ParserTypedef + }; + + $handlers->{$e->{TYPE}}->($e, $t, has_property($e, "public")) + if (defined($handlers->{$e->{TYPE}})); pidl ""; } @@ -224,10 +238,9 @@ sub ParserInterface($) pidl_hdr "#define __TDR_$x->{NAME}_HEADER__"; foreach (@{$x->{DATA}}) { - next if ($_->{TYPE} ne "TYPEDEF"); - ParserTypedef($_, "pull"); - ParserTypedef($_, "push"); - ParserTypedef($_, "print"); + ParserType($_, "pull"); + ParserType($_, "push"); + ParserType($_, "print"); } pidl_hdr "#endif /* __TDR_$x->{NAME}_HEADER__ */"; diff --git a/tools/pidl/lib/Parse/Pidl/Typelist.pm b/tools/pidl/lib/Parse/Pidl/Typelist.pm index 7be7e5a5c3..55f8390f65 100644 --- a/tools/pidl/lib/Parse/Pidl/Typelist.pm +++ b/tools/pidl/lib/Parse/Pidl/Typelist.pm @@ -7,14 +7,17 @@ package Parse::Pidl::Typelist; require Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(hasType getType mapType scalar_is_reference expandAlias); +@EXPORT_OK = qw(hasType getType mapTypeName scalar_is_reference expandAlias + mapScalarType addType typeIs is_scalar enum_type_fn + bitmap_type_fn mapType +); use vars qw($VERSION); $VERSION = '0.01'; use Parse::Pidl::Util qw(has_property); use strict; -my %typedefs = (); +my %types = (); my @reference_scalars = ( "string", "string_array", "nbt_string", @@ -89,14 +92,14 @@ sub mapScalarType($) sub addType($) { my $t = shift; - $typedefs{$t->{NAME}} = $t; + $types{$t->{NAME}} = $t; } sub getType($) { my $t = shift; return undef if not hasType($t); - return $typedefs{$t}; + return $types{$t}; } sub typeIs($$) @@ -110,7 +113,7 @@ sub typeIs($$) sub hasType($) { my $t = shift; - return 1 if defined($typedefs{$t}); + return 1 if defined($types{$t}); return 0; } @@ -178,7 +181,22 @@ sub bitmap_type_fn($) return "uint32"; } -sub mapType($) +sub mapType($$) +{ + sub mapType($$); + my ($t, $n) = @_; + + return mapType($t->{DATA}, $n) if ($t->{TYPE} eq "TYPEDEF"); + return mapType($t->{DATA}, $n) if ($t->{TYPE} eq "DECLARE"); + return mapScalarType($n) if ($t->{TYPE} eq "SCALAR"); + return "enum $n" if ($t->{TYPE} eq "ENUM"); + return "struct $n" if ($t->{TYPE} eq "STRUCT"); + return "union $n" if ($t->{TYPE} eq "UNION"); + return mapScalarType(bitmap_type_fn($t)) if ($t->{TYPE} eq "BITMAP"); + die("Unknown type $t->{TYPE}"); +} + +sub mapTypeName($) { my $t = shift; return "void" unless defined($t); @@ -189,17 +207,8 @@ sub mapType($) # Best guess return "struct $t"; } - return mapScalarType($t) if ($dt->{DATA}->{TYPE} eq "SCALAR"); - return "enum $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "ENUM"); - return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "STRUCT"); - return "struct $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "INTERFACE"); - return "union $dt->{NAME}" if ($dt->{DATA}->{TYPE} eq "UNION"); - - if ($dt->{DATA}->{TYPE} eq "BITMAP") { - return mapScalarType(bitmap_type_fn($dt->{DATA})); - } - die("Unknown type $dt->{DATA}->{TYPE}"); + return mapType($dt, $dt->{NAME}); } sub LoadIdl($) @@ -209,17 +218,14 @@ sub LoadIdl($) foreach my $x (@{$idl}) { next if $x->{TYPE} ne "INTERFACE"; - # DCOM interfaces can be types as well - addType({ - NAME => $x->{NAME}, - TYPE => "TYPEDEF", - DATA => $x - }) if (has_property($x, "object")); - foreach my $y (@{$x->{DATA}}) { addType($y) if ( $y->{TYPE} eq "TYPEDEF" - or $y->{TYPE} eq "DECLARE"); + or $y->{TYPE} eq "DECLARE" + or $y->{TYPE} eq "UNION" + or $y->{TYPE} eq "STRUCT" + or $y->{TYPE} eq "ENUM" + or $y->{TYPE} eq "BITMAP"); } } } diff --git a/tools/pidl/lib/Parse/Pidl/Util.pm b/tools/pidl/lib/Parse/Pidl/Util.pm index 00185fbef7..8716094abd 100644 --- a/tools/pidl/lib/Parse/Pidl/Util.pm +++ b/tools/pidl/lib/Parse/Pidl/Util.pm @@ -15,9 +15,31 @@ use strict; use Parse::Pidl::Expr; use Parse::Pidl qw(error); -##################################################################### -# a dumper wrapper to prevent dependence on the Data::Dumper module -# unless we actually need it +=head1 NAME + +Parse::Pidl::Util - Generic utility functions for pidl + +=head1 SYNOPSIS + +use Parse::Pidl::Util; + +=head1 DESCRIPTION + +Simple module that contains a couple of trivial helper functions +used throughout the various pidl modules. + +=head1 FUNCTIONS + +=over 4 + +=cut + +=item B<MyDumper> +a dumper wrapper to prevent dependence on the Data::Dumper module +unless we actually need it + +=cut + sub MyDumper($) { require Data::Dumper; @@ -25,8 +47,10 @@ sub MyDumper($) return Data::Dumper::Dumper($s); } -##################################################################### -# see if a pidl property list contains a given property +=item B<has_property> +see if a pidl property list contains a given property + +=cut sub has_property($$) { my($e, $p) = @_; @@ -36,8 +60,10 @@ sub has_property($$) return $e->{PROPERTIES}->{$p}; } -##################################################################### -# see if a pidl property matches a value +=item B<property_matches> +see if a pidl property matches a value + +=cut sub property_matches($$$) { my($e,$p,$v) = @_; @@ -53,16 +79,22 @@ sub property_matches($$$) return undef; } -# return 1 if the string is a C constant +=item B<is_constant> +return 1 if the string is a C constant + +=cut sub is_constant($) { my $s = shift; - return 1 if (defined $s && $s =~ /^\d+$/); - return 1 if (defined $s && $s =~ /^0x[0-9A-Fa-f]+$/); + return 1 if ($s =~ /^\d+$/); + return 1 if ($s =~ /^0x[0-9A-Fa-f]+$/); return 0; } -# return a "" quoted string, unless already quoted +=item B<make_str> +return a "" quoted string, unless already quoted + +=cut sub make_str($) { my $str = shift; @@ -72,6 +104,10 @@ sub make_str($) return "\"$str\""; } +=item B<print_uuid> +Print C representation of a UUID. + +=cut sub print_uuid($) { my ($uuid) = @_; @@ -87,12 +123,14 @@ sub print_uuid($) "{".join(',', map {"0x$_"} @node)."}}"; } +=item B<ParseExpr> +Interpret an IDL expression, substituting particular variables. + +=cut sub ParseExpr($$$) { my($expr, $varlist, $e) = @_; - die("Undefined value in ParseExpr") if not defined($expr); - my $x = new Parse::Pidl::Expr(); return $x->Run($expr, sub { my $x = shift; error($e, $x); }, @@ -104,12 +142,15 @@ sub ParseExpr($$$) undef, undef); } +=item B<ParseExprExt> +Interpret an IDL expression, substituting particular variables. Can call +callbacks when pointers are being dereferenced or variables are being used. + +=cut sub ParseExprExt($$$$$) { my($expr, $varlist, $e, $deref, $use) = @_; - die("Undefined value in ParseExpr") if not defined($expr); - my $x = new Parse::Pidl::Expr(); return $x->Run($expr, sub { my $x = shift; error($e, $x); }, @@ -121,4 +162,8 @@ sub ParseExprExt($$$$$) $deref, $use); } +=back + +=cut + 1; diff --git a/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm b/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm index 4ad60319a6..9798c7c552 100644 --- a/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm +++ b/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm @@ -96,7 +96,7 @@ use vars qw($VERSION); $VERSION = '0.01'; @ISA = qw(Exporter); -@EXPORT_OK = qw(ReadConformance); +@EXPORT_OK = qw(ReadConformance ReadConformanceFH); use strict; @@ -157,7 +157,7 @@ sub handle_hf_rename($$$$) my ($pos,$data,$old,$new) = @_; unless(defined($new)) { - error($pos, "incomplete HF_RENAME command"); + warning($pos, "incomplete HF_RENAME command"); return; } @@ -253,6 +253,11 @@ sub handle_manual($$$) { my ($pos,$data,$fn) = @_; + unless(defined($fn)) { + warning($pos, "incomplete MANUAL command"); + return; + } + $data->{manual}->{$fn} = 1; } @@ -271,6 +276,11 @@ sub handle_fielddescription($$$$) { my ($pos,$data,$field,$desc) = @_; + unless(defined($desc)) { + warning($pos, "incomplete FIELD_DESCRIPTION command"); + return; + } + $data->{fielddescription}->{$field} = { DESCRIPTION => $desc, POS => $pos, @@ -314,16 +324,26 @@ my %field_handlers = ( sub ReadConformance($$) { my ($f,$data) = @_; + my $ret; - $data->{override} = ""; + open(IN,"<$f") or return undef; - my $incodeblock = 0; + $ret = ReadConformanceFH(*IN, $data, $f); - open(IN,"<$f") or return undef; + close(IN); + + return $ret; +} + +sub ReadConformanceFH($$$) +{ + my ($fh,$data,$f) = @_; + + my $incodeblock = 0; my $ln = 0; - foreach (<IN>) { + foreach (<$fh>) { $ln++; next if (/^#.*$/); next if (/^$/); @@ -337,7 +357,11 @@ sub ReadConformance($$) $incodeblock = 0; next; } elsif ($incodeblock) { - $data->{override}.="$_\n"; + if (exists $data->{override}) { + $data->{override}.="$_\n"; + } else { + $data->{override} = "$_\n"; + } next; } @@ -349,6 +373,8 @@ sub ReadConformance($$) my $pos = { FILE => $f, LINE => $ln }; + next unless(defined($cmd)); + if (not defined($field_handlers{$cmd})) { warning($pos, "Unknown command `$cmd'"); next; @@ -357,7 +383,13 @@ sub ReadConformance($$) $field_handlers{$cmd}($pos, $data, @fields); } - close(IN); + if ($incodeblock) { + warning({ FILE => $f, LINE => $ln }, + "Expecting CODE END"); + return undef; + } + + return 1; } 1; diff --git a/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm b/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm index 9415c16652..9ba6f2f3e0 100644 --- a/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm +++ b/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm @@ -2,7 +2,7 @@ # Samba4 NDR parser generator for IDL structures # Copyright tridge@samba.org 2000-2003 # Copyright tpot@samba.org 2001,2005 -# Copyright jelmer@samba.org 2004-2005 +# Copyright jelmer@samba.org 2004-2007 # Portions based on idl2eth.c by Ronnie Sahlberg # released under the GNU GPL @@ -16,19 +16,23 @@ Parse::Pidl::Wireshark::NDR - Parser generator for Wireshark package Parse::Pidl::Wireshark::NDR; +use Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(field2name @ett %res PrintIdl); + use strict; -use Parse::Pidl qw(error); +use Parse::Pidl qw(error warning); use Parse::Pidl::Typelist qw(getType); use Parse::Pidl::Util qw(has_property property_matches make_str); use Parse::Pidl::NDR qw(ContainsString GetNextLevel); -use Parse::Pidl::Dump qw(DumpTypedef DumpFunction); +use Parse::Pidl::Dump qw(DumpType DumpFunction); use Parse::Pidl::Wireshark::Conformance qw(ReadConformance); use File::Basename; use vars qw($VERSION); $VERSION = '0.01'; -my @ett; +our @ett; my %hf_used = (); my %return_types = (); @@ -66,7 +70,7 @@ sub field2name($) return $field; } -my %res = (); +our %res = (); my $tabs = ""; my $cur_fn = undef; sub pidl_fn_start($) @@ -108,7 +112,7 @@ sub deindent() sub PrintIdl($) { - my $idl = shift; + my ($idl) = @_; foreach (split /\n/, $idl) { pidl_code "/* IDL: $_ */"; @@ -123,7 +127,7 @@ sub Interface($) { my($interface) = @_; Const($_,$interface->{NAME}) foreach (@{$interface->{CONSTS}}); - Typedef($_,$interface->{NAME}) foreach (@{$interface->{TYPES}}); + Type($_, $_->{NAME}, $interface->{NAME}) foreach (@{$interface->{TYPES}}); Function($_,$interface->{NAME}) foreach (@{$interface->{FUNCTIONS}}); } @@ -633,18 +637,26 @@ sub Const($$) } } -sub Typedef($$) +sub Typedef($$$) { - my ($e,$ifname) = @_; + my ($e,$name,$ifname) = @_; - PrintIdl DumpTypedef($e->{ORIGINAL}); + Type($e->{DATA}, $name, $ifname); +} + +sub Type($$$) +{ + my ($e, $name, $ifname) = @_; + + PrintIdl DumpType($e->{ORIGINAL}); { ENUM => \&Enum, STRUCT => \&Struct, UNION => \&Union, - BITMAP => \&Bitmap - }->{$e->{DATA}->{TYPE}}->($e->{DATA}, $e->{NAME}, $ifname); + BITMAP => \&Bitmap, + TYPEDEF => \&Typedef + }->{$e->{TYPE}}->($e, $name, $ifname); } sub RegisterInterface($) @@ -918,7 +930,9 @@ sub Parse($$$$) $parser.=$res{ett}; $parser.=$res{hf}; $parser.=$res{def}; - $parser.=$conformance->{override}; + if (exists ($conformance->{override})) { + $parser.=$conformance->{override}; + } $parser.=$res{code}; my $header = "/* autogenerated by pidl */\n\n"; diff --git a/tools/pidl/pidl b/tools/pidl/pidl index 0bd841a5ff..b04e278902 100755 --- a/tools/pidl/pidl +++ b/tools/pidl/pidl @@ -17,7 +17,7 @@ pidl - An IDL compiler written in Perl pidl --help -pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=OUTPUT]] [<idlfile>.idl]... +pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--ndr-parser[=OUTPUT]] [--client] [--server] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=OUTPUT]] [<idlfile>.idl]... =head1 DESCRIPTION @@ -401,7 +401,6 @@ use Getopt::Long; use File::Basename; use Parse::Pidl; use Parse::Pidl::Util; -use Parse::Pidl::ODL; ##################################################################### # save a data structure into a file @@ -468,8 +467,6 @@ my($opt_ndr_parser); my($opt_tdr_parser); my($opt_ws_parser); my($opt_swig); -my($opt_dcom_proxy); -my($opt_com_header); my($opt_ejs); my($opt_quiet) = 0; my($opt_outputdir) = '.'; @@ -510,8 +507,6 @@ Samba 4 output: --swig[=OUTFILE] create swig wrapper file [BASENAME.i] --server[=OUTFILE] create server boilerplate [ndr_BASENAME_s.c] --template print a template for a pipe - --dcom-proxy[=OUTFILE] create DCOM proxy [ndr_BASENAME_p.c] - --com-header[=OUTFILE] create header for COM [com_BASENAME.h] Samba 3 output: --samba3-ndr-client[=OUTF] create client calls for Samba3 @@ -545,8 +540,6 @@ my $result = GetOptions ( 'ejs' => \$opt_ejs, 'diff' => \$opt_diff, 'swig:s' => \$opt_swig, - 'dcom-proxy:s' => \$opt_dcom_proxy, - 'com-header:s' => \$opt_com_header, 'quiet' => \$opt_quiet, 'verbose' => \$opt_verbose, 'warn-compat' => \$opt_warn_compat, @@ -602,31 +595,11 @@ sub process_file($) unlink($tempfile); } - my $comh_filename = ($opt_com_header or "$outputdir/com_$basename.h"); - if (defined($opt_com_header)) { - require Parse::Pidl::Samba4::COM::Header; - my $res = Parse::Pidl::Samba4::COM::Header::Parse($pidl,"$outputdir/ndr_$basename.h"); - if ($res) { - FileSave($comh_filename, $res); - } - } - - if (defined($opt_dcom_proxy)) { - require Parse::Pidl::Samba4::COM::Proxy; - my $res = Parse::Pidl::Samba4::COM::Proxy::Parse($pidl,$comh_filename); - if ($res) { - my ($client) = ($opt_dcom_proxy or "$outputdir/$basename\_p.c"); - FileSave($client, $res); - } - } - if ($opt_warn_compat) { require Parse::Pidl::Compat; Parse::Pidl::Compat::Check($pidl); } - $pidl = Parse::Pidl::ODL::ODL2IDL($pidl); - if (defined($opt_ws_parser) or defined($opt_client) or defined($opt_server) or defined($opt_ndr_parser) or defined($opt_ejs) or @@ -679,30 +652,8 @@ sub process_file($) if (defined($opt_server)) { require Parse::Pidl::Samba4::NDR::Server; - my $dcom = ""; - - foreach (@{$pidl}) { - next if ($_->{TYPE} ne "INTERFACE"); - - if (Parse::Pidl::Util::has_property($_, "object")) { - require Parse::Pidl::Samba4::COM::Stub; - $dcom .= Parse::Pidl::Samba4::COM::Stub::ParseInterface($_); - } - } FileSave(($opt_server or "$outputdir/ndr_$basename\_s.c"), Parse::Pidl::Samba4::NDR::Server::Parse($ndr,$h_filename)); - - if ($dcom ne "") { - $dcom = " -#include \"includes.h\" -#include \"$h_filename\" -#include \"rpc_server/dcerpc_server.h\" -#include \"rpc_server/common/common.h\" - -$dcom -"; - FileSave("$outputdir/$basename\_d.c", $dcom); - } } if (defined($opt_ndr_parser)) { diff --git a/tools/pidl/tests/Util.pm b/tools/pidl/tests/Util.pm index a406b868e1..a65cd89c55 100644 --- a/tools/pidl/tests/Util.pm +++ b/tools/pidl/tests/Util.pm @@ -91,7 +91,6 @@ SKIP: { my $cmd = "$cc $cflags -x c - -o $outfile $flags $ldflags"; $cmd =~ s/\n//g; - print "$cmd\n"; open CC, "|$cmd"; print CC "#define uint_t unsigned int\n"; print CC "#define _GNU_SOURCE\n"; diff --git a/tools/pidl/tests/dump.pl b/tools/pidl/tests/dump.pl new file mode 100755 index 0000000000..d1a56f0973 --- /dev/null +++ b/tools/pidl/tests/dump.pl @@ -0,0 +1,15 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU General Public License +use strict; +use warnings; + +use Test::More tests => 1; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Dump qw(DumpStruct); + +is (DumpStruct({ NAME => "foo", ELEMENTS => []}), + "struct foo {\n}"); + diff --git a/tools/pidl/tests/header.pl b/tools/pidl/tests/header.pl new file mode 100755 index 0000000000..3dae33ae6c --- /dev/null +++ b/tools/pidl/tests/header.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU General Public License +use strict; +use warnings; + +use Test::More tests => 10; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Util qw(MyDumper); +use Parse::Pidl::Samba4::Header; +use Parse::Pidl::IDL qw(parse_string); + +sub parse_idl($) +{ + my $text = shift; + my $idl = Parse::Pidl::IDL::parse_string($text, "nofile"); + return Parse::Pidl::Samba4::Header::Parse($idl); +} + +like(parse_idl(""), qr/\/\* header auto-generated by pidl \*\/\n/sm, "includes work"); +like(parse_idl("interface x {}"), qr/\/\* header auto-generated by pidl \*\/\n/sm, "simple empty interface doesn't cause overhead"); +like(parse_idl("interface p { typedef struct { int y; } x; };"), + qr/.*#ifndef _HEADER_p\n#define _HEADER_p\n.+\n#endif \/\* _HEADER_p \*\/.*/ms, "ifdefs are created"); +like(parse_idl("interface p { typedef struct { int y; } x; };"), + qr/struct x.*{.*int32_t y;.*}.*;/sm, "interface member generated properly"); +like(parse_idl("interface x { void foo (void); };"), + qr/struct foo.*{\s+int _dummy_element;\s+};/sm, "void fn contains dummy element"); +like(parse_idl("interface x { void foo ([in] uint32 x); };"), + qr/struct foo.*{\s+struct\s+{\s+uint32_t x;\s+} in;\s+};/sm, "fn in arg works"); +like(parse_idl("interface x { void foo ([out] uint32 x); };"), + qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} out;.*};/sm, "fn out arg works"); +like(parse_idl("interface x { void foo ([in,out] uint32 x); };"), + qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} in;\s+struct\s+{\s+uint32_t x;\s+} out;.*};/sm, "fn in,out arg works"); +like(parse_idl("interface x { void foo (uint32 x); };"), qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} in;\s+struct\s+{\s+uint32_t x;\s+} out;.*};/sm, "fn with no props implies in,out"); +like(parse_idl("interface p { struct x { int y; }; };"), + qr/struct x.*{.*int32_t y;.*}.*;/sm, "interface member generated properly"); diff --git a/tools/pidl/tests/ndr.pl b/tools/pidl/tests/ndr.pl index da22949c6d..26fb6c290b 100755 --- a/tools/pidl/tests/ndr.pl +++ b/tools/pidl/tests/ndr.pl @@ -4,7 +4,7 @@ use strict; use warnings; -use Test::More tests => 10; +use Test::More tests => 12; use FindBin qw($RealBin); use lib "$RealBin"; use Util; @@ -27,15 +27,13 @@ is_deeply(GetElementLevelTable($e), [ 'IS_DEFERRED' => 0, 'LEVEL_INDEX' => 0, 'DATA_TYPE' => 'uint8', - 'CONVERT_FROM' => undef, 'CONTAINS_DEFERRED' => 0, 'TYPE' => 'DATA', 'IS_SURROUNDING' => 0, - 'CONVERT_TO' => undef } ]); -my $ne = ParseElement($e); +my $ne = ParseElement($e, undef); is($ne->{ORIGINAL}, $e); is($ne->{NAME}, "v"); is($ne->{ALIGN}, 1); @@ -45,11 +43,9 @@ is_deeply($ne->{LEVELS}, [ 'IS_DEFERRED' => 0, 'LEVEL_INDEX' => 0, 'DATA_TYPE' => 'uint8', - 'CONVERT_FROM' => undef, 'CONTAINS_DEFERRED' => 0, 'TYPE' => 'DATA', 'IS_SURROUNDING' => 0, - 'CONVERT_TO' => undef } ]); @@ -77,11 +73,9 @@ is_deeply(GetElementLevelTable($e), [ 'IS_DEFERRED' => 1, 'LEVEL_INDEX' => 1, 'DATA_TYPE' => 'uint8', - 'CONVERT_FROM' => undef, 'CONTAINS_DEFERRED' => 0, 'TYPE' => 'DATA', 'IS_SURROUNDING' => 0, - 'CONVERT_TO' => undef } ]); @@ -117,11 +111,9 @@ is_deeply(GetElementLevelTable($e), [ 'IS_DEFERRED' => 1, 'LEVEL_INDEX' => 2, 'DATA_TYPE' => 'uint8', - 'CONVERT_FROM' => undef, 'CONTAINS_DEFERRED' => 0, 'TYPE' => 'DATA', 'IS_SURROUNDING' => 0, - 'CONVERT_TO' => undef } ]); @@ -149,11 +141,9 @@ is_deeply(GetElementLevelTable($e), [ 'IS_DEFERRED' => 1, 'LEVEL_INDEX' => 1, 'DATA_TYPE' => 'uint8', - 'CONVERT_FROM' => undef, 'CONTAINS_DEFERRED' => 0, 'TYPE' => 'DATA', 'IS_SURROUNDING' => 0, - 'CONVERT_TO' => undef } ]); @@ -182,10 +172,34 @@ is_deeply(GetElementLevelTable($e), [ 'IS_DEFERRED' => 0, 'LEVEL_INDEX' => 1, 'DATA_TYPE' => 'uint8', - 'CONVERT_FROM' => undef, 'CONTAINS_DEFERRED' => 0, 'TYPE' => 'DATA', 'IS_SURROUNDING' => 0, - 'CONVERT_TO' => undef } ]); + +# representation_type +$e = { + 'FILE' => 'foo.idl', + 'NAME' => 'v', + 'PROPERTIES' => { represent_as => "bar" }, + 'POINTERS' => 0, + 'TYPE' => 'uint8', + 'PARENT' => { TYPE => 'STRUCT' }, + 'LINE' => 42 }; + +$ne = ParseElement($e, undef); +is($ne->{REPRESENTATION_TYPE}, "bar"); + +# representation_type +$e = { + 'FILE' => 'foo.idl', + 'NAME' => 'v', + 'PROPERTIES' => { }, + 'POINTERS' => 0, + 'TYPE' => 'uint8', + 'PARENT' => { TYPE => 'STRUCT' }, + 'LINE' => 42 }; + +$ne = ParseElement($e, undef); +is($ne->{REPRESENTATION_TYPE}, "uint8"); diff --git a/tools/pidl/tests/ndr_deprecations.pl b/tools/pidl/tests/ndr_deprecations.pl index 89738e42f6..86828e5982 100755 --- a/tools/pidl/tests/ndr_deprecations.pl +++ b/tools/pidl/tests/ndr_deprecations.pl @@ -24,5 +24,3 @@ my $e = { test_warnings("foo.idl:42: subcontext() is deprecated. Use represent_as() or transmit_as() instead\n", sub { ValidElement($e); }); - - diff --git a/tools/pidl/tests/ndr_tagtype.pl b/tools/pidl/tests/ndr_tagtype.pl index a7f7d0490a..067fa096b4 100755 --- a/tools/pidl/tests/ndr_tagtype.pl +++ b/tools/pidl/tests/ndr_tagtype.pl @@ -8,15 +8,7 @@ use FindBin qw($RealBin); use lib "$RealBin"; use Util qw(test_samba4_ndr); -SKIP: { - skip "Tagged types without typedef are not supported yet", 8; - -test_samba4_ndr('struct-notypedef', -' - struct bla { - uint8 x; - }; -', +test_samba4_ndr('struct-notypedef', '[public] struct bla { uint8 x; }; ', ' struct ndr_push *ndr = ndr_push_init_ctx(NULL); struct bla r; @@ -33,5 +25,3 @@ test_samba4_ndr('struct-notypedef', if (!data_blob_equal(&result_blob, &expected_blob)) return 2; '); - -} diff --git a/tools/pidl/tests/parse_idl.pl b/tools/pidl/tests/parse_idl.pl index 859c2b4e46..265ac7a2bd 100755 --- a/tools/pidl/tests/parse_idl.pl +++ b/tools/pidl/tests/parse_idl.pl @@ -4,7 +4,7 @@ # Published under the GNU General Public License use strict; -use Test::More tests => 59 * 2; +use Test::More tests => 62 * 2; use FindBin qw($RealBin); use lib "$RealBin"; use Util qw(test_errors); @@ -83,8 +83,12 @@ testok "nested1", "interface test { struct x { struct { int a; } z; }; };"; testok "nested2", "interface test { struct x { struct y { int a; } z; }; };"; testok "bitmap1", "interface test { bitmap x { a=1 }; };"; testok "unsigned", "interface test { struct x { unsigned short y; }; };"; +testok "struct-property", "interface test { [public] struct x { short y; }; };"; testok "signed", "interface test { struct x { signed short y; }; };"; testok "declarg", "interface test { void test(struct { int x; } a); };"; +testok "structarg", "interface test { void test(struct a b); };"; +testfail "structargmissing", "interface test { void test(struct a); };", + "<structargmissing>:0: Syntax error near ')'\n"; testok "structqual", "interface test { struct x { struct y z; }; };"; testok "unionqual", "interface test { struct x { union y z; }; };"; testok "enumqual", "interface test { struct x { enum y z; }; };"; diff --git a/tools/pidl/tests/samba-ndr.pl b/tools/pidl/tests/samba-ndr.pl index a3e94bd8b5..1167f77aee 100755 --- a/tools/pidl/tests/samba-ndr.pl +++ b/tools/pidl/tests/samba-ndr.pl @@ -4,12 +4,14 @@ use strict; use warnings; -use Test::More tests => 10; +use Test::More tests => 34; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use Parse::Pidl::Util qw(MyDumper); -use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer); +use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer + GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv + EnvSubstituteValue NeededFunction NeededElement NeededType $res); my $output; sub print_fn($) { my $x = shift; $output.=$x; } @@ -133,3 +135,159 @@ test_warnings("nofile:2: unknown dereferenced expression `r->in.bla'\n", sub { $fn->("r->in.bla"); }); is($output, "if (r->in.bla == NULL) return;"); + +# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work +$fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionOutEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] }; +is_deeply({ }, GenerateFunctionInEnv($fn)); + +$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; +is_deeply({ foo => "r->foo", bar => "r->bar", this => "r" }, + GenerateStructEnv($fn, "r")); + +$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; +is_deeply({ foo => "some->complex.variable->foo", + bar => "some->complex.variable->bar", + this => "some->complex.variable" }, + GenerateStructEnv($fn, "some->complex.variable")); + +$fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 3 }} ] }; + +my $env = GenerateStructEnv($fn, "r"); +EnvSubstituteValue($env, $fn); +is_deeply($env, { foo => 3, this => "r" }); + +$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; +$env = GenerateStructEnv($fn, "r"); +EnvSubstituteValue($env, $fn); +is_deeply($env, { foo => 'r->foo', bar => 'r->bar', this => "r" }); + +$fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 0 }} ] }; + +$env = GenerateStructEnv($fn, "r"); +EnvSubstituteValue($env, $fn); +is_deeply($env, { foo => 0, this => "r" }); + +my $needed = {}; +NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed); +is_deeply($needed, { pull_foo => 1 }); + +# old settings should be kept +$needed = { pull_foo => 0 }; +NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed); +is_deeply($needed, { pull_foo => 0 }); + +# print/pull/push are independent of each other +$needed = { pull_foo => 0 }; +NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "print", $needed); +is_deeply($needed, { pull_foo => 0, print_foo => 1 }); + +$needed = { }; +NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] }, $needed); +is_deeply($needed, { pull_foo => 1, print_foo => 1, push_foo => 1, + pull_bar => 1, print_bar => 1, push_bar => 1}); + +# push/pull/print are always set for functions +$needed = { pull_foo => 0 }; +NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] }, $needed); +is_deeply($needed, { pull_foo => 1, print_foo => 1, push_foo => 1, + pull_bar => 1, push_bar => 1, print_bar => 1}); + +# public structs are always needed +$needed = {}; +NeededType({ NAME => "bla", DATA => { TYPE => "STRUCT", ELEMENTS => [] } }, + $needed); +is_deeply($needed, { }); + +$needed = {}; +NeededType({ PROPERTIES => { public => 1 }, NAME => "bla", + DATA => { TYPE => "STRUCT", ELEMENTS => [] } }, + $needed); +is_deeply($needed, { pull_bla => 1, print_bla => 1, push_bla => 1 }); + +# make sure types for elements are set too +$needed = {}; +NeededType({ PROPERTIES => { public => 1 }, NAME => "bla", + DATA => { TYPE => "STRUCT", + ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } }, + $needed); +is_deeply($needed, { pull_bla => 1, print_bla => 1, push_bla => 1, + pull_bar => 1, print_bar => 1, push_bar => 1}); + +$needed = {}; +NeededType({ PROPERTIES => { gensize => 1}, NAME => "bla", + DATA => { TYPE => "STRUCT", + ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } }, + $needed); +is_deeply($needed, { ndr_size_bla => 1 }); + +# make sure types for elements are set too +$needed = { pull_bla => 1 }; +NeededType({ NAME => "bla", + DATA => { TYPE => "STRUCT", + ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } }, + $needed); +is_deeply($needed, { pull_bla => 1, pull_bar => 1 }); + +$needed = {}; +NeededType({ PROPERTIES => { public => 1}, + NAME => "bla", + DATA => { TYPE => "STRUCT", + ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "rep" } ] } }, + $needed); +is_deeply($needed, { pull_bla => 1, push_bla => 1, print_bla => 1, print_rep => 1, + pull_bar => 1, push_bar => 1, + ndr_bar_to_rep => 1, ndr_rep_to_bar => 1}); + +$res = ""; +Parse::Pidl::Samba4::NDR::Parser::ParseStructPush({ + NAME => "mystruct", + TYPE => "STRUCT", + PROPERTIES => {}, + ALIGN => 4, + ELEMENTS => [ ]}, "x"); +is($res, "if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); +} +if (ndr_flags & NDR_BUFFERS) { +} +"); + +$res = ""; +my $e = { + NAME => "el1", + TYPE => "mytype", + REPRESENTATION_TYPE => "mytype", + PROPERTIES => {}, + LEVELS => [ + { LEVEL_INDEX => 0, TYPE => "DATA", DATA_TYPE => "mytype" } +] }; +Parse::Pidl::Samba4::NDR::Parser::ParseStructPush({ + NAME => "mystruct", + TYPE => "STRUCT", + PROPERTIES => {}, + ALIGN => 4, + SURROUNDING_ELEMENT => $e, + ELEMENTS => [ $e ]}, "x"); +is($res, "if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, x->el1))); + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_mytype(ndr, NDR_SCALARS, &x->el1)); +} +if (ndr_flags & NDR_BUFFERS) { +} +"); diff --git a/tools/pidl/tests/samba3-cli.pl b/tools/pidl/tests/samba3-cli.pl new file mode 100755 index 0000000000..1d1bae8550 --- /dev/null +++ b/tools/pidl/tests/samba3-cli.pl @@ -0,0 +1,56 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU General Public License +use strict; +use warnings; + +use Test::More tests => 4; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Util qw(MyDumper); +use Parse::Pidl::Samba3::ClientNDR qw(GenerateFunctionInEnv ParseFunction $res + $res_hdr); + +# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work +my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionInEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionInEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] }; +is_deeply({ }, GenerateFunctionInEnv($fn)); + +$fn = { NAME => "bar", ELEMENTS => [ ] }; +ParseFunction("foo", $fn); +is($res, "NTSTATUS rpccli_bar(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx) +{ +\tstruct bar r; +\tNTSTATUS status; +\t +\t/* In parameters */ +\t +\tif (DEBUGLEVEL >= 10) +\t\tNDR_PRINT_IN_DEBUG(bar, &r); +\t +\tstatus = cli_do_rpc_ndr(cli, mem_ctx, PI_foo, DCERPC_BAR, &r, (ndr_pull_flags_fn_t)ndr_pull_bar, (ndr_push_flags_fn_t)ndr_push_bar); +\t +\tif (!NT_STATUS_IS_OK(status)) { +\t\treturn status; +\t} +\t +\tif (DEBUGLEVEL >= 10) +\t\tNDR_PRINT_OUT_DEBUG(bar, &r); +\t +\tif (NT_STATUS_IS_ERR(status)) { +\t\treturn status; +\t} +\t +\t/* Return variables */ +\t +\t/* Return result */ +\treturn NT_STATUS_OK; +} + +"); diff --git a/tools/pidl/tests/tdr.pl b/tools/pidl/tests/tdr.pl new file mode 100755 index 0000000000..35e54f53fc --- /dev/null +++ b/tools/pidl/tests/tdr.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU General Public License +use strict; +use warnings; + +use Test::More tests => 6; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Samba4::TDR qw($ret $ret_hdr ParserType); + +ParserType({TYPE => "STRUCT", NAME => "foo", PROPERTIES => {public => 1}}, "pull"); +is($ret, "NTSTATUS tdr_pull_foo (struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, struct foo *v) +{ + return NT_STATUS_OK; +} + +"); +is($ret_hdr, "NTSTATUS tdr_pull_foo (struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, struct foo *v);\n"); + +$ret = ""; $ret_hdr = ""; + +ParserType({TYPE => "UNION", NAME => "bar", PROPERTIES => {public => 1}}, "pull"); +is($ret, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v) +{ + switch (level) { + } + return NT_STATUS_OK; + +} + +"); +is($ret_hdr, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v);\n"); + +$ret = ""; $ret_hdr = ""; + +ParserType({TYPE => "UNION", NAME => "bar", PROPERTIES => {}}, "pull"); +is($ret, "static NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v) +{ + switch (level) { + } + return NT_STATUS_OK; + +} + +"); +is($ret_hdr, ""); diff --git a/tools/pidl/tests/typelist.pl b/tools/pidl/tests/typelist.pl new file mode 100755 index 0000000000..5c1a7ddd21 --- /dev/null +++ b/tools/pidl/tests/typelist.pl @@ -0,0 +1,59 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU General Public License +use strict; +use warnings; + +use Test::More tests => 33; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Typelist qw(hasType getType mapTypeName expandAlias + mapScalarType addType typeIs is_scalar scalar_is_reference + enum_type_fn bitmap_type_fn mapType); + +is("foo", expandAlias("foo")); +is("uint32", expandAlias("DWORD")); +is("int32", expandAlias("int")); +is("", expandAlias("")); +is("int32", expandAlias("int32")); + +is("uint32_t", mapScalarType("uint32")); +is("void", mapScalarType("void")); +is("uint64_t", mapScalarType("hyper")); + +my $x = { TYPE => "ENUM", NAME => "foo" }; +addType($x); +is($x, getType("foo")); +is(undef, getType("bloebla")); + +is(0, typeIs("someUnknownType", "ENUM")); + +is(1, hasType("foo")); +is(0, hasType("nonexistant")); + +is(1, is_scalar("uint32")); +is(0, is_scalar("nonexistant")); + +is(1, scalar_is_reference("string")); +is(0, scalar_is_reference("uint32")); + +is("uint8", enum_type_fn({TYPE => "ENUM", PARENT=>{PROPERTIES => {enum8bit => 1}}})); +is("uint32", enum_type_fn({TYPE => "ENUM", PARENT=>{PROPERTIES => {v1_enum => 1}}})); +is("uint16", enum_type_fn({TYPE => "ENUM", PARENT=>{PROPERTIES => {}}})); + +is("uint8", bitmap_type_fn({TYPE => "BITMAP", PROPERTIES => {bitmap8bit => 1}})); +is("uint16", bitmap_type_fn({TYPE => "BITMAP", PROPERTIES => {bitmap16bit => 1}})); +is("hyper", bitmap_type_fn({TYPE => "BITMAP", PROPERTIES => {bitmap64bit => 1}})); +is("uint32", bitmap_type_fn({TYPE => "BITMAP", PROPERTIES => {}})); + +is("enum foo", mapType({TYPE => "ENUM"}, "foo")); +is("union foo", mapType({TYPE => "UNION"}, "foo")); +is("struct foo", mapType({TYPE => "STRUCT"}, "foo")); +is("uint8_t", mapType({TYPE => "BITMAP", PROPERTIES => {bitmap8bit => 1}}, "foo")); +is("uint8_t", mapType({TYPE => "SCALAR"}, "uint8")); +is("uint32_t", mapType({TYPE => "TYPEDEF", DATA => {TYPE => "SCALAR"}}, "uint32")); + +is("void", mapTypeName(undef)); +is("uint32_t", mapTypeName("uint32")); +is("int32_t", mapTypeName("int")); diff --git a/tools/pidl/tests/wireshark-conf.pl b/tools/pidl/tests/wireshark-conf.pl new file mode 100755 index 0000000000..8601a91ed9 --- /dev/null +++ b/tools/pidl/tests/wireshark-conf.pl @@ -0,0 +1,62 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU General Public License +# test parsing wireshark conformance files +use strict; +use warnings; + +use Test::More tests => 20; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Util qw(MyDumper); +use Parse::Pidl::Wireshark::Conformance qw(ReadConformanceFH); + +sub parse_conf($) +{ + my $str = shift; + open(TMP, "+>", undef) or die("unable to open temp file"); + print TMP $str; + seek(TMP, 0, 0); + my $data = {}; + ReadConformanceFH(*TMP, $data, "nofile") or return undef; + close(TMP); + return $data; +} + +ok(parse_conf("\n"), undef); +ok(parse_conf(" \n"), undef); +ok(parse_conf("CODE START\nCODE END\n")); +test_warnings("nofile:1: Expecting CODE END\n", sub { is(parse_conf("CODE START\n"), undef); }); +ok(parse_conf("#foobar\n"), undef); +test_warnings("nofile:1: Unknown command `foobar'\n", + sub { ok(parse_conf("foobar\n"), undef); }); + +test_warnings("nofile:1: incomplete HF_RENAME command\n", + sub { parse_conf("HF_RENAME\n"); }); + + +is_deeply(parse_conf("HF_RENAME foo bar\n")->{hf_renames}->{foo}, + { OLDNAME => "foo", NEWNAME => "bar", POS => {FILE => "nofile", LINE => 1}, USED => 0}); + +is_deeply(parse_conf("NOEMIT\n"), { "noemit_dissector" => 1 }); +is_deeply(parse_conf("NOEMIT foo\n"), { "noemit" => { "foo" => 1 } }); + +test_warnings("nofile:1: incomplete MANUAL command\n", + sub { parse_conf("MANUAL\n"); } ); + +is_deeply(parse_conf("MANUAL foo\n"), { manual => {foo => 1}}); + +test_warnings("nofile:1: incomplete FIELD_DESCRIPTION command\n", + sub { parse_conf("FIELD_DESCRIPTION foo\n"); }); + +is_deeply(parse_conf("FIELD_DESCRIPTION foo \"my description\"\n"), + { fielddescription => { foo => { DESCRIPTION => "\"my description\"", POS => { FILE => "nofile", LINE => 1}, USED => 0 }}}); + +is_deeply(parse_conf("FIELD_DESCRIPTION foo my description\n"), + { fielddescription => { foo => { DESCRIPTION => "my", POS => { FILE => "nofile", LINE => 1}, USED => 0 }}}); + +is_deeply(parse_conf("CODE START\ndata\nCODE END\n"), { override => "data\n" }); +is_deeply(parse_conf("CODE START\ndata\nmore data\nCODE END\n"), { override => "data\nmore data\n" }); +test_warnings("nofile:1: Unknown command `CODE'\n", + sub { parse_conf("CODE END\n"); } ); diff --git a/tools/pidl/tests/wireshark-ndr.pl b/tools/pidl/tests/wireshark-ndr.pl new file mode 100755 index 0000000000..574060f8ea --- /dev/null +++ b/tools/pidl/tests/wireshark-ndr.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU General Public License +# test parsing wireshark conformance files +use strict; +use warnings; + +use Test::More tests => 3; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Util qw(MyDumper); +use Parse::Pidl::Wireshark::NDR qw(field2name %res PrintIdl); + +is("Access Mask", field2name("access_mask")); +is("Accessmask", field2name("AccessMask")); + +$res{code} = ""; +PrintIdl("foo\nbar\n"); +is("/* IDL: foo */ +/* IDL: bar */ + +", $res{code}); |