diff options
author | Ronnie Sahlberg <ronnie_sahlberg@ozemail.com.au> | 2009-07-28 13:38:46 +0000 |
---|---|---|
committer | Ronnie Sahlberg <ronnie_sahlberg@ozemail.com.au> | 2009-07-28 13:38:46 +0000 |
commit | ad5682dc8ccb570203dbb929e601655a1d191ea8 (patch) | |
tree | bb3a2cf85e9f4ebe7ecf79e7a95562af1129a1d1 /tools/pidl | |
parent | f8cf2d2c838b8fa318dce0f47a0b79c314c16783 (diff) |
update pidl to the newest version from samba
svn path=/trunk/; revision=29214
Diffstat (limited to 'tools/pidl')
39 files changed, 3112 insertions, 2268 deletions
diff --git a/tools/pidl/MANIFEST b/tools/pidl/MANIFEST index 7f30c3ab54..8eb4d22d5b 100644 --- a/tools/pidl/MANIFEST +++ b/tools/pidl/MANIFEST @@ -22,10 +22,8 @@ lib/Parse/Pidl/Samba4/NDR/Server.pm lib/Parse/Pidl/Samba4/NDR/Parser.pm lib/Parse/Pidl/Samba4/NDR/Client.pm lib/Parse/Pidl/Samba4/Header.pm -lib/Parse/Pidl/Samba4/SWIG.pm lib/Parse/Pidl/Samba4/TDR.pm lib/Parse/Pidl/Samba4/Template.pm -lib/Parse/Pidl/Samba4/EJS.pm lib/Parse/Pidl/Samba4.pm lib/Parse/Pidl/Wireshark/Conformance.pm lib/Parse/Pidl/Wireshark/NDR.pm @@ -40,4 +38,4 @@ idl.yp TODO README pidl -META.yml Module meta-data (added by MakeMaker) +META.yml diff --git a/tools/pidl/README b/tools/pidl/README index 5bf7752da9..c6b7e11792 100644 --- a/tools/pidl/README +++ b/tools/pidl/README @@ -3,8 +3,9 @@ Introduction: This directory contains the source code of the pidl (Perl IDL) compiler for Samba 4. -The main sources for pidl are available by Subversion on -svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/pidl +The main sources for pidl are available using Git as part of +the combined Samba 3 / Samba 4 tree. Use: +git clone git://git.samba.org/samba.git Pidl works by building a parse tree from a .pidl file (a simple dump of it's internal parse tree) or a .idl file @@ -34,12 +35,11 @@ Parse::Pidl::Test - Utility functions for use in pidl's testsuite -- Samba NDR -- Parse::Pidl::Samba4::NDR::Client - Generates client call functions in C using the NDR parser -Parse::Pidl::Samba4::SWIG - Generates SWIG interface files (.i) Parse::Pidl::Samba4::NDR::Parser - Generates pull/push functions for parsing NDR Parse::Pidl::Samba4::NDR::Server - Generates server side implementation in C Parse::Pidl::Samba4::TDR - Parser generator for the "Trivial Data Representation" Parse::Pidl::Samba4::Template - Generates stubs in C for server implementation -Parse::Pidl::Samba4::EJS - Generates bindings for Embedded JavaScript (EJS) +Parse::Pidl::Samba4::Python - Generates bindings for Python -- Samba COM / DCOM -- Parse::Pidl::Samba4::COM::Proxy - Generates proxy object for DCOM (client-side) diff --git a/tools/pidl/TODO b/tools/pidl/TODO index 487d51d11e..87ae0c5fd3 100644 --- a/tools/pidl/TODO +++ b/tools/pidl/TODO @@ -1,12 +1,10 @@ -- EJS output backend shouldn't use the NDR levels stuff but instead - as the "C levels" and NDR levels don't necessarily match. +- warn when union instances don't have a discriminant - true multiple dimension array / strings in arrays support - compatibility mode for generating MIDL-readable data: - strip out pidl-specific properties -- remove declare in favor of typedef - make bitmap an optional attribute on enum - support nested elements - support typedefs properly (e.g. allow "typedef void **bla;") @@ -32,3 +30,15 @@ - remove NDR_AUTO_REF_ALLOC flag - automatic test generator based on IDL pointer types + +- support converting structs to tuples in Python rather than objects +- convert structs with a single mattering member to that member directly, e.g.: + struct bar { + int size; + [size_is(size)] uint32 *array; + }; + + should be converted to an array of uint32's + +- python: fill in size members automatically in some places if the struct isn't being returned + (so we don't have to cope with the array growing) diff --git a/tools/pidl/idl.yp b/tools/pidl/idl.yp index c372569a75..d557590494 100644 --- a/tools/pidl/idl.yp +++ b/tools/pidl/idl.yp @@ -1,7 +1,7 @@ ######################## # IDL Parse::Yapp parser # Copyright (C) Andrew Tridgell <tridge@samba.org> -# released under the GNU GPL version 2 or later +# released under the GNU GPL version 3 or later @@ -67,17 +67,24 @@ interface_names: | interface_names 'interface' identifier ';' { push(@{$_[1]}, $_[2]); $_[1] } ; -interface: property_list 'interface' identifier '{' definitions '}' optional_semicolon +interface: property_list 'interface' identifier base_interface '{' definitions '}' optional_semicolon {{ "TYPE" => "INTERFACE", "PROPERTIES" => $_[1], "NAME" => $_[3], - "DATA" => $_[5], + "BASE" => $_[4], + "DATA" => $_[6], "FILE" => $_[0]->YYData->{FILE}, "LINE" => $_[0]->YYData->{LINE}, }} ; +base_interface: + #empty + | ':' identifier { $_[2] } +; + + cpp_quote: 'cpp_quote' '(' text ')' {{ "TYPE" => "CPP_QUOTE", @@ -93,7 +100,7 @@ definitions: ; -definition: function | const | typedef | declare | typedecl +definition: function | const | typedef | typedecl ; const: 'const' identifier pointers identifier '=' anytext ';' @@ -132,40 +139,6 @@ function: property_list type identifier '(' element_list2 ')' ';' }} ; -declare: 'declare' decl_type identifier';' - {{ - "TYPE" => "DECLARE", - "NAME" => $_[3], - "DATA" => $_[2], - "FILE" => $_[0]->YYData->{FILE}, - "LINE" => $_[0]->YYData->{LINE}, - }} -; - -decl_type: decl_enum | decl_bitmap | decl_union -; - -decl_enum: property_list 'enum' - {{ - "TYPE" => "ENUM", - "PROPERTIES" => $_[1] - }} -; - -decl_bitmap: property_list 'bitmap' - {{ - "TYPE" => "BITMAP", - "PROPERTIES" => $_[1] - }} -; - -decl_union: property_list 'union' - {{ - "TYPE" => "UNION", - "PROPERTIES" => $_[1] - }} -; - typedef: property_list 'typedef' type identifier array_len ';' {{ "TYPE" => "TYPEDEF", @@ -303,11 +276,16 @@ element_list1: | element_list1 base_element ';' { push(@{$_[1]}, $_[2]); $_[1] } ; +optional_const: + #empty + | 'const' +; + element_list2: #empty | 'void' - | base_element { [ $_[1] ] } - | element_list2 ',' base_element { push(@{$_[1]}, $_[3]); $_[1] } + | optional_const base_element { [ $_[2] ] } + | element_list2 ',' optional_const base_element { push(@{$_[1]}, $_[4]); $_[1] } ; array_len: @@ -327,12 +305,7 @@ properties: property { $_[1] } ; property: identifier {{ "$_[1]" => "1" }} - | identifier '(' listtext ')' {{ "$_[1]" => "$_[3]" }} -; - -listtext: - anytext - | listtext ',' anytext { "$_[1] $_[3]" } + | identifier '(' commalisttext ')' {{ "$_[1]" => "$_[3]" }} ; commalisttext: @@ -430,7 +403,7 @@ sub _Error { error($_[0]->YYData, $_[0]->YYData->{ERRMSG}); delete $_[0]->YYData->{ERRMSG}; return; - }; + } my $last_token = $_[0]->YYData->{LAST_TOKEN}; error($_[0]->YYData, "Syntax error near '$last_token'"); @@ -476,7 +449,7 @@ again: if (s/^([\w_]+)//) { $parser->YYData->{LAST_TOKEN} = $1; if ($1 =~ - /^(coclass|interface|const|typedef|declare|union|cpp_quote + /^(coclass|interface|const|typedef|union|cpp_quote |struct|enum|bitmap|void|unsigned|signed|import|include |importlib)$/x) { return $1; diff --git a/tools/pidl/lib/Parse/Pidl.pm b/tools/pidl/lib/Parse/Pidl.pm index 0c6e0e5727..40e3673908 100644 --- a/tools/pidl/lib/Parse/Pidl.pm +++ b/tools/pidl/lib/Parse/Pidl.pm @@ -9,7 +9,7 @@ package Parse::Pidl; require Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(warning error fatal); +@EXPORT_OK = qw(warning error fatal $VERSION); use strict; @@ -20,13 +20,19 @@ $VERSION = '0.02'; sub warning { my ($l,$m) = @_; - print STDERR "$l->{FILE}:$l->{LINE}: warning: $m\n"; + if ($l) { + print STDERR "$l->{FILE}:$l->{LINE}: "; + } + print STDERR "warning: $m\n"; } sub error { my ($l,$m) = @_; - print STDERR "$l->{FILE}:$l->{LINE}: error: $m\n"; + if ($l) { + print STDERR "$l->{FILE}:$l->{LINE}: "; + } + print STDERR "error: $m\n"; } sub fatal($$) diff --git a/tools/pidl/lib/Parse/Pidl/Compat.pm b/tools/pidl/lib/Parse/Pidl/Compat.pm index f1241ef341..1b49c439c4 100644 --- a/tools/pidl/lib/Parse/Pidl/Compat.pm +++ b/tools/pidl/lib/Parse/Pidl/Compat.pm @@ -44,7 +44,6 @@ my %supported_properties = ( "nopush" => ["FUNCTION", "TYPEDEF"], "nopull" => ["FUNCTION", "TYPEDEF"], "noprint" => ["FUNCTION", "TYPEDEF"], - "noejs" => ["FUNCTION", "TYPEDEF"], # union "switch_is" => ["ELEMENT"], @@ -148,17 +147,6 @@ sub CheckInterface($) { my $if = shift; - if (has_property($if, "pointer_default_top") and - $if->{PROPERTIES}->{pointer_default_top} ne "ref") { - warning($if, "pointer_default_top() is pidl-specific"); - } - - foreach my $x (@{$if->{DATA}}) { - if ($x->{TYPE} eq "DECLARE") { - warning($if, "the declare keyword is pidl-specific"); - next; - } - } } sub Check($) diff --git a/tools/pidl/lib/Parse/Pidl/Expr.pm b/tools/pidl/lib/Parse/Pidl/Expr.pm index 4e02be0575..5524374fae 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 "pidl/expr.yp" +#line 22 "./pidl/expr.yp" { "\"$_[1]\"" } ], [#Rule 3 @@ -1139,199 +1139,199 @@ sub [#Rule 5 'exp', 2, sub -#line 25 "pidl/expr.yp" +#line 25 "./pidl/expr.yp" { "~$_[2]" } ], [#Rule 6 'exp', 3, sub -#line 26 "pidl/expr.yp" +#line 26 "./pidl/expr.yp" { "$_[1] + $_[3]" } ], [#Rule 7 'exp', 3, sub -#line 27 "pidl/expr.yp" +#line 27 "./pidl/expr.yp" { "$_[1] - $_[3]" } ], [#Rule 8 'exp', 3, sub -#line 28 "pidl/expr.yp" +#line 28 "./pidl/expr.yp" { "$_[1] * $_[3]" } ], [#Rule 9 'exp', 3, sub -#line 29 "pidl/expr.yp" +#line 29 "./pidl/expr.yp" { "$_[1] % $_[3]" } ], [#Rule 10 'exp', 3, sub -#line 30 "pidl/expr.yp" +#line 30 "./pidl/expr.yp" { "$_[1] < $_[3]" } ], [#Rule 11 'exp', 3, sub -#line 31 "pidl/expr.yp" +#line 31 "./pidl/expr.yp" { "$_[1] > $_[3]" } ], [#Rule 12 'exp', 3, sub -#line 32 "pidl/expr.yp" +#line 32 "./pidl/expr.yp" { "$_[1] | $_[3]" } ], [#Rule 13 'exp', 3, sub -#line 33 "pidl/expr.yp" +#line 33 "./pidl/expr.yp" { "$_[1] == $_[3]" } ], [#Rule 14 'exp', 3, sub -#line 34 "pidl/expr.yp" +#line 34 "./pidl/expr.yp" { "$_[1] <= $_[3]" } ], [#Rule 15 'exp', 3, sub -#line 35 "pidl/expr.yp" +#line 35 "./pidl/expr.yp" { "$_[1] => $_[3]" } ], [#Rule 16 'exp', 3, sub -#line 36 "pidl/expr.yp" +#line 36 "./pidl/expr.yp" { "$_[1] << $_[3]" } ], [#Rule 17 'exp', 3, sub -#line 37 "pidl/expr.yp" +#line 37 "./pidl/expr.yp" { "$_[1] >> $_[3]" } ], [#Rule 18 'exp', 3, sub -#line 38 "pidl/expr.yp" +#line 38 "./pidl/expr.yp" { "$_[1] != $_[3]" } ], [#Rule 19 'exp', 3, sub -#line 39 "pidl/expr.yp" +#line 39 "./pidl/expr.yp" { "$_[1] || $_[3]" } ], [#Rule 20 'exp', 3, sub -#line 40 "pidl/expr.yp" +#line 40 "./pidl/expr.yp" { "$_[1] && $_[3]" } ], [#Rule 21 'exp', 3, sub -#line 41 "pidl/expr.yp" +#line 41 "./pidl/expr.yp" { "$_[1] & $_[3]" } ], [#Rule 22 'exp', 5, sub -#line 42 "pidl/expr.yp" +#line 42 "./pidl/expr.yp" { "$_[1]?$_[3]:$_[5]" } ], [#Rule 23 'exp', 2, sub -#line 43 "pidl/expr.yp" +#line 43 "./pidl/expr.yp" { "~$_[1]" } ], [#Rule 24 'exp', 2, sub -#line 44 "pidl/expr.yp" +#line 44 "./pidl/expr.yp" { "not $_[1]" } ], [#Rule 25 'exp', 3, sub -#line 45 "pidl/expr.yp" +#line 45 "./pidl/expr.yp" { "$_[1] / $_[3]" } ], [#Rule 26 'exp', 2, sub -#line 46 "pidl/expr.yp" +#line 46 "./pidl/expr.yp" { "-$_[2]" } ], [#Rule 27 'exp', 2, sub -#line 47 "pidl/expr.yp" +#line 47 "./pidl/expr.yp" { "&$_[2]" } ], [#Rule 28 'exp', 3, sub -#line 48 "pidl/expr.yp" +#line 48 "./pidl/expr.yp" { "$_[1]^$_[3]" } ], [#Rule 29 'exp', 3, sub -#line 49 "pidl/expr.yp" +#line 49 "./pidl/expr.yp" { "($_[2])" } ], [#Rule 30 'possible_pointer', 1, sub -#line 53 "pidl/expr.yp" +#line 53 "./pidl/expr.yp" { $_[0]->_Lookup($_[1]) } ], [#Rule 31 'possible_pointer', 2, sub -#line 54 "pidl/expr.yp" +#line 54 "./pidl/expr.yp" { $_[0]->_Dereference($_[2]); "*$_[2]" } ], [#Rule 32 'var', 1, sub -#line 57 "pidl/expr.yp" +#line 57 "./pidl/expr.yp" { $_[0]->_Use($_[1]) } ], [#Rule 33 'var', 3, sub -#line 58 "pidl/expr.yp" +#line 58 "./pidl/expr.yp" { $_[0]->_Use("$_[1].$_[3]") } ], [#Rule 34 'var', 3, sub -#line 59 "pidl/expr.yp" +#line 59 "./pidl/expr.yp" { "($_[2])" } ], [#Rule 35 'var', 3, sub -#line 60 "pidl/expr.yp" +#line 60 "./pidl/expr.yp" { $_[0]->_Use("*$_[1]"); $_[1]."->".$_[3] } ], [#Rule 36 'func', 4, sub -#line 64 "pidl/expr.yp" +#line 64 "./pidl/expr.yp" { "$_[1]($_[3])" } ], [#Rule 37 'opt_args', 0, sub -#line 65 "pidl/expr.yp" +#line 65 "./pidl/expr.yp" { "" } ], [#Rule 38 @@ -1349,7 +1349,7 @@ sub [#Rule 42 'args', 3, sub -#line 68 "pidl/expr.yp" +#line 68 "./pidl/expr.yp" { "$_[1], $_[3]" } ] ], @@ -1357,7 +1357,7 @@ sub bless($self,$class); } -#line 71 "pidl/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 e9155e4e00..06d54fb4b5 100644 --- a/tools/pidl/lib/Parse/Pidl/IDL.pm +++ b/tools/pidl/lib/Parse/Pidl/IDL.pm @@ -38,7 +38,7 @@ sub new { "import" => 7, "include" => 13 }, - DEFAULT => -91, + DEFAULT => -85, GOTOS => { 'cpp_quote' => 11, 'importlib' => 10, @@ -124,7 +124,7 @@ sub new { } }, {#State 16 - DEFAULT => -124 + DEFAULT => -116 }, {#State 17 DEFAULT => -11 @@ -184,7 +184,7 @@ sub new { } }, {#State 26 - DEFAULT => -120 + DEFAULT => -112 }, {#State 27 ACTIONS => { @@ -193,23 +193,27 @@ sub new { }, {#State 28 ACTIONS => { - "{" => 37 + ":" => 37 + }, + DEFAULT => -17, + GOTOS => { + 'base_interface' => 38 } }, {#State 29 ACTIONS => { - "," => 38, - "]" => 39 + "," => 39, + "]" => 40 } }, {#State 30 ACTIONS => { - "(" => 40 + "(" => 41 }, - DEFAULT => -95 + DEFAULT => -89 }, {#State 31 - DEFAULT => -93 + DEFAULT => -87 }, {#State 32 DEFAULT => -8 @@ -218,7 +222,7 @@ sub new { DEFAULT => -9 }, {#State 34 - DEFAULT => -17 + DEFAULT => -19 }, {#State 35 DEFAULT => -12 @@ -226,1570 +230,1473 @@ sub new { {#State 36 DEFAULT => -14, GOTOS => { - 'interface_names' => 41 + 'interface_names' => 42 } }, {#State 37 ACTIONS => { - "declare" => 49, - "const" => 53 + 'IDENTIFIER' => 26 }, - DEFAULT => -91, GOTOS => { - 'typedecl' => 42, - 'function' => 43, - 'definitions' => 45, - 'bitmap' => 44, - 'definition' => 48, - 'property_list' => 47, - 'usertype' => 46, - 'const' => 52, - 'declare' => 51, - 'struct' => 50, - 'typedef' => 55, - 'enum' => 54, - 'union' => 56 + 'identifier' => 43 } }, {#State 38 ACTIONS => { + "{" => 44 + } + }, + {#State 39 + ACTIONS => { 'IDENTIFIER' => 26 }, GOTOS => { 'identifier' => 30, - 'property' => 57 + 'property' => 45 } }, - {#State 39 - DEFAULT => -92 - }, {#State 40 + DEFAULT => -86 + }, + {#State 41 ACTIONS => { - 'CONSTANT' => 61, + 'CONSTANT' => 48, 'TEXT' => 16, 'IDENTIFIER' => 26 }, - DEFAULT => -101, + DEFAULT => -93, GOTOS => { - 'identifier' => 62, - 'text' => 63, - 'listtext' => 59, - 'anytext' => 58, - 'constant' => 60 + 'identifier' => 50, + 'text' => 51, + 'anytext' => 46, + 'constant' => 47, + 'commalisttext' => 49 } }, - {#State 41 + {#State 42 ACTIONS => { - "}" => 64, - "interface" => 65 + "}" => 52, + "interface" => 53 } }, - {#State 42 - DEFAULT => -24 - }, {#State 43 - DEFAULT => -20 + DEFAULT => -18 }, {#State 44 - DEFAULT => -39 - }, - {#State 45 ACTIONS => { - "}" => 66, - "declare" => 49, - "const" => 53 + "const" => 63 }, - DEFAULT => -91, + DEFAULT => -85, GOTOS => { - 'typedecl' => 42, - 'function' => 43, - 'bitmap' => 44, - 'definition' => 67, - 'property_list' => 47, - 'usertype' => 46, - 'const' => 52, - 'struct' => 50, - 'declare' => 51, - 'typedef' => 55, - 'enum' => 54, - 'union' => 56 + 'typedecl' => 54, + 'function' => 55, + 'definitions' => 57, + 'bitmap' => 56, + 'definition' => 60, + 'property_list' => 59, + 'usertype' => 58, + 'const' => 62, + 'struct' => 61, + 'typedef' => 65, + 'enum' => 64, + 'union' => 66 } }, + {#State 45 + DEFAULT => -88 + }, {#State 46 ACTIONS => { - ";" => 68 - } + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 + }, + DEFAULT => -91 }, {#State 47 - ACTIONS => { - "typedef" => 69, - 'IDENTIFIER' => 26, - "signed" => 77, - "union" => 70, - "enum" => 79, - "bitmap" => 80, - 'void' => 71, - "unsigned" => 81, - "[" => 20, - "struct" => 76 - }, - GOTOS => { - 'existingtype' => 78, - 'bitmap' => 44, - 'usertype' => 73, - 'property_list' => 72, - 'identifier' => 74, - 'struct' => 50, - 'enum' => 54, - 'type' => 82, - 'union' => 56, - 'sign' => 75 - } + DEFAULT => -95 }, {#State 48 - DEFAULT => -18 + DEFAULT => -115 }, {#State 49 - DEFAULT => -91, - GOTOS => { - 'decl_enum' => 84, - 'decl_bitmap' => 85, - 'decl_type' => 87, - 'decl_union' => 86, - 'property_list' => 83 + ACTIONS => { + "," => 82, + ")" => 83 } }, {#State 50 - DEFAULT => -36 + DEFAULT => -94 }, {#State 51 - DEFAULT => -23 + DEFAULT => -96 }, {#State 52 - DEFAULT => -21 + ACTIONS => { + ";" => 85 + }, + DEFAULT => -117, + GOTOS => { + 'optional_semicolon' => 84 + } }, {#State 53 ACTIONS => { 'IDENTIFIER' => 26 }, GOTOS => { - 'identifier' => 88 + 'identifier' => 86 } }, {#State 54 - DEFAULT => -38 + DEFAULT => -25 }, {#State 55 DEFAULT => -22 }, {#State 56 - DEFAULT => -37 + DEFAULT => -33 }, {#State 57 - DEFAULT => -94 + ACTIONS => { + "}" => 87, + "const" => 63 + }, + DEFAULT => -85, + GOTOS => { + 'typedecl' => 54, + 'function' => 55, + 'bitmap' => 56, + 'definition' => 88, + 'property_list' => 59, + 'usertype' => 58, + 'struct' => 61, + 'const' => 62, + 'typedef' => 65, + 'enum' => 64, + 'union' => 66 + } }, {#State 58 ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 - }, - DEFAULT => -97 + ";" => 89 + } }, {#State 59 ACTIONS => { - "," => 104, - ")" => 105 + "typedef" => 90, + 'IDENTIFIER' => 26, + "signed" => 98, + "union" => 91, + "enum" => 100, + "bitmap" => 101, + 'void' => 92, + "unsigned" => 102, + "[" => 20, + "struct" => 97 + }, + GOTOS => { + 'existingtype' => 99, + 'bitmap' => 56, + 'usertype' => 94, + 'property_list' => 93, + 'identifier' => 95, + 'struct' => 61, + 'enum' => 64, + 'type' => 103, + 'union' => 66, + 'sign' => 96 } }, {#State 60 - DEFAULT => -103 + DEFAULT => -20 }, {#State 61 - DEFAULT => -123 + DEFAULT => -30 }, {#State 62 - DEFAULT => -102 + DEFAULT => -23 }, {#State 63 - DEFAULT => -104 - }, - {#State 64 ACTIONS => { - ";" => 106 + 'IDENTIFIER' => 26 }, - DEFAULT => -125, GOTOS => { - 'optional_semicolon' => 107 + 'identifier' => 104 } }, + {#State 64 + DEFAULT => -32 + }, {#State 65 + DEFAULT => -24 + }, + {#State 66 + DEFAULT => -31 + }, + {#State 67 ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, 'IDENTIFIER' => 26 }, + DEFAULT => -93, GOTOS => { - 'identifier' => 108 + 'identifier' => 50, + 'anytext' => 105, + 'text' => 51, + 'constant' => 47 } }, - {#State 66 + {#State 68 ACTIONS => { - ";" => 106 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -125, + DEFAULT => -93, GOTOS => { - 'optional_semicolon' => 109 + 'identifier' => 50, + 'anytext' => 106, + 'text' => 51, + 'constant' => 47 } }, - {#State 67 - DEFAULT => -19 - }, - {#State 68 - DEFAULT => -40 - }, {#State 69 ACTIONS => { - 'IDENTIFIER' => 26, - "signed" => 77, - 'void' => 71, - "unsigned" => 81 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -91, + DEFAULT => -93, GOTOS => { - 'existingtype' => 78, - 'bitmap' => 44, - 'usertype' => 73, - 'property_list' => 72, - 'identifier' => 74, - 'struct' => 50, - 'enum' => 54, - 'type' => 110, - 'union' => 56, - 'sign' => 75 + 'identifier' => 50, + 'anytext' => 107, + 'text' => 51, + 'constant' => 47 } }, {#State 70 ACTIONS => { - 'IDENTIFIER' => 111 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -122, + DEFAULT => -93, GOTOS => { - 'optional_identifier' => 112 + 'identifier' => 50, + 'anytext' => 108, + 'text' => 51, + 'constant' => 47 } }, {#State 71 - DEFAULT => -47 + ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 + }, + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 109, + 'text' => 51, + 'constant' => 47 + } }, {#State 72 ACTIONS => { - "union" => 70, - "enum" => 79, - "bitmap" => 80, - "[" => 20, - "struct" => 76 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 + }, + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 110, + 'text' => 51, + 'constant' => 47 } }, {#State 73 - DEFAULT => -45 + ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 + }, + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 46, + 'text' => 51, + 'constant' => 47, + 'commalisttext' => 111 + } }, {#State 74 - DEFAULT => -44 + ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 + }, + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 112, + 'text' => 51, + 'constant' => 47 + } }, {#State 75 ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, 'IDENTIFIER' => 26 }, + DEFAULT => -93, GOTOS => { - 'identifier' => 113 + 'identifier' => 50, + 'anytext' => 113, + 'text' => 51, + 'constant' => 47 } }, {#State 76 ACTIONS => { - 'IDENTIFIER' => 111 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -122, + DEFAULT => -93, GOTOS => { - 'optional_identifier' => 114 + 'identifier' => 50, + 'anytext' => 114, + 'text' => 51, + 'constant' => 47 } }, {#State 77 - DEFAULT => -41 + ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 + }, + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 46, + 'text' => 51, + 'constant' => 47, + 'commalisttext' => 115 + } }, {#State 78 - DEFAULT => -46 + ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 + }, + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 116, + 'text' => 51, + 'constant' => 47 + } }, {#State 79 ACTIONS => { - 'IDENTIFIER' => 111 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -122, + DEFAULT => -93, GOTOS => { - 'optional_identifier' => 115 + 'identifier' => 50, + 'anytext' => 117, + 'text' => 51, + 'constant' => 47 } }, {#State 80 ACTIONS => { - 'IDENTIFIER' => 111 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -122, + DEFAULT => -93, GOTOS => { - 'optional_identifier' => 116 + 'identifier' => 50, + 'anytext' => 118, + 'text' => 51, + 'constant' => 47 } }, {#State 81 - DEFAULT => -42 + ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 + }, + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 119, + 'text' => 51, + 'constant' => 47 + } }, {#State 82 ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, 'IDENTIFIER' => 26 }, + DEFAULT => -93, GOTOS => { - 'identifier' => 117 + 'identifier' => 50, + 'anytext' => 120, + 'text' => 51, + 'constant' => 47 } }, {#State 83 - ACTIONS => { - "union" => 118, - "enum" => 119, - "bitmap" => 120, - "[" => 20 - } + DEFAULT => -90 }, {#State 84 - DEFAULT => -29 + DEFAULT => -13 }, {#State 85 - DEFAULT => -30 + DEFAULT => -118 }, {#State 86 - DEFAULT => -31 + ACTIONS => { + ";" => 121 + } }, {#State 87 ACTIONS => { - 'IDENTIFIER' => 26 + ";" => 85 }, + DEFAULT => -117, GOTOS => { - 'identifier' => 121 + 'optional_semicolon' => 122 } }, {#State 88 - DEFAULT => -80, - GOTOS => { - 'pointers' => 122 - } + DEFAULT => -21 }, {#State 89 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 123, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -34 }, {#State 90 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + 'IDENTIFIER' => 26, + "signed" => 98, + 'void' => 92, + "unsigned" => 102 }, - DEFAULT => -101, + DEFAULT => -85, GOTOS => { - 'identifier' => 62, - 'anytext' => 124, - 'text' => 63, - 'constant' => 60 + 'existingtype' => 99, + 'bitmap' => 56, + 'usertype' => 94, + 'property_list' => 93, + 'identifier' => 95, + 'struct' => 61, + 'enum' => 64, + 'type' => 123, + 'union' => 66, + 'sign' => 96 } }, {#State 91 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + 'IDENTIFIER' => 124 }, - DEFAULT => -101, + DEFAULT => -114, GOTOS => { - 'identifier' => 62, - 'anytext' => 125, - 'text' => 63, - 'constant' => 60 + 'optional_identifier' => 125 } }, {#State 92 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 126, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -41 }, {#State 93 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 127, - 'text' => 63, - 'constant' => 60 + "union" => 91, + "enum" => 100, + "bitmap" => 101, + "[" => 20, + "struct" => 97 } }, {#State 94 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 128, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -39 }, {#State 95 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 129, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -38 }, {#State 96 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, 'IDENTIFIER' => 26 }, - DEFAULT => -101, GOTOS => { - 'identifier' => 62, - 'anytext' => 130, - 'text' => 63, - 'constant' => 60, - 'commalisttext' => 131 + 'identifier' => 126 } }, {#State 97 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + 'IDENTIFIER' => 124 }, - DEFAULT => -101, + DEFAULT => -114, GOTOS => { - 'identifier' => 62, - 'anytext' => 132, - 'text' => 63, - 'constant' => 60 + 'optional_identifier' => 127 } }, {#State 98 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 133, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -35 }, {#State 99 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 134, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -40 }, {#State 100 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + 'IDENTIFIER' => 124 }, - DEFAULT => -101, + DEFAULT => -114, GOTOS => { - 'identifier' => 62, - 'anytext' => 130, - 'text' => 63, - 'constant' => 60, - 'commalisttext' => 135 + 'optional_identifier' => 128 } }, {#State 101 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + 'IDENTIFIER' => 124 }, - DEFAULT => -101, + DEFAULT => -114, GOTOS => { - 'identifier' => 62, - 'anytext' => 136, - 'text' => 63, - 'constant' => 60 + 'optional_identifier' => 129 } }, {#State 102 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 137, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -36 }, {#State 103 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, 'IDENTIFIER' => 26 }, - DEFAULT => -101, GOTOS => { - 'identifier' => 62, - 'anytext' => 138, - 'text' => 63, - 'constant' => 60 + 'identifier' => 130 } }, {#State 104 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, + DEFAULT => -74, GOTOS => { - 'identifier' => 62, - 'anytext' => 139, - 'text' => 63, - 'constant' => 60 + 'pointers' => 131 } }, {#State 105 - DEFAULT => -96 + ACTIONS => { + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 + }, + DEFAULT => -106 }, {#State 106 - DEFAULT => -126 + ACTIONS => { + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 + }, + DEFAULT => -97 }, {#State 107 - DEFAULT => -13 + ACTIONS => { + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 + }, + DEFAULT => -105 }, {#State 108 ACTIONS => { - ";" => 140 - } + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 + }, + DEFAULT => -101 }, {#State 109 - DEFAULT => -16 + ACTIONS => { + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 + }, + DEFAULT => -109 }, {#State 110 ACTIONS => { - 'IDENTIFIER' => 26 + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 }, - GOTOS => { - 'identifier' => 141 - } + DEFAULT => -108 }, {#State 111 - DEFAULT => -121 + ACTIONS => { + "}" => 132, + "," => 82 + } }, {#State 112 ACTIONS => { - "{" => 143 + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 }, - DEFAULT => -76, - GOTOS => { - 'union_body' => 144, - 'opt_union_body' => 142 - } + DEFAULT => -103 }, {#State 113 - DEFAULT => -43 + ACTIONS => { + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 + }, + DEFAULT => -104 }, {#State 114 ACTIONS => { - "{" => 146 + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 }, - DEFAULT => -66, - GOTOS => { - 'struct_body' => 145, - 'opt_struct_body' => 147 - } + DEFAULT => -107 }, {#State 115 ACTIONS => { - "{" => 148 - }, - DEFAULT => -49, - GOTOS => { - 'opt_enum_body' => 150, - 'enum_body' => 149 + "," => 82, + ")" => 133 } }, {#State 116 ACTIONS => { - "{" => 152 + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 }, - DEFAULT => -57, - GOTOS => { - 'bitmap_body' => 153, - 'opt_bitmap_body' => 151 - } + DEFAULT => -102 }, {#State 117 ACTIONS => { - "(" => 154 - } + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 + }, + DEFAULT => -99 }, {#State 118 - DEFAULT => -34 + ACTIONS => { + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 + }, + DEFAULT => -98 }, {#State 119 - DEFAULT => -32 + ACTIONS => { + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 + }, + DEFAULT => -100 }, {#State 120 - DEFAULT => -33 + ACTIONS => { + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 + }, + DEFAULT => -92 }, {#State 121 - ACTIONS => { - ";" => 155 - } + DEFAULT => -15 }, {#State 122 + DEFAULT => -16 + }, + {#State 123 ACTIONS => { - 'IDENTIFIER' => 26, - "*" => 157 + 'IDENTIFIER' => 26 }, GOTOS => { - 'identifier' => 156 + 'identifier' => 134 } }, - {#State 123 - ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 - }, - DEFAULT => -114 - }, {#State 124 - ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 - }, - DEFAULT => -105 + DEFAULT => -113 }, {#State 125 ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 + "{" => 136 }, - DEFAULT => -109 + DEFAULT => -70, + GOTOS => { + 'union_body' => 137, + 'opt_union_body' => 135 + } }, {#State 126 - ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 - }, - DEFAULT => -117 + DEFAULT => -37 }, {#State 127 ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 + "{" => 139 }, - DEFAULT => -116 + DEFAULT => -60, + GOTOS => { + 'struct_body' => 138, + 'opt_struct_body' => 140 + } }, {#State 128 ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 + "{" => 141 }, - DEFAULT => -107 + DEFAULT => -43, + GOTOS => { + 'opt_enum_body' => 143, + 'enum_body' => 142 + } }, {#State 129 ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 + "{" => 145 }, - DEFAULT => -113 + DEFAULT => -51, + GOTOS => { + 'bitmap_body' => 146, + 'opt_bitmap_body' => 144 + } }, {#State 130 ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 - }, - DEFAULT => -99 + "(" => 147 + } }, {#State 131 ACTIONS => { - "}" => 158, - "," => 159 + 'IDENTIFIER' => 26, + "*" => 149 + }, + GOTOS => { + 'identifier' => 148 } }, {#State 132 ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -111 + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 150, + 'text' => 51, + 'constant' => 47 + } }, {#State 133 ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -112 + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 151, + 'text' => 51, + 'constant' => 47 + } }, {#State 134 ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 + "[" => 152 }, - DEFAULT => -115 + DEFAULT => -82, + GOTOS => { + 'array_len' => 153 + } }, {#State 135 - ACTIONS => { - "," => 159, - ")" => 160 - } + DEFAULT => -72 }, {#State 136 - ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 - }, - DEFAULT => -110 + DEFAULT => -67, + GOTOS => { + 'union_elements' => 154 + } }, {#State 137 - ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 - }, - DEFAULT => -106 + DEFAULT => -71 }, {#State 138 - ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 - }, - DEFAULT => -108 + DEFAULT => -61 }, {#State 139 - ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 - }, - DEFAULT => -98 + DEFAULT => -76, + GOTOS => { + 'element_list1' => 155 + } }, {#State 140 - DEFAULT => -15 + DEFAULT => -62 }, {#State 141 ACTIONS => { - "[" => 161 + 'IDENTIFIER' => 26 }, - DEFAULT => -88, GOTOS => { - 'array_len' => 162 + 'identifier' => 156, + 'enum_element' => 157, + 'enum_elements' => 158 } }, {#State 142 - DEFAULT => -78 + DEFAULT => -44 }, {#State 143 - DEFAULT => -73, - GOTOS => { - 'union_elements' => 163 - } + DEFAULT => -45 }, {#State 144 - DEFAULT => -77 + DEFAULT => -53 }, {#State 145 - DEFAULT => -67 - }, - {#State 146 - DEFAULT => -82, + ACTIONS => { + 'IDENTIFIER' => 26 + }, + DEFAULT => -56, GOTOS => { - 'element_list1' => 164 + 'identifier' => 161, + 'bitmap_element' => 160, + 'bitmap_elements' => 159, + 'opt_bitmap_elements' => 162 } }, + {#State 146 + DEFAULT => -52 + }, {#State 147 - DEFAULT => -68 + ACTIONS => { + "," => -78, + "void" => 166, + ")" => -78 + }, + DEFAULT => -85, + GOTOS => { + 'base_element' => 163, + 'element_list2' => 165, + 'property_list' => 164 + } }, {#State 148 ACTIONS => { - 'IDENTIFIER' => 26 + "[" => 152, + "=" => 168 }, GOTOS => { - 'identifier' => 165, - 'enum_element' => 166, - 'enum_elements' => 167 + 'array_len' => 167 } }, {#State 149 - DEFAULT => -50 + DEFAULT => -75 }, {#State 150 - DEFAULT => -51 + ACTIONS => { + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 + }, + DEFAULT => -111 }, {#State 151 - DEFAULT => -59 + ACTIONS => { + ":" => 67, + "<" => 70, + "~" => 71, + "?" => 69, + "{" => 73, + "=" => 76 + }, + DEFAULT => -110 }, {#State 152 ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, + "]" => 169, 'IDENTIFIER' => 26 }, - DEFAULT => -62, + DEFAULT => -93, GOTOS => { - 'identifier' => 170, - 'bitmap_element' => 169, - 'bitmap_elements' => 168, - 'opt_bitmap_elements' => 171 + 'identifier' => 50, + 'anytext' => 170, + 'text' => 51, + 'constant' => 47 } }, {#State 153 - DEFAULT => -58 + ACTIONS => { + ";" => 171 + } }, {#State 154 ACTIONS => { - "," => -84, - "void" => 175, - ")" => -84 + "}" => 172 }, - DEFAULT => -91, + DEFAULT => -85, GOTOS => { - 'base_element' => 172, - 'element_list2' => 174, + 'optional_base_element' => 174, 'property_list' => 173 } }, {#State 155 - DEFAULT => -28 + ACTIONS => { + "}" => 175 + }, + DEFAULT => -85, + GOTOS => { + 'base_element' => 176, + 'property_list' => 164 + } }, {#State 156 ACTIONS => { - "[" => 161, "=" => 177 }, - GOTOS => { - 'array_len' => 176 - } + DEFAULT => -48 }, {#State 157 - DEFAULT => -81 + DEFAULT => -46 }, {#State 158 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 178, - 'text' => 63, - 'constant' => 60 + "}" => 178, + "," => 179 } }, {#State 159 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + "," => 180 }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 179, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -57 }, {#State 160 - ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 180, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -54 }, {#State 161 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - "]" => 181, - 'IDENTIFIER' => 26 - }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 182, - 'text' => 63, - 'constant' => 60 + "=" => 181 } }, {#State 162 ACTIONS => { - ";" => 183 + "}" => 182 } }, {#State 163 - ACTIONS => { - "}" => 184 - }, - DEFAULT => -91, - GOTOS => { - 'optional_base_element' => 186, - 'property_list' => 185 - } + DEFAULT => -80 }, {#State 164 ACTIONS => { - "}" => 187 + 'IDENTIFIER' => 26, + "signed" => 98, + 'void' => 92, + "unsigned" => 102, + "[" => 20 }, - DEFAULT => -91, + DEFAULT => -85, GOTOS => { - 'base_element' => 188, - 'property_list' => 173 + 'existingtype' => 99, + 'bitmap' => 56, + 'usertype' => 94, + 'property_list' => 93, + 'identifier' => 95, + 'struct' => 61, + 'enum' => 64, + 'type' => 183, + 'union' => 66, + 'sign' => 96 } }, {#State 165 ACTIONS => { - "=" => 189 - }, - DEFAULT => -54 + "," => 184, + ")" => 185 + } }, {#State 166 - DEFAULT => -52 + DEFAULT => -79 }, {#State 167 ACTIONS => { - "}" => 190, - "," => 191 + "=" => 186 } }, {#State 168 ACTIONS => { - "," => 192 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -63 + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 187, + 'text' => 51, + 'constant' => 47 + } }, {#State 169 - DEFAULT => -60 + ACTIONS => { + "[" => 152 + }, + DEFAULT => -82, + GOTOS => { + 'array_len' => 188 + } }, {#State 170 ACTIONS => { - "=" => 193 + "-" => 68, + ":" => 67, + "?" => 69, + "<" => 70, + "+" => 72, + "~" => 71, + "&" => 74, + "{" => 73, + "/" => 75, + "=" => 76, + "|" => 78, + "(" => 77, + "*" => 79, + "." => 80, + "]" => 189, + ">" => 81 } }, {#State 171 - ACTIONS => { - "}" => 194 - } + DEFAULT => -29 }, {#State 172 - DEFAULT => -86 + DEFAULT => -69 }, {#State 173 ACTIONS => { - 'IDENTIFIER' => 26, - "signed" => 77, - 'void' => 71, - "unsigned" => 81, "[" => 20 }, - DEFAULT => -91, + DEFAULT => -85, GOTOS => { - 'existingtype' => 78, - 'bitmap' => 44, - 'usertype' => 73, - 'property_list' => 72, - 'identifier' => 74, - 'struct' => 50, - 'enum' => 54, - 'type' => 195, - 'union' => 56, - 'sign' => 75 + 'base_or_empty' => 190, + 'base_element' => 191, + 'empty_element' => 192, + 'property_list' => 193 } }, {#State 174 - ACTIONS => { - "," => 196, - ")" => 197 - } + DEFAULT => -68 }, {#State 175 - DEFAULT => -85 + DEFAULT => -59 }, {#State 176 ACTIONS => { - "=" => 198 + ";" => 194 } }, {#State 177 ACTIONS => { - 'CONSTANT' => 61, + 'CONSTANT' => 48, 'TEXT' => 16, 'IDENTIFIER' => 26 }, - DEFAULT => -101, + DEFAULT => -93, GOTOS => { - 'identifier' => 62, - 'anytext' => 199, - 'text' => 63, - 'constant' => 60 + 'identifier' => 50, + 'anytext' => 195, + 'text' => 51, + 'constant' => 47 } }, {#State 178 - ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 - }, - DEFAULT => -119 + DEFAULT => -42 }, {#State 179 ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 + 'IDENTIFIER' => 26 }, - DEFAULT => -100 + GOTOS => { + 'identifier' => 156, + 'enum_element' => 196 + } }, {#State 180 ACTIONS => { - ":" => 89, - "<" => 91, - "~" => 92, - "?" => 95, - "{" => 96, - "=" => 99 + 'IDENTIFIER' => 26 }, - DEFAULT => -118 + GOTOS => { + 'identifier' => 161, + 'bitmap_element' => 197 + } }, {#State 181 ACTIONS => { - "[" => 161 + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 }, - DEFAULT => -88, + DEFAULT => -93, GOTOS => { - 'array_len' => 200 + 'identifier' => 50, + 'anytext' => 198, + 'text' => 51, + 'constant' => 47 } }, {#State 182 - ACTIONS => { - "-" => 90, - ":" => 89, - "?" => 95, - "<" => 91, - "+" => 93, - "~" => 92, - "&" => 97, - "{" => 96, - "/" => 98, - "=" => 99, - "|" => 101, - "(" => 100, - "*" => 94, - "." => 102, - "]" => 201, - ">" => 103 - } + DEFAULT => -50 }, {#State 183 - DEFAULT => -35 + DEFAULT => -74, + GOTOS => { + 'pointers' => 199 + } }, {#State 184 - DEFAULT => -75 + DEFAULT => -85, + GOTOS => { + 'base_element' => 200, + 'property_list' => 164 + } }, {#State 185 ACTIONS => { - "[" => 20 - }, - DEFAULT => -91, - GOTOS => { - 'base_or_empty' => 202, - 'base_element' => 203, - 'empty_element' => 204, - 'property_list' => 205 + ";" => 201 } }, {#State 186 - DEFAULT => -74 + ACTIONS => { + 'CONSTANT' => 48, + 'TEXT' => 16, + 'IDENTIFIER' => 26 + }, + DEFAULT => -93, + GOTOS => { + 'identifier' => 50, + 'anytext' => 202, + 'text' => 51, + 'constant' => 47 + } }, {#State 187 - DEFAULT => -65 - }, - {#State 188 ACTIONS => { - ";" => 206 + "-" => 68, + ":" => 67, + "?" => 69, + "<" => 70, + ";" => 203, + "+" => 72, + "~" => 71, + "&" => 74, + "{" => 73, + "/" => 75, + "=" => 76, + "|" => 78, + "(" => 77, + "*" => 79, + "." => 80, + ">" => 81 } }, + {#State 188 + DEFAULT => -83 + }, {#State 189 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + "[" => 152 }, - DEFAULT => -101, + DEFAULT => -82, GOTOS => { - 'identifier' => 62, - 'anytext' => 207, - 'text' => 63, - 'constant' => 60 + 'array_len' => 204 } }, {#State 190 - DEFAULT => -48 + DEFAULT => -66 }, {#State 191 ACTIONS => { - 'IDENTIFIER' => 26 - }, - GOTOS => { - 'identifier' => 165, - 'enum_element' => 208 + ";" => 205 } }, {#State 192 - ACTIONS => { - 'IDENTIFIER' => 26 - }, - GOTOS => { - 'identifier' => 170, - 'bitmap_element' => 209 - } + DEFAULT => -65 }, {#State 193 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + 'IDENTIFIER' => 26, + "signed" => 98, + ";" => 206, + 'void' => 92, + "unsigned" => 102, + "[" => 20 }, - DEFAULT => -101, + DEFAULT => -85, GOTOS => { - 'identifier' => 62, - 'anytext' => 210, - 'text' => 63, - 'constant' => 60 + 'existingtype' => 99, + 'bitmap' => 56, + 'usertype' => 94, + 'property_list' => 93, + 'identifier' => 95, + 'struct' => 61, + 'enum' => 64, + 'type' => 183, + 'union' => 66, + 'sign' => 96 } }, {#State 194 - DEFAULT => -56 + DEFAULT => -77 }, {#State 195 - DEFAULT => -80, - GOTOS => { - 'pointers' => 211 - } + ACTIONS => { + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 + }, + DEFAULT => -49 }, {#State 196 - DEFAULT => -91, - GOTOS => { - 'base_element' => 212, - 'property_list' => 173 - } + DEFAULT => -47 }, {#State 197 - ACTIONS => { - ";" => 213 - } + DEFAULT => -55 }, {#State 198 ACTIONS => { - 'CONSTANT' => 61, - 'TEXT' => 16, - 'IDENTIFIER' => 26 + "-" => 68, + ":" => 67, + "<" => 70, + "+" => 72, + "~" => 71, + "*" => 79, + "?" => 69, + "{" => 73, + "&" => 74, + "/" => 75, + "=" => 76, + "(" => 77, + "|" => 78, + "." => 80, + ">" => 81 }, - DEFAULT => -101, - GOTOS => { - 'identifier' => 62, - 'anytext' => 214, - 'text' => 63, - 'constant' => 60 - } + DEFAULT => -58 }, {#State 199 ACTIONS => { - "-" => 90, - ":" => 89, - "?" => 95, - "<" => 91, - ";" => 215, - "+" => 93, - "~" => 92, - "&" => 97, - "{" => 96, - "/" => 98, - "=" => 99, - "|" => 101, - "(" => 100, - "*" => 94, - "." => 102, - ">" => 103 + 'IDENTIFIER' => 26, + "*" => 149 + }, + GOTOS => { + 'identifier' => 207 } }, {#State 200 - DEFAULT => -89 + DEFAULT => -81 }, {#State 201 - ACTIONS => { - "[" => 161 - }, - DEFAULT => -88, - GOTOS => { - 'array_len' => 216 - } + DEFAULT => -28 }, {#State 202 - DEFAULT => -72 - }, - {#State 203 ACTIONS => { - ";" => 217 + "-" => 68, + ":" => 67, + "?" => 69, + "<" => 70, + ";" => 208, + "+" => 72, + "~" => 71, + "&" => 74, + "{" => 73, + "/" => 75, + "=" => 76, + "|" => 78, + "(" => 77, + "*" => 79, + "." => 80, + ">" => 81 } }, + {#State 203 + DEFAULT => -26 + }, {#State 204 - DEFAULT => -71 + DEFAULT => -84 }, {#State 205 - ACTIONS => { - 'IDENTIFIER' => 26, - "signed" => 77, - ";" => 218, - 'void' => 71, - "unsigned" => 81, - "[" => 20 - }, - DEFAULT => -91, - GOTOS => { - 'existingtype' => 78, - 'bitmap' => 44, - 'usertype' => 73, - 'property_list' => 72, - 'identifier' => 74, - 'struct' => 50, - 'enum' => 54, - 'type' => 195, - 'union' => 56, - 'sign' => 75 - } + DEFAULT => -64 }, {#State 206 - DEFAULT => -83 + DEFAULT => -63 }, {#State 207 ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 - }, - DEFAULT => -55 - }, - {#State 208 - DEFAULT => -53 - }, - {#State 209 - DEFAULT => -61 - }, - {#State 210 - ACTIONS => { - "-" => 90, - ":" => 89, - "<" => 91, - "+" => 93, - "~" => 92, - "*" => 94, - "?" => 95, - "{" => 96, - "&" => 97, - "/" => 98, - "=" => 99, - "(" => 100, - "|" => 101, - "." => 102, - ">" => 103 - }, - DEFAULT => -64 - }, - {#State 211 - ACTIONS => { - 'IDENTIFIER' => 26, - "*" => 157 + "[" => 152 }, + DEFAULT => -82, GOTOS => { - 'identifier' => 219 + 'array_len' => 209 } }, - {#State 212 - DEFAULT => -87 - }, - {#State 213 + {#State 208 DEFAULT => -27 }, - {#State 214 - ACTIONS => { - "-" => 90, - ":" => 89, - "?" => 95, - "<" => 91, - ";" => 220, - "+" => 93, - "~" => 92, - "&" => 97, - "{" => 96, - "/" => 98, - "=" => 99, - "|" => 101, - "(" => 100, - "*" => 94, - "." => 102, - ">" => 103 - } - }, - {#State 215 - DEFAULT => -25 - }, - {#State 216 - DEFAULT => -90 - }, - {#State 217 - DEFAULT => -70 - }, - {#State 218 - DEFAULT => -69 - }, - {#State 219 - ACTIONS => { - "[" => 161 - }, - DEFAULT => -88, - GOTOS => { - 'array_len' => 221 - } - }, - {#State 220 - DEFAULT => -26 - }, - {#State 221 - DEFAULT => -79 + {#State 209 + DEFAULT => -73 } ], yyrules => @@ -1803,43 +1710,43 @@ sub new { [#Rule 2 'idl', 2, sub -#line 19 "idl.yp" +#line 19 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 3 'idl', 2, sub -#line 20 "idl.yp" +#line 20 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 4 'idl', 2, sub -#line 21 "idl.yp" +#line 21 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 5 'idl', 2, sub -#line 22 "idl.yp" +#line 22 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 6 'idl', 2, sub -#line 23 "idl.yp" +#line 23 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 7 'idl', 2, sub -#line 24 "idl.yp" +#line 24 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 8 'import', 3, sub -#line 27 "idl.yp" +#line 27 "pidl/idl.yp" {{ "TYPE" => "IMPORT", "PATHS" => $_[2], @@ -1850,7 +1757,7 @@ sub [#Rule 9 'include', 3, sub -#line 34 "idl.yp" +#line 34 "pidl/idl.yp" {{ "TYPE" => "INCLUDE", "PATHS" => $_[2], @@ -1861,7 +1768,7 @@ sub [#Rule 10 'importlib', 3, sub -#line 41 "idl.yp" +#line 41 "pidl/idl.yp" {{ "TYPE" => "IMPORTLIB", "PATHS" => $_[2], @@ -1872,19 +1779,19 @@ sub [#Rule 11 'commalist', 1, sub -#line 50 "idl.yp" +#line 50 "pidl/idl.yp" { [ $_[1] ] } ], [#Rule 12 'commalist', 3, sub -#line 51 "idl.yp" +#line 51 "pidl/idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], [#Rule 13 'coclass', 7, sub -#line 55 "idl.yp" +#line 55 "pidl/idl.yp" {{ "TYPE" => "COCLASS", "PROPERTIES" => $_[1], @@ -1900,26 +1807,36 @@ sub [#Rule 15 'interface_names', 4, sub -#line 67 "idl.yp" +#line 67 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], [#Rule 16 - 'interface', 7, + 'interface', 8, sub -#line 71 "idl.yp" +#line 71 "pidl/idl.yp" {{ "TYPE" => "INTERFACE", "PROPERTIES" => $_[1], "NAME" => $_[3], - "DATA" => $_[5], + "BASE" => $_[4], + "DATA" => $_[6], "FILE" => $_[0]->YYData->{FILE}, "LINE" => $_[0]->YYData->{LINE}, }} ], [#Rule 17 + 'base_interface', 0, undef + ], + [#Rule 18 + 'base_interface', 2, +sub +#line 84 "pidl/idl.yp" +{ $_[2] } + ], + [#Rule 19 'cpp_quote', 4, sub -#line 82 "idl.yp" +#line 89 "pidl/idl.yp" {{ "TYPE" => "CPP_QUOTE", "FILE" => $_[0]->YYData->{FILE}, @@ -1927,24 +1844,18 @@ sub "DATA" => $_[3] }} ], - [#Rule 18 + [#Rule 20 'definitions', 1, sub -#line 91 "idl.yp" +#line 98 "pidl/idl.yp" { [ $_[1] ] } ], - [#Rule 19 + [#Rule 21 'definitions', 2, sub -#line 92 "idl.yp" +#line 99 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], - [#Rule 20 - 'definition', 1, undef - ], - [#Rule 21 - 'definition', 1, undef - ], [#Rule 22 'definition', 1, undef ], @@ -1955,9 +1866,12 @@ sub 'definition', 1, undef ], [#Rule 25 + 'definition', 1, undef + ], + [#Rule 26 'const', 7, sub -#line 100 "idl.yp" +#line 107 "pidl/idl.yp" {{ "TYPE" => "CONST", "DTYPE" => $_[2], @@ -1968,10 +1882,10 @@ sub "LINE" => $_[0]->YYData->{LINE}, }} ], - [#Rule 26 + [#Rule 27 'const', 8, sub -#line 110 "idl.yp" +#line 117 "pidl/idl.yp" {{ "TYPE" => "CONST", "DTYPE" => $_[2], @@ -1983,10 +1897,10 @@ sub "LINE" => $_[0]->YYData->{LINE}, }} ], - [#Rule 27 + [#Rule 28 'function', 7, sub -#line 124 "idl.yp" +#line 131 "pidl/idl.yp" {{ "TYPE" => "FUNCTION", "NAME" => $_[3], @@ -1997,58 +1911,10 @@ sub "LINE" => $_[0]->YYData->{LINE}, }} ], - [#Rule 28 - 'declare', 4, -sub -#line 136 "idl.yp" -{{ - "TYPE" => "DECLARE", - "NAME" => $_[3], - "DATA" => $_[2], - "FILE" => $_[0]->YYData->{FILE}, - "LINE" => $_[0]->YYData->{LINE}, - }} - ], [#Rule 29 - 'decl_type', 1, undef - ], - [#Rule 30 - 'decl_type', 1, undef - ], - [#Rule 31 - 'decl_type', 1, undef - ], - [#Rule 32 - 'decl_enum', 2, -sub -#line 149 "idl.yp" -{{ - "TYPE" => "ENUM", - "PROPERTIES" => $_[1] - }} - ], - [#Rule 33 - 'decl_bitmap', 2, -sub -#line 156 "idl.yp" -{{ - "TYPE" => "BITMAP", - "PROPERTIES" => $_[1] - }} - ], - [#Rule 34 - 'decl_union', 2, -sub -#line 163 "idl.yp" -{{ - "TYPE" => "UNION", - "PROPERTIES" => $_[1] - }} - ], - [#Rule 35 'typedef', 6, sub -#line 170 "idl.yp" +#line 143 "pidl/idl.yp" {{ "TYPE" => "TYPEDEF", "PROPERTIES" => $_[1], @@ -2059,67 +1925,67 @@ sub "LINE" => $_[0]->YYData->{LINE}, }} ], - [#Rule 36 + [#Rule 30 'usertype', 1, undef ], - [#Rule 37 + [#Rule 31 'usertype', 1, undef ], - [#Rule 38 + [#Rule 32 'usertype', 1, undef ], - [#Rule 39 + [#Rule 33 'usertype', 1, undef ], - [#Rule 40 + [#Rule 34 'typedecl', 2, sub -#line 183 "idl.yp" +#line 156 "pidl/idl.yp" { $_[1] } ], - [#Rule 41 + [#Rule 35 'sign', 1, undef ], - [#Rule 42 + [#Rule 36 'sign', 1, undef ], - [#Rule 43 + [#Rule 37 'existingtype', 2, sub -#line 188 "idl.yp" +#line 161 "pidl/idl.yp" { ($_[1]?$_[1]:"signed") ." $_[2]" } ], - [#Rule 44 + [#Rule 38 'existingtype', 1, undef ], - [#Rule 45 + [#Rule 39 'type', 1, undef ], - [#Rule 46 + [#Rule 40 'type', 1, undef ], - [#Rule 47 + [#Rule 41 'type', 1, sub -#line 192 "idl.yp" +#line 165 "pidl/idl.yp" { "void" } ], - [#Rule 48 + [#Rule 42 'enum_body', 3, sub -#line 194 "idl.yp" +#line 167 "pidl/idl.yp" { $_[2] } ], - [#Rule 49 + [#Rule 43 'opt_enum_body', 0, undef ], - [#Rule 50 + [#Rule 44 'opt_enum_body', 1, undef ], - [#Rule 51 + [#Rule 45 'enum', 4, sub -#line 197 "idl.yp" +#line 170 "pidl/idl.yp" {{ "TYPE" => "ENUM", "PROPERTIES" => $_[1], @@ -2127,43 +1993,43 @@ sub "ELEMENTS" => $_[4] }} ], - [#Rule 52 + [#Rule 46 'enum_elements', 1, sub -#line 206 "idl.yp" +#line 179 "pidl/idl.yp" { [ $_[1] ] } ], - [#Rule 53 + [#Rule 47 'enum_elements', 3, sub -#line 207 "idl.yp" +#line 180 "pidl/idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], - [#Rule 54 + [#Rule 48 'enum_element', 1, undef ], - [#Rule 55 + [#Rule 49 'enum_element', 3, sub -#line 211 "idl.yp" +#line 184 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 56 + [#Rule 50 'bitmap_body', 3, sub -#line 214 "idl.yp" +#line 187 "pidl/idl.yp" { $_[2] } ], - [#Rule 57 + [#Rule 51 'opt_bitmap_body', 0, undef ], - [#Rule 58 + [#Rule 52 'opt_bitmap_body', 1, undef ], - [#Rule 59 + [#Rule 53 'bitmap', 4, sub -#line 217 "idl.yp" +#line 190 "pidl/idl.yp" {{ "TYPE" => "BITMAP", "PROPERTIES" => $_[1], @@ -2171,46 +2037,46 @@ sub "ELEMENTS" => $_[4] }} ], - [#Rule 60 + [#Rule 54 'bitmap_elements', 1, sub -#line 226 "idl.yp" +#line 199 "pidl/idl.yp" { [ $_[1] ] } ], - [#Rule 61 + [#Rule 55 'bitmap_elements', 3, sub -#line 227 "idl.yp" +#line 200 "pidl/idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], - [#Rule 62 + [#Rule 56 'opt_bitmap_elements', 0, undef ], - [#Rule 63 + [#Rule 57 'opt_bitmap_elements', 1, undef ], - [#Rule 64 + [#Rule 58 'bitmap_element', 3, sub -#line 232 "idl.yp" +#line 205 "pidl/idl.yp" { "$_[1] ( $_[3] )" } ], - [#Rule 65 + [#Rule 59 'struct_body', 3, sub -#line 235 "idl.yp" +#line 208 "pidl/idl.yp" { $_[2] } ], - [#Rule 66 + [#Rule 60 'opt_struct_body', 0, undef ], - [#Rule 67 + [#Rule 61 'opt_struct_body', 1, undef ], - [#Rule 68 + [#Rule 62 'struct', 4, sub -#line 239 "idl.yp" +#line 212 "pidl/idl.yp" {{ "TYPE" => "STRUCT", "PROPERTIES" => $_[1], @@ -2218,10 +2084,10 @@ sub "ELEMENTS" => $_[4] }} ], - [#Rule 69 + [#Rule 63 'empty_element', 2, sub -#line 248 "idl.yp" +#line 221 "pidl/idl.yp" {{ "NAME" => "", "TYPE" => "EMPTY", @@ -2232,43 +2098,43 @@ sub "LINE" => $_[0]->YYData->{LINE}, }} ], - [#Rule 70 + [#Rule 64 'base_or_empty', 2, undef ], - [#Rule 71 + [#Rule 65 'base_or_empty', 1, undef ], - [#Rule 72 + [#Rule 66 'optional_base_element', 2, sub -#line 262 "idl.yp" +#line 235 "pidl/idl.yp" { $_[2]->{PROPERTIES} = FlattenHash([$_[1],$_[2]->{PROPERTIES}]); $_[2] } ], - [#Rule 73 + [#Rule 67 'union_elements', 0, undef ], - [#Rule 74 + [#Rule 68 'union_elements', 2, sub -#line 267 "idl.yp" +#line 240 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], - [#Rule 75 + [#Rule 69 'union_body', 3, sub -#line 270 "idl.yp" +#line 243 "pidl/idl.yp" { $_[2] } ], - [#Rule 76 + [#Rule 70 'opt_union_body', 0, undef ], - [#Rule 77 + [#Rule 71 'opt_union_body', 1, undef ], - [#Rule 78 + [#Rule 72 'union', 4, sub -#line 274 "idl.yp" +#line 247 "pidl/idl.yp" {{ "TYPE" => "UNION", "PROPERTIES" => $_[1], @@ -2276,10 +2142,10 @@ sub "ELEMENTS" => $_[4] }} ], - [#Rule 79 + [#Rule 73 'base_element', 5, sub -#line 283 "idl.yp" +#line 256 "pidl/idl.yp" {{ "NAME" => $_[4], "TYPE" => $_[2], @@ -2290,241 +2156,232 @@ sub "LINE" => $_[0]->YYData->{LINE}, }} ], - [#Rule 80 + [#Rule 74 'pointers', 0, sub -#line 297 "idl.yp" +#line 270 "pidl/idl.yp" { 0 } ], - [#Rule 81 + [#Rule 75 'pointers', 2, sub -#line 298 "idl.yp" +#line 271 "pidl/idl.yp" { $_[1]+1 } ], - [#Rule 82 + [#Rule 76 'element_list1', 0, sub -#line 302 "idl.yp" +#line 275 "pidl/idl.yp" { [] } ], - [#Rule 83 + [#Rule 77 'element_list1', 3, sub -#line 303 "idl.yp" +#line 276 "pidl/idl.yp" { push(@{$_[1]}, $_[2]); $_[1] } ], - [#Rule 84 + [#Rule 78 'element_list2', 0, undef ], - [#Rule 85 + [#Rule 79 'element_list2', 1, undef ], - [#Rule 86 + [#Rule 80 'element_list2', 1, sub -#line 309 "idl.yp" +#line 282 "pidl/idl.yp" { [ $_[1] ] } ], - [#Rule 87 + [#Rule 81 'element_list2', 3, sub -#line 310 "idl.yp" +#line 283 "pidl/idl.yp" { push(@{$_[1]}, $_[3]); $_[1] } ], - [#Rule 88 + [#Rule 82 'array_len', 0, undef ], - [#Rule 89 + [#Rule 83 'array_len', 3, sub -#line 315 "idl.yp" +#line 288 "pidl/idl.yp" { push(@{$_[3]}, "*"); $_[3] } ], - [#Rule 90 + [#Rule 84 'array_len', 4, sub -#line 316 "idl.yp" +#line 289 "pidl/idl.yp" { push(@{$_[4]}, "$_[2]"); $_[4] } ], - [#Rule 91 + [#Rule 85 'property_list', 0, undef ], - [#Rule 92 + [#Rule 86 'property_list', 4, sub -#line 322 "idl.yp" +#line 295 "pidl/idl.yp" { FlattenHash([$_[1],$_[3]]); } ], - [#Rule 93 + [#Rule 87 'properties', 1, sub -#line 325 "idl.yp" +#line 298 "pidl/idl.yp" { $_[1] } ], - [#Rule 94 + [#Rule 88 'properties', 3, sub -#line 326 "idl.yp" +#line 299 "pidl/idl.yp" { FlattenHash([$_[1], $_[3]]); } ], - [#Rule 95 + [#Rule 89 'property', 1, sub -#line 329 "idl.yp" +#line 302 "pidl/idl.yp" {{ "$_[1]" => "1" }} ], - [#Rule 96 + [#Rule 90 'property', 4, sub -#line 330 "idl.yp" +#line 303 "pidl/idl.yp" {{ "$_[1]" => "$_[3]" }} ], - [#Rule 97 - 'listtext', 1, undef - ], - [#Rule 98 - 'listtext', 3, -sub -#line 335 "idl.yp" -{ "$_[1] $_[3]" } - ], - [#Rule 99 + [#Rule 91 'commalisttext', 1, undef ], - [#Rule 100 + [#Rule 92 'commalisttext', 3, sub -#line 340 "idl.yp" +#line 308 "pidl/idl.yp" { "$_[1],$_[3]" } ], - [#Rule 101 + [#Rule 93 'anytext', 0, sub -#line 344 "idl.yp" +#line 312 "pidl/idl.yp" { "" } ], - [#Rule 102 + [#Rule 94 'anytext', 1, undef ], - [#Rule 103 + [#Rule 95 'anytext', 1, undef ], - [#Rule 104 + [#Rule 96 'anytext', 1, undef ], - [#Rule 105 + [#Rule 97 'anytext', 3, sub -#line 346 "idl.yp" +#line 314 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 106 + [#Rule 98 'anytext', 3, sub -#line 347 "idl.yp" +#line 315 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 107 + [#Rule 99 'anytext', 3, sub -#line 348 "idl.yp" +#line 316 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 108 + [#Rule 100 'anytext', 3, sub -#line 349 "idl.yp" +#line 317 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 109 + [#Rule 101 'anytext', 3, sub -#line 350 "idl.yp" +#line 318 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 110 + [#Rule 102 'anytext', 3, sub -#line 351 "idl.yp" +#line 319 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 111 + [#Rule 103 'anytext', 3, sub -#line 352 "idl.yp" +#line 320 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 112 + [#Rule 104 'anytext', 3, sub -#line 353 "idl.yp" +#line 321 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 113 + [#Rule 105 'anytext', 3, sub -#line 354 "idl.yp" +#line 322 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 114 + [#Rule 106 'anytext', 3, sub -#line 355 "idl.yp" +#line 323 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 115 + [#Rule 107 'anytext', 3, sub -#line 356 "idl.yp" +#line 324 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 116 + [#Rule 108 'anytext', 3, sub -#line 357 "idl.yp" +#line 325 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 117 + [#Rule 109 'anytext', 3, sub -#line 358 "idl.yp" +#line 326 "pidl/idl.yp" { "$_[1]$_[2]$_[3]" } ], - [#Rule 118 + [#Rule 110 'anytext', 5, sub -#line 359 "idl.yp" +#line 327 "pidl/idl.yp" { "$_[1]$_[2]$_[3]$_[4]$_[5]" } ], - [#Rule 119 + [#Rule 111 'anytext', 5, sub -#line 360 "idl.yp" +#line 328 "pidl/idl.yp" { "$_[1]$_[2]$_[3]$_[4]$_[5]" } ], - [#Rule 120 + [#Rule 112 'identifier', 1, undef ], - [#Rule 121 + [#Rule 113 'optional_identifier', 1, undef ], - [#Rule 122 + [#Rule 114 'optional_identifier', 0, undef ], - [#Rule 123 + [#Rule 115 'constant', 1, undef ], - [#Rule 124 + [#Rule 116 'text', 1, sub -#line 374 "idl.yp" +#line 342 "pidl/idl.yp" { "\"$_[1]\"" } ], - [#Rule 125 + [#Rule 117 'optional_semicolon', 0, undef ], - [#Rule 126 + [#Rule 118 'optional_semicolon', 1, undef ] ], @@ -2532,7 +2389,7 @@ sub bless($self,$class); } -#line 385 "idl.yp" +#line 353 "pidl/idl.yp" use Parse::Pidl qw(error); @@ -2581,7 +2438,7 @@ sub _Error { error($_[0]->YYData, $_[0]->YYData->{ERRMSG}); delete $_[0]->YYData->{ERRMSG}; return; - }; + } my $last_token = $_[0]->YYData->{LAST_TOKEN}; error($_[0]->YYData, "Syntax error near '$last_token'"); @@ -2627,7 +2484,7 @@ again: if (s/^([\w_]+)//) { $parser->YYData->{LAST_TOKEN} = $1; if ($1 =~ - /^(coclass|interface|const|typedef|declare|union|cpp_quote + /^(coclass|interface|const|typedef|union|cpp_quote |struct|enum|bitmap|void|unsigned|signed|import|include |importlib)$/x) { return $1; diff --git a/tools/pidl/lib/Parse/Pidl/NDR.pm b/tools/pidl/lib/Parse/Pidl/NDR.pm index f624d2bdc0..8440f0183d 100644 --- a/tools/pidl/lib/Parse/Pidl/NDR.pm +++ b/tools/pidl/lib/Parse/Pidl/NDR.pm @@ -35,7 +35,7 @@ use vars qw($VERSION); $VERSION = '0.01'; @ISA = qw(Exporter); @EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsString); -@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar ParseType can_contain_deferred); +@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar ParseType can_contain_deferred is_charset_array); use strict; use Parse::Pidl qw(warning fatal); @@ -53,6 +53,7 @@ my $scalar_alignment = { 'int32' => 4, 'uint32' => 4, 'hyper' => 8, + 'double' => 8, 'pointer' => 8, 'dlong' => 4, 'udlong' => 4, @@ -72,9 +73,9 @@ my $scalar_alignment = { 'ipv4address' => 4 }; -sub GetElementLevelTable($) +sub GetElementLevelTable($$) { - my $e = shift; + my ($e, $pointer_default) = @_; my $order = []; my $is_deferred = 0; @@ -141,6 +142,13 @@ sub GetElementLevelTable($) $is_fixed = 1 if (not $is_conformant and Parse::Pidl::Util::is_constant($size)); $is_inline = 1 if (not $is_conformant and not Parse::Pidl::Util::is_constant($size)); + if ($i == 0 and $is_fixed and has_property($e, "string")) { + $is_fixed = 0; + $is_varying = 1; + $is_string = 1; + delete($e->{PROPERTIES}->{string}); + } + push (@$order, { TYPE => "ARRAY", SIZE_IS => $size, @@ -157,32 +165,45 @@ sub GetElementLevelTable($) # Next, all the pointers foreach my $i (1..$e->{POINTERS}) { - my $pt = pointer_type($e); - my $level = "EMBEDDED"; # Top level "ref" pointers do not have a referrent identifier - $level = "TOP" if ( defined($pt) - and $i == 1 - and $e->{PARENT}->{TYPE} eq "FUNCTION"); + $level = "TOP" if ($i == 1 and $e->{PARENT}->{TYPE} eq "FUNCTION"); + + my $pt; + # + # Only the first level gets the pointer type from the + # pointer property, the others get them from + # the pointer_default() interface property + # + # see http://msdn2.microsoft.com/en-us/library/aa378984(VS.85).aspx + # (Here they talk about the rightmost pointer, but testing shows + # they mean the leftmost pointer.) + # + # --metze + # + $pt = pointer_type($e); + if ($i > 1) { + $is_deferred = 1 if ($pt ne "ref" and $e->{PARENT}->{TYPE} eq "FUNCTION"); + $pt = $pointer_default; + } push (@$order, { TYPE => "POINTER", - # for now, there can only be one pointer type per element - POINTER_TYPE => pointer_type($e), + POINTER_TYPE => $pt, POINTER_INDEX => $pointer_idx, IS_DEFERRED => "$is_deferred", LEVEL => $level }); warning($e, "top-level \[out\] pointer `$e->{NAME}' is not a \[ref\] pointer") - if ($i == 1 and pointer_type($e) ne "ref" and + if ($i == 1 and $pt ne "ref" and $e->{PARENT}->{TYPE} eq "FUNCTION" and not has_property($e, "in")); $pointer_idx++; # everything that follows will be deferred - $is_deferred = 1 if ($e->{PARENT}->{TYPE} ne "FUNCTION"); + $is_deferred = 1 if ($level ne "TOP"); my $array_size = shift @size_is; my $array_length; @@ -274,6 +295,22 @@ sub GetElementLevelTable($) return $order; } +sub GetTypedefLevelTable($$$) +{ + my ($e, $data, $pointer_default) = @_; + + my $order = []; + + push (@$order, { + TYPE => "TYPEDEF" + }); + + my $i = 0; + foreach (@$order) { $_->{LEVEL_INDEX} = $i; $i+=1; } + + return $order; +} + ##################################################################### # see if a type contains any deferred data sub can_contain_deferred($) @@ -287,8 +324,6 @@ sub can_contain_deferred($) return 0 if (Parse::Pidl::Typelist::is_scalar($type)); - return 1 if ($type->{TYPE} eq "DECLARE"); # assume the worst - return can_contain_deferred($type->{DATA}) if ($type->{TYPE} eq "TYPEDEF"); return 0 unless defined($type->{ELEMENTS}); @@ -354,21 +389,25 @@ sub align_type($) return $scalar_alignment->{$e->{NAME}}; } + return 0 if ($e eq "EMPTY"); + unless (hasType($e)) { # it must be an external type - all we can do is guess - # print "Warning: assuming alignment of unknown type '$e' is 4\n"; + # warning($e, "assuming alignment of unknown type '$e' is 4"); return 4; } my $dt = getType($e); - if ($dt->{TYPE} eq "TYPEDEF" or $dt->{TYPE} eq "DECLARE") { + if ($dt->{TYPE} eq "TYPEDEF") { return align_type($dt->{DATA}); } elsif ($dt->{TYPE} eq "ENUM") { return align_type(Parse::Pidl::Typelist::enum_type_fn($dt)); } elsif ($dt->{TYPE} eq "BITMAP") { return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt)); } elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) { + # Struct/union without body: assume 4 + return 4 unless (defined($dt->{ELEMENTS})); return find_largest_alignment($dt); } @@ -389,7 +428,7 @@ sub ParseElement($$) NAME => $e->{NAME}, TYPE => $e->{TYPE}, PROPERTIES => $e->{PROPERTIES}, - LEVELS => GetElementLevelTable($e), + LEVELS => GetElementLevelTable($e, $pointer_default), REPRESENTATION_TYPE => ($e->{PROPERTIES}->{represent_as} or $e->{TYPE}), ALIGN => align_type($e->{TYPE}), ORIGINAL => $e @@ -560,6 +599,7 @@ sub ParseTypedef($$) NAME => $d->{NAME}, TYPE => $d->{TYPE}, PROPERTIES => $d->{PROPERTIES}, + LEVELS => GetTypedefLevelTable($d, $data, $pointer_default), DATA => $data, ORIGINAL => $d }; @@ -579,7 +619,7 @@ sub ParseFunction($$$) my $rettype = undef; my $thisopnum = undef; - CheckPointerTypes($d, $ndr->{PROPERTIES}->{pointer_default_top}); + CheckPointerTypes($d, "ref"); if (not defined($d->{PROPERTIES}{noopnum})) { $thisopnum = ${$opnum}; @@ -621,7 +661,7 @@ sub CheckPointerTypes($$) foreach my $e (@{$s->{ELEMENTS}}) { if ($e->{POINTERS} and not defined(pointer_type($e))) { - $e->{PROPERTIES}->{$default} = 1; + $e->{PROPERTIES}->{$default} = '1'; } } } @@ -631,7 +671,7 @@ sub FindNestedTypes($$) sub FindNestedTypes($$); my ($l, $t) = @_; - return if not defined($t->{ELEMENTS}); + return unless defined($t->{ELEMENTS}); return if ($t->{TYPE} eq "ENUM"); return if ($t->{TYPE} eq "BITMAP"); @@ -650,7 +690,6 @@ sub ParseInterface($) my @consts = (); my @functions = (); my @endpoints; - my @declares = (); my $opnum = 0; my $version; @@ -660,16 +699,8 @@ sub ParseInterface($) $idl->{PROPERTIES}->{pointer_default} = "unique"; } - if (not has_property($idl, "pointer_default_top")) { - $idl->{PROPERTIES}->{pointer_default_top} = "ref"; - } else { - warning($idl, "pointer_default_top() is a pidl extension and should not be used"); - } - foreach my $d (@{$idl->{DATA}}) { - if ($d->{TYPE} eq "DECLARE") { - push (@declares, $d); - } elsif ($d->{TYPE} eq "FUNCTION") { + if ($d->{TYPE} eq "FUNCTION") { push (@functions, ParseFunction($idl, $d, \$opnum)); } elsif ($d->{TYPE} eq "CONST") { push (@consts, ParseConst($idl, $d)); @@ -682,14 +713,19 @@ sub ParseInterface($) $version = "0.0"; if(defined $idl->{PROPERTIES}->{version}) { - $version = $idl->{PROPERTIES}->{version}; + my @if_version = split(/\./, $idl->{PROPERTIES}->{version}); + if ($if_version[0] == $idl->{PROPERTIES}->{version}) { + $version = $idl->{PROPERTIES}->{version}; + } else { + $version = $if_version[1] << 16 | $if_version[0]; + } } # If no endpoint is set, default to the interface name as a named pipe if (!defined $idl->{PROPERTIES}->{endpoint}) { push @endpoints, "\"ncacn_np:[\\\\pipe\\\\" . $idl->{NAME} . "]\""; } else { - @endpoints = split / /, $idl->{PROPERTIES}->{endpoint}; + @endpoints = split /,/, $idl->{PROPERTIES}->{endpoint}; } return { @@ -701,7 +737,6 @@ sub ParseInterface($) FUNCTIONS => \@functions, CONSTS => \@consts, TYPES => \@types, - DECLARES => \@declares, ENDPOINTS => \@endpoints }; } @@ -785,20 +820,21 @@ sub ContainsDeferred($$) sub el_name($) { my $e = shift; + my $name = "<ANONYMOUS>"; - if ($e->{PARENT} && $e->{PARENT}->{NAME}) { - return "$e->{PARENT}->{NAME}.$e->{NAME}"; - } + $name = $e->{NAME} if defined($e->{NAME}); - if ($e->{PARENT} && $e->{PARENT}->{PARENT}->{NAME}) { - return "$e->{PARENT}->{PARENT}->{NAME}.$e->{NAME}"; + if (defined($e->{PARENT}) and defined($e->{PARENT}->{NAME})) { + return "$e->{PARENT}->{NAME}.$name"; } - if ($e->{PARENT}) { - return "$e->{PARENT}->{NAME}.$e->{NAME}"; + if (defined($e->{PARENT}) and + defined($e->{PARENT}->{PARENT}) and + defined($e->{PARENT}->{PARENT}->{NAME})) { + return "$e->{PARENT}->{PARENT}->{NAME}.$name"; } - return $e->{NAME}; + return $name; } ################################### @@ -826,9 +862,10 @@ my %property_list = ( "uuid" => ["INTERFACE"], "endpoint" => ["INTERFACE"], "pointer_default" => ["INTERFACE"], - "pointer_default_top" => ["INTERFACE"], "helper" => ["INTERFACE"], + "pyhelper" => ["INTERFACE"], "authservice" => ["INTERFACE"], + "restricted" => ["INTERFACE"], # dcom "object" => ["INTERFACE"], @@ -849,24 +886,25 @@ my %property_list = ( "unique" => ["ELEMENT"], "ignore" => ["ELEMENT"], "relative" => ["ELEMENT"], - "relative_base" => ["TYPEDEF"], + "null_is_ffffffff" => ["ELEMENT"], + "relative_base" => ["TYPEDEF", "STRUCT", "UNION"], - "gensize" => ["TYPEDEF"], + "gensize" => ["TYPEDEF", "STRUCT", "UNION"], "value" => ["ELEMENT"], - "flag" => ["ELEMENT", "TYPEDEF"], + "flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"], # generic - "public" => ["FUNCTION", "TYPEDEF"], - "nopush" => ["FUNCTION", "TYPEDEF"], - "nopull" => ["FUNCTION", "TYPEDEF"], - "nosize" => ["FUNCTION", "TYPEDEF"], - "noprint" => ["FUNCTION", "TYPEDEF"], - "noejs" => ["FUNCTION", "TYPEDEF"], + "public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"], + "nopush" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"], + "nopull" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"], + "nosize" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"], + "noprint" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "ELEMENT"], + "todo" => ["FUNCTION"], # union "switch_is" => ["ELEMENT"], - "switch_type" => ["ELEMENT", "TYPEDEF"], - "nodiscriminant" => ["TYPEDEF"], + "switch_type" => ["ELEMENT", "UNION"], + "nodiscriminant" => ["UNION"], "case" => ["ELEMENT"], "default" => ["ELEMENT"], @@ -879,15 +917,15 @@ my %property_list = ( "compression" => ["ELEMENT"], # enum - "enum8bit" => ["TYPEDEF"], - "enum16bit" => ["TYPEDEF"], - "v1_enum" => ["TYPEDEF"], + "enum8bit" => ["ENUM"], + "enum16bit" => ["ENUM"], + "v1_enum" => ["ENUM"], # bitmap - "bitmap8bit" => ["TYPEDEF"], - "bitmap16bit" => ["TYPEDEF"], - "bitmap32bit" => ["TYPEDEF"], - "bitmap64bit" => ["TYPEDEF"], + "bitmap8bit" => ["BITMAP"], + "bitmap16bit" => ["BITMAP"], + "bitmap32bit" => ["BITMAP"], + "bitmap64bit" => ["BITMAP"], # array "range" => ["ELEMENT"], @@ -911,7 +949,7 @@ sub ValidProperties($$) unless defined($property_list{$key}); fatal($e, el_name($e) . ": property '$key' not allowed on '$t'") - unless grep($t, @{$property_list{$key}}); + unless grep(/^$t$/, @{$property_list{$key}}); } } @@ -1052,8 +1090,9 @@ sub ValidUnion($) ValidProperties($union,"UNION"); - if (has_property($union->{PARENT}, "nodiscriminant") and has_property($union->{PARENT}, "switch_type")) { - fatal($union->{PARENT}, $union->{PARENT}->{NAME} . ": switch_type() on union without discriminant"); + if (has_property($union->{PARENT}, "nodiscriminant") and + has_property($union->{PARENT}, "switch_type")) { + fatal($union->{PARENT}, $union->{PARENT}->{NAME} . ": switch_type(" . $union->{PARENT}->{PROPERTIES}->{switch_type} . ") on union without discriminant"); } return unless defined($union->{ELEMENTS}); @@ -1072,7 +1111,7 @@ sub ValidUnion($) } if (has_property($e, "ref")) { - fatal($e, el_name($e) . " : embedded ref pointers are not supported yet\n"); + fatal($e, el_name($e) . ": embedded ref pointers are not supported yet\n"); } @@ -1091,6 +1130,9 @@ sub ValidTypedef($) $data->{PARENT} = $typedef; + $data->{FILE} = $typedef->{FILE} unless defined($data->{FILE}); + $data->{LINE} = $typedef->{LINE} unless defined($data->{LINE}); + ValidType($data) if (ref($data) eq "HASH"); } @@ -1183,4 +1225,19 @@ sub Validate($) } } +sub is_charset_array($$) +{ + my ($e,$l) = @_; + + return 0 if ($l->{TYPE} ne "ARRAY"); + + my $nl = GetNextLevel($e,$l); + + return 0 unless ($nl->{TYPE} eq "DATA"); + + return has_property($e, "charset"); +} + + + 1; diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm index f6c9a04a8e..a2a61d87d0 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm @@ -2,31 +2,39 @@ # Samba3 client generator for IDL structures # on top of Samba4 style NDR functions # Copyright jelmer@samba.org 2005-2006 +# Copyright gd@samba.org 2008 # released under the GNU GPL package Parse::Pidl::Samba3::ClientNDR; use Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(GenerateFunctionInEnv ParseFunction $res $res_hdr); +@EXPORT_OK = qw(ParseFunction $res $res_hdr ParseOutputArgument); use strict; -use Parse::Pidl qw(fatal warning); -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 qw(fatal warning error); +use Parse::Pidl::Util qw(has_property ParseExpr); use Parse::Pidl::Samba4 qw(DeclLong); -use Parse::Pidl::Samba4::NDR::Parser qw(GenerateFunctionInEnv); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv); use vars qw($VERSION); $VERSION = '0.01'; sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; } sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); } -sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= "$self->{tabs}$txt\n"; } +sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; } sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; } sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); } +sub genpad($) +{ + my ($s) = @_; + my $nt = int((length($s)+1)/8); + my $lt = ($nt*8)-1; + my $ns = (length($s)-$lt); + return "\t"x($nt)." "x($ns); +} + sub new($) { my ($class) = shift; @@ -34,19 +42,107 @@ sub new($) bless($self, $class); } +sub ElementDirection($) +{ + my ($e) = @_; + + return "[in,out]" if (has_property($e, "in") and has_property($e, "out")); + return "[in]" if (has_property($e, "in")); + return "[out]" if (has_property($e, "out")); + return "[in,out]"; +} + +sub HeaderProperties($$) +{ + my($props,$ignores) = @_; + my $ret = ""; + + foreach my $d (keys %{$props}) { + next if (grep(/^$d$/, @$ignores)); + if($props->{$d} ne "1") { + $ret.= "$d($props->{$d}),"; + } else { + $ret.="$d,"; + } + } + + if ($ret) { + return "[" . substr($ret, 0, -1) . "]"; + } +} + +sub ParseOutputArgument($$$) +{ + my ($self, $fn, $e) = @_; + my $level = 0; + + if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY") { + $self->pidl("return NT_STATUS_NOT_SUPPORTED;"); + error($e->{ORIGINAL}, "[out] argument is not a pointer or array"); + return; + } + + if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") { + $level = 1; + if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") { + $self->pidl("if ($e->{NAME} && r.out.$e->{NAME}) {"); + $self->indent; + } + } + + if ($e->{LEVELS}[$level]->{TYPE} eq "ARRAY") { + # This is a call to GenerateFunctionInEnv intentionally. + # Since the data is being copied into a user-provided data + # structure, the user should be able to know the size beforehand + # to allocate a structure of the right size. + my $env = GenerateFunctionInEnv($fn, "r."); + my $l = $e->{LEVELS}[$level]; + unless (defined($l->{SIZE_IS})) { + error($e->{ORIGINAL}, "no size known for [out] array `$e->{NAME}'"); + $self->pidl('#error No size known for [out] array `$e->{NAME}'); + } else { + my $size_is = ParseExpr($l->{SIZE_IS}, $env, $e->{ORIGINAL}); + if (has_property($e, "charset")) { + $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));"); + } else { + $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));"); + } + } + } else { + $self->pidl("*$e->{NAME} = *r.out.$e->{NAME};"); + } + + if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") { + if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") { + $self->deindent; + $self->pidl("}"); + } + } +} + sub ParseFunction($$$) { my ($self, $if, $fn) = @_; - my $inargs = ""; - my $defargs = ""; + my $fn_args = ""; my $uif = uc($if); my $ufn = "NDR_".uc($fn->{NAME}); + my $fn_str = "NTSTATUS rpccli_$fn->{NAME}"; + my $pad = genpad($fn_str); + + $fn_args .= "struct rpc_pipe_client *cli,\n" . $pad . "TALLOC_CTX *mem_ctx"; foreach (@{$fn->{ELEMENTS}}) { - $defargs .= ", " . DeclLong($_); + my $dir = ElementDirection($_); + my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]); + $fn_args .= ",\n" . $pad . DeclLong($_) . " /* $dir $prop */"; + } + + if (defined($fn->{RETURN_TYPE}) && ($fn->{RETURN_TYPE} eq "WERROR")) { + $fn_args .= ",\n" . $pad . "WERROR *werror"; } - $self->fn_declare("NTSTATUS rpccli_$fn->{NAME}(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx$defargs)"); + + $self->fn_declare("$fn_str($fn_args)"); $self->pidl("{"); $self->indent; $self->pidl("struct $fn->{NAME} r;"); @@ -57,14 +153,21 @@ sub ParseFunction($$$) foreach (@{$fn->{ELEMENTS}}) { if (grep(/in/, @{$_->{DIRECTION}})) { $self->pidl("r.in.$_->{NAME} = $_->{NAME};"); - } + } } $self->pidl(""); - $self->pidl("if (DEBUGLEVEL >= 10)"); - $self->pidl("\tNDR_PRINT_IN_DEBUG($fn->{NAME}, &r);"); + $self->pidl("if (DEBUGLEVEL >= 10) {"); + $self->indent; + $self->pidl("NDR_PRINT_IN_DEBUG($fn->{NAME}, &r);"); + $self->deindent; + $self->pidl("}"); $self->pidl(""); - $self->pidl("status = cli_do_rpc_ndr(cli, mem_ctx, PI_$uif, &ndr_table_$if, $ufn, &r);"); + $self->pidl("status = cli->dispatch(cli,"); + $self->pidl("\t\t\tmem_ctx,"); + $self->pidl("\t\t\t&ndr_table_$if,"); + $self->pidl("\t\t\t$ufn,"); + $self->pidl("\t\t\t&r);"); $self->pidl(""); $self->pidl("if (!NT_STATUS_IS_OK(status)) {"); @@ -74,46 +177,24 @@ sub ParseFunction($$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("if (DEBUGLEVEL >= 10)"); - $self->pidl("\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, &r);"); + $self->pidl("if (DEBUGLEVEL >= 10) {"); + $self->indent; + $self->pidl("NDR_PRINT_OUT_DEBUG($fn->{NAME}, &r);"); + $self->deindent; + $self->pidl("}"); $self->pidl(""); $self->pidl("if (NT_STATUS_IS_ERR(status)) {"); - $self->pidl("\treturn status;"); + $self->indent; + $self->pidl("return status;"); + $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("/* Return variables */"); foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/out/, @{$e->{DIRECTION}})); - my $level = 0; - - fatal($e->{ORIGINAL}, "[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") { - $level = 1; - if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") { - $self->pidl("if ($e->{NAME} && r.out.$e->{NAME}) {"); - $self->indent; - } - } - if ($e->{LEVELS}[$level]->{TYPE} eq "ARRAY") { - # This is a call to GenerateFunctionInEnv intentionally. - # Since the data is being copied into a user-provided data - # structure, the user should be able to know the size beforehand - # to allocate a structure of the right size. - my $env = GenerateFunctionInEnv($fn, "r."); - my $size_is = ParseExpr($e->{LEVELS}[$level]->{SIZE_IS}, $env, $e->{ORIGINAL}); - $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is);"); - } else { - $self->pidl("*$e->{NAME} = *r.out.$e->{NAME};"); - } + $self->ParseOutputArgument($fn, $e); - if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") { - if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") { - $self->deindent; - $self->pidl("}"); - } - } } $self->pidl(""); @@ -123,6 +204,12 @@ sub ParseFunction($$$) } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") { $self->pidl("return r.out.result;"); } elsif ($fn->{RETURN_TYPE} eq "WERROR") { + $self->pidl("if (werror) {"); + $self->indent; + $self->pidl("*werror = r.out.result;"); + $self->deindent; + $self->pidl("}"); + $self->pidl(""); $self->pidl("return werror_to_ntstatus(r.out.result);"); } else { warning($fn->{ORIGINAL}, "Unable to convert $fn->{RETURN_TYPE} to NTSTATUS"); @@ -142,7 +229,10 @@ sub ParseInterface($$) $self->pidl_hdr("#ifndef __CLI_$uif\__"); $self->pidl_hdr("#define __CLI_$uif\__"); - $self->ParseFunction($if->{NAME}, $_) foreach (@{$if->{FUNCTIONS}}); + foreach (@{$if->{FUNCTIONS}}) { + next if ($_->{PROPERTIES}{noopnum}); + $self->ParseFunction($if->{NAME}, $_); + } $self->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 a07d0ddc6c..5599de9d79 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm @@ -6,13 +6,17 @@ package Parse::Pidl::Samba3::ServerNDR; +use Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw(DeclLevel); + use strict; -use Parse::Pidl qw(warning fatal); +use Parse::Pidl qw(warning error fatal); 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(ElementStars DeclLong); -use Parse::Pidl::Samba4::NDR::Parser qw(GenerateFunctionOutEnv); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionOutEnv); use vars qw($VERSION); $VERSION = '0.01'; @@ -22,11 +26,11 @@ my $res_hdr; my $tabs = ""; sub indent() { $tabs.="\t"; } sub deindent() { $tabs = substr($tabs, 1); } -sub pidl($) { $res .= $tabs.(shift)."\n"; } +sub pidl($) { my ($txt) = @_; $res .= $txt?$tabs.(shift)."\n":"\n"; } sub pidl_hdr($) { $res_hdr .= (shift)."\n"; } sub fn_declare($) { my ($n) = @_; pidl $n; pidl_hdr "$n;"; } -sub DeclLevel($$) +sub DeclLevel($$) { my ($e, $l) = @_; my $res = ""; @@ -44,9 +48,9 @@ sub DeclLevel($$) return $res; } -sub AllocOutVar($$$$) +sub AllocOutVar($$$$$) { - my ($e, $mem_ctx, $name, $env) = @_; + my ($e, $mem_ctx, $name, $env, $fail) = @_; my $l = $e->{LEVELS}[0]; @@ -54,30 +58,80 @@ sub AllocOutVar($$$$) if ($l->{TYPE} eq "POINTER") { my $nl = GetNextLevel($e, $l); $l = $nl if ($nl->{TYPE} eq "ARRAY"); - } + } elsif # we don't support multi-dimentional arrays yet - if ($l->{TYPE} eq "ARRAY") { + ($l->{TYPE} eq "ARRAY") { my $nl = GetNextLevel($e, $l); if ($nl->{TYPE} eq "ARRAY") { fatal($e->{ORIGINAL},"multi-dimentional [out] arrays are not supported!"); } + } else { + # neither pointer nor array, no need to alloc something. + return; } if ($l->{TYPE} eq "ARRAY") { - my $size = ParseExpr($l->{SIZE_IS}, $env, $e); - pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);"; + unless(defined($l->{SIZE_IS})) { + error($e->{ORIGINAL}, "No size known for array `$e->{NAME}'"); + pidl "#error No size known for array `$e->{NAME}'"; + } else { + my $size = ParseExpr($l->{SIZE_IS}, $env, $e); + pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);"; + } } else { pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");"; } pidl "if ($name == NULL) {"; - pidl "\ttalloc_free($mem_ctx);"; - pidl "\treturn False;"; + $fail->(); pidl "}"; pidl ""; } +sub CallWithStruct($$$$) +{ + my ($pipes_struct, $mem_ctx, $fn, $fail) = @_; + my $env = GenerateFunctionOutEnv($fn); + my $hasout = 0; + foreach (@{$fn->{ELEMENTS}}) { + if (grep(/out/, @{$_->{DIRECTION}})) { $hasout = 1; } + } + + pidl "ZERO_STRUCT(r->out);" if ($hasout); + + my $proto = "_$fn->{NAME}(pipes_struct *p, struct $fn->{NAME} *r"; + my $ret = "_$fn->{NAME}($pipes_struct, r"; + foreach (@{$fn->{ELEMENTS}}) { + my @dir = @{$_->{DIRECTION}}; + if (grep(/in/, @dir) and grep(/out/, @dir)) { + pidl "r->out.$_->{NAME} = r->in.$_->{NAME};"; + } + } + + foreach (@{$fn->{ELEMENTS}}) { + my @dir = @{$_->{DIRECTION}}; + if (grep(/in/, @dir) and grep(/out/, @dir)) { + # noop + } elsif (grep(/out/, @dir) and not + has_property($_, "represent_as")) { + AllocOutVar($_, $mem_ctx, "r->out.$_->{NAME}", $env, $fail); + } + } + $ret .= ")"; + $proto .= ");"; + + if ($fn->{RETURN_TYPE}) { + $ret = "r->out.result = $ret"; + $proto = "$fn->{RETURN_TYPE} $proto"; + } else { + $proto = "void $proto"; + } + + pidl_hdr "$proto"; + pidl "$ret;"; +} + sub ParseFunction($$) { my ($if,$fn) = @_; @@ -96,101 +150,117 @@ sub ParseFunction($$) pidl ""; pidl "call = &ndr_table_$if->{NAME}.calls[$op];"; pidl ""; - pidl "r = talloc(NULL, struct $fn->{NAME});"; + pidl "r = talloc(talloc_tos(), struct $fn->{NAME});"; pidl "if (r == NULL) {"; - pidl "\treturn False;"; + pidl "\treturn false;"; pidl "}"; pidl ""; pidl "if (!prs_data_blob(&p->in_data.data, &blob, r)) {"; pidl "\ttalloc_free(r);"; - pidl "\treturn False;"; + pidl "\treturn false;"; pidl "}"; pidl ""; - pidl "pull = ndr_pull_init_blob(&blob, r);"; + pidl "pull = ndr_pull_init_blob(&blob, r, NULL);"; pidl "if (pull == NULL) {"; pidl "\ttalloc_free(r);"; - pidl "\treturn False;"; + pidl "\treturn false;"; pidl "}"; pidl ""; pidl "pull->flags |= LIBNDR_FLAG_REF_ALLOC;"; pidl "ndr_err = call->ndr_pull(pull, NDR_IN, r);"; pidl "if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {"; pidl "\ttalloc_free(r);"; - pidl "\treturn False;"; + pidl "\treturn false;"; pidl "}"; pidl ""; - pidl "if (DEBUGLEVEL >= 10)"; + pidl "if (DEBUGLEVEL >= 10) {"; pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, r);"; + pidl "}"; pidl ""; - my $env = GenerateFunctionOutEnv($fn); - my $hasout = 0; - foreach (@{$fn->{ELEMENTS}}) { - if (grep(/out/, @{$_->{DIRECTION}})) { $hasout = 1; } - } - - pidl "ZERO_STRUCT(r->out);" if ($hasout); - - my $proto = "_$fn->{NAME}(pipes_struct *p, struct $fn->{NAME} *r"; - my $ret = "_$fn->{NAME}(p, r"; - foreach (@{$fn->{ELEMENTS}}) { - my @dir = @{$_->{DIRECTION}}; - if (grep(/in/, @dir) and grep(/out/, @dir)) { - pidl "r->out.$_->{NAME} = r->in.$_->{NAME};"; - } elsif (grep(/out/, @dir) and not - has_property($_, "represent_as")) { - AllocOutVar($_, "r", "r->out.$_->{NAME}", $env); + CallWithStruct("p", "r", $fn, + sub { + pidl "\ttalloc_free(r);"; + pidl "\treturn false;"; } - } - $ret .= ")"; - $proto .= ");"; - - if ($fn->{RETURN_TYPE}) { - $ret = "r->out.result = $ret"; - $proto = "$fn->{RETURN_TYPE} $proto"; - } else { - $proto = "void $proto"; - } - - pidl_hdr "$proto"; - pidl "$ret;"; + ); pidl ""; pidl "if (p->rng_fault_state) {"; pidl "\ttalloc_free(r);"; - pidl "\t/* Return True here, srv_pipe_hnd.c will take care */"; - pidl "\treturn True;"; + pidl "\t/* Return true here, srv_pipe_hnd.c will take care */"; + pidl "\treturn true;"; pidl "}"; pidl ""; - pidl "if (DEBUGLEVEL >= 10)"; + pidl "if (DEBUGLEVEL >= 10) {"; pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, r);"; + pidl "}"; pidl ""; - pidl "push = ndr_push_init_ctx(r);"; + pidl "push = ndr_push_init_ctx(r, NULL);"; pidl "if (push == NULL) {"; pidl "\ttalloc_free(r);"; - pidl "\treturn False;"; + pidl "\treturn false;"; pidl "}"; pidl ""; pidl "ndr_err = call->ndr_push(push, NDR_OUT, r);"; pidl "if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {"; pidl "\ttalloc_free(r);"; - pidl "\treturn False;"; + pidl "\treturn false;"; pidl "}"; pidl ""; pidl "blob = ndr_push_blob(push);"; - pidl "if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32)blob.length)) {"; + pidl "if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) {"; pidl "\ttalloc_free(r);"; - pidl "\treturn False;"; + pidl "\treturn false;"; pidl "}"; pidl ""; pidl "talloc_free(r);"; pidl ""; - pidl "return True;"; + pidl "return true;"; deindent; pidl "}"; pidl ""; } +sub ParseDispatchFunction($) +{ + my ($if) = @_; + + pidl_hdr "NTSTATUS rpc_$if->{NAME}_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r);"; + pidl "NTSTATUS rpc_$if->{NAME}_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *_r)"; + pidl "{"; + indent; + pidl "if (cli->pipes_struct == NULL) {"; + pidl "\treturn NT_STATUS_INVALID_PARAMETER;"; + pidl "}"; + pidl ""; + pidl "switch (opnum)"; + pidl "{"; + indent; + foreach my $fn (@{$if->{FUNCTIONS}}) { + next if ($fn->{PROPERTIES}{noopnum}); + my $op = "NDR_".uc($fn->{NAME}); + pidl "case $op: {"; + indent; + pidl "struct $fn->{NAME} *r = (struct $fn->{NAME} *)_r;"; + CallWithStruct("cli->pipes_struct", "mem_ctx", $fn, + sub { pidl "return NT_STATUS_NO_MEMORY;"; }); + pidl "return NT_STATUS_OK;"; + deindent; + pidl "}"; + pidl ""; + } + + pidl "default:"; + pidl "\treturn NT_STATUS_NOT_IMPLEMENTED;"; + deindent; + pidl "}"; + deindent; + pidl "}"; + + pidl ""; +} + sub ParseInterface($) { my $if = shift; @@ -199,7 +269,11 @@ sub ParseInterface($) pidl_hdr "#ifndef __SRV_$uif\__"; pidl_hdr "#define __SRV_$uif\__"; - ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}}); + + foreach (@{$if->{FUNCTIONS}}) { + next if ($_->{PROPERTIES}{noopnum}); + ParseFunction($if, $_); + } pidl ""; pidl "/* Tables */"; @@ -208,6 +282,7 @@ sub ParseInterface($) indent; foreach (@{$if->{FUNCTIONS}}) { + next if ($_->{PROPERTIES}{noopnum}); pidl "{\"" . uc($_->{NAME}) . "\", NDR_" . uc($_->{NAME}) . ", api_$_->{NAME}},"; } @@ -226,10 +301,12 @@ sub ParseInterface($) pidl "}"; pidl ""; + ParseDispatchFunction($if); + pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);"; pidl "NTSTATUS rpc_$if->{NAME}_init(void)"; pidl "{"; - pidl "\treturn rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));"; + pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));"; pidl "}"; pidl_hdr "#endif /* __SRV_$uif\__ */"; @@ -251,7 +328,7 @@ sub Parse($$$) pidl "#include \"$header\""; pidl_hdr "#include \"$ndr_header\""; pidl ""; - + foreach (@$ndr) { ParseInterface($_) if ($_->{TYPE} eq "INTERFACE"); } diff --git a/tools/pidl/lib/Parse/Pidl/Samba4.pm b/tools/pidl/lib/Parse/Pidl/Samba4.pm index 5848543a60..20c518dceb 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4.pm @@ -7,11 +7,12 @@ package Parse::Pidl::Samba4; require Exporter; @ISA = qw(Exporter); -@EXPORT = qw(is_intree choose_header NumStars ElementStars ArrayBrackets DeclLong); +@EXPORT = qw(is_intree choose_header NumStars ElementStars ArrayBrackets DeclLong ArrayDynamicallyAllocated); use Parse::Pidl::Util qw(has_property is_constant); use Parse::Pidl::NDR qw(GetNextLevel); use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference); +use Parse::Pidl qw(fatal error); use strict; use vars qw($VERSION); @@ -35,6 +36,14 @@ sub choose_header($$) return "#include <$out>"; } +sub ArrayDynamicallyAllocated($$) +{ + my ($e, $l) = @_; + die("Not an array") unless ($l->{TYPE} eq "ARRAY"); + return 0 if ($l->{IS_FIXED} and not has_property($e, "charset")); + return 1; +} + sub NumStars($;$) { my ($e, $d) = @_; @@ -56,11 +65,11 @@ sub NumStars($;$) foreach my $l (@{$e->{LEVELS}}) { next unless ($l->{TYPE} eq "ARRAY"); - next if ($l->{IS_FIXED}) and not has_property($e, "charset"); + next unless (ArrayDynamicallyAllocated($e, $l)); $n++; } - fatal($e->{ORIGINAL}, "Too few pointers $n < $d") if ($n < $d); + error($e->{ORIGINAL}, "Too few pointers $n < $d") if ($n < $d); $n -= $d; @@ -86,7 +95,7 @@ sub ArrayBrackets($) foreach my $l (@{$e->{LEVELS}}) { next unless ($l->{TYPE} eq "ARRAY"); - next unless ($l->{IS_FIXED}) and not has_property($e, "charset"); + next if ArrayDynamicallyAllocated($e, $l); $res .= "[$l->{SIZE_IS}]"; } diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm b/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm index 7a6ffa46d6..5315957946 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -6,10 +6,15 @@ package Parse::Pidl::Samba4::Header; +require Exporter; + +@ISA = qw(Exporter); +@EXPORT_OK = qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv); + use strict; use Parse::Pidl qw(fatal); use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference); -use Parse::Pidl::Util qw(has_property is_constant unmake_str); +use Parse::Pidl::Util qw(has_property is_constant unmake_str ParseExpr); use Parse::Pidl::Samba4 qw(is_intree ElementStars ArrayBrackets choose_header); use vars qw($VERSION); @@ -77,10 +82,11 @@ sub HeaderElement($) ##################################################################### # parse a struct -sub HeaderStruct($$) +sub HeaderStruct($$;$) { - my($struct,$name) = @_; + my($struct,$name,$tail) = @_; pidl "struct $name"; + pidl $tail if defined($tail) and not defined($struct->{ELEMENTS}); return if (not defined($struct->{ELEMENTS})); pidl " {\n"; $tab_depth++; @@ -98,35 +104,36 @@ sub HeaderStruct($$) if (defined $struct->{PROPERTIES}) { HeaderProperties($struct->{PROPERTIES}, []); } + pidl $tail if defined($tail); } ##################################################################### # parse a enum -sub HeaderEnum($$) +sub HeaderEnum($$;$) { - my($enum,$name) = @_; + my($enum,$name,$tail) = @_; my $first = 1; - pidl "#ifndef USE_UINT_ENUMS\n"; - pidl "enum $name {\n"; - $tab_depth++; + pidl "enum $name"; if (defined($enum->{ELEMENTS})) { + pidl "\n#ifndef USE_UINT_ENUMS\n"; + pidl " {\n"; + $tab_depth++; foreach my $e (@{$enum->{ELEMENTS}}) { unless ($first) { pidl ",\n"; } $first = 0; pidl tabs(); pidl $e; } - } - pidl "\n"; - $tab_depth--; - pidl "}\n"; - pidl "#else\n"; - my $count = 0; - pidl "enum $name { __donnot_use_enum_$name=0x7FFFFFFF}\n"; - my $with_val = 0; - my $without_val = 0; - if (defined($enum->{ELEMENTS})) { + pidl "\n"; + $tab_depth--; + pidl "}"; + pidl "\n"; + pidl "#else\n"; + my $count = 0; + my $with_val = 0; + my $without_val = 0; + pidl " { __donnot_use_enum_$name=0x7FFFFFFF}\n"; foreach my $e (@{$enum->{ELEMENTS}}) { my $t = "$e"; my $name; @@ -146,8 +153,9 @@ sub HeaderEnum($$) } pidl "#define $name ( $value )\n"; } + pidl "#endif\n"; } - pidl "#endif\n"; + pidl $tail if defined($tail); } ##################################################################### @@ -165,41 +173,49 @@ sub HeaderBitmap($$) ##################################################################### # parse a union -sub HeaderUnion($$) +sub HeaderUnion($$;$) { - my($union,$name) = @_; + my($union,$name,$tail) = @_; my %done = (); pidl "union $name"; + pidl $tail if defined($tail) and not defined($union->{ELEMENTS}); return if (not defined($union->{ELEMENTS})); pidl " {\n"; $tab_depth++; + my $needed = 0; foreach my $e (@{$union->{ELEMENTS}}) { if ($e->{TYPE} ne "EMPTY") { if (! defined $done{$e->{NAME}}) { HeaderElement($e); } $done{$e->{NAME}} = 1; + $needed++; } } + if (!$needed) { + # sigh - some compilers don't like empty structures + pidl tabs()."int _dummy_element;\n"; + } $tab_depth--; pidl "}"; if (defined $union->{PROPERTIES}) { HeaderProperties($union->{PROPERTIES}, []); } + pidl $tail if defined($tail); } ##################################################################### # parse a type -sub HeaderType($$$) +sub HeaderType($$$;$) { - my($e,$data,$name) = @_; + my($e,$data,$name,$tail) = @_; if (ref($data) eq "HASH") { - ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name); + ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name, $tail); ($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name); - ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name); - ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name); + ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name, $tail); + ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name, $tail); return; } @@ -208,14 +224,17 @@ sub HeaderType($$$) } else { pidl mapTypeName($e->{TYPE}); } + pidl $tail if defined($tail); } ##################################################################### # parse a typedef -sub HeaderTypedef($) +sub HeaderTypedef($;$) { - my($typedef) = shift; - HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME}); + my($typedef,$tail) = @_; + # Don't print empty "enum foo;", since some compilers don't like it. + return if ($typedef->{DATA}->{TYPE} eq "ENUM" and not defined($typedef->{DATA}->{ELEMENTS})); + HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME}, $tail) if defined ($typedef->{DATA}); } ##################################################################### @@ -323,10 +342,10 @@ sub HeaderFunction($) sub HeaderImport { my @imports = @_; - foreach (@imports) { - s/\.idl\"$//; - s/^\"//; - pidl choose_header("librpc/gen_ndr/$_\.h", "gen_ndr/$_.h") . "\n"; + foreach my $import (@imports) { + $import = unmake_str($import); + $import =~ s/\.idl$//; + pidl choose_header("librpc/gen_ndr/$import\.h", "gen_ndr/$import.h") . "\n"; } } @@ -352,16 +371,11 @@ sub HeaderInterface($) } foreach my $t (@{$interface->{TYPES}}) { - HeaderTypedef($t) if ($t->{TYPE} eq "TYPEDEF"); - HeaderStruct($t, $t->{NAME}) if ($t->{TYPE} eq "STRUCT"); - HeaderUnion($t, $t->{NAME}) if ($t->{TYPE} eq "UNION"); - HeaderEnum($t, $t->{NAME}) if ($t->{TYPE} eq "ENUM"); + HeaderTypedef($t, ";\n\n") if ($t->{TYPE} eq "TYPEDEF"); + HeaderStruct($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "STRUCT"); + HeaderUnion($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "UNION"); + HeaderEnum($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "ENUM"); HeaderBitmap($t, $t->{NAME}) if ($t->{TYPE} eq "BITMAP"); - pidl ";\n\n" if ($t->{TYPE} eq "BITMAP" or - $t->{TYPE} eq "STRUCT" or - $t->{TYPE} eq "TYPEDEF" or - $t->{TYPE} eq "UNION" or - $t->{TYPE} eq "ENUM"); } foreach my $fn (@{$interface->{FUNCTIONS}}) { @@ -393,6 +407,9 @@ sub Parse($) } pidl "#include <stdint.h>\n"; pidl "\n"; + # FIXME: Include this only if NTSTATUS was actually used + pidl choose_header("libcli/util/ntstatus.h", "core/ntstatus.h") . "\n"; + pidl "\n"; foreach (@{$ndr}) { ($_->{TYPE} eq "CPP_QUOTE") && HeaderQuote($_); @@ -404,4 +421,66 @@ sub Parse($) return $res; } +sub GenerateStructEnv($$) +{ + my ($x, $v) = @_; + my %env; + + foreach my $e (@{$x->{ELEMENTS}}) { + $env{$e->{NAME}} = "$v->$e->{NAME}"; + } + + $env{"this"} = $v; + + return \%env; +} + +sub EnvSubstituteValue($$) +{ + my ($env,$s) = @_; + + # Substitute the value() values in the env + foreach my $e (@{$s->{ELEMENTS}}) { + next unless (defined(my $v = has_property($e, "value"))); + + $env->{$e->{NAME}} = ParseExpr($v, $env, $e); + } + + return $env; +} + +sub GenerateFunctionInEnv($;$) +{ + my ($fn, $base) = @_; + my %env; + + $base = "r->" unless defined($base); + + foreach my $e (@{$fn->{ELEMENTS}}) { + if (grep (/in/, @{$e->{DIRECTION}})) { + $env{$e->{NAME}} = $base."in.$e->{NAME}"; + } + } + + return \%env; +} + +sub GenerateFunctionOutEnv($;$) +{ + my ($fn, $base) = @_; + my %env; + + $base = "r->" unless defined($base); + + foreach my $e (@{$fn->{ELEMENTS}}) { + if (grep (/out/, @{$e->{DIRECTION}})) { + $env{$e->{NAME}} = $base."out.$e->{NAME}"; + } elsif (grep (/in/, @{$e->{DIRECTION}})) { + $env{$e->{NAME}} = $base."in.$e->{NAME}"; + } + } + + return \%env; +} + 1; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm index e9c158e933..9d3ccaf8c8 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm @@ -7,6 +7,7 @@ package Parse::Pidl::Samba4::NDR::Client; use Parse::Pidl::Samba4 qw(choose_header is_intree); +use Parse::Pidl::Util qw(has_property); use vars qw($VERSION); $VERSION = '0.01'; @@ -15,37 +16,55 @@ use strict; my($res,$res_hdr); -##################################################################### -# parse a function -sub ParseFunction($$) +sub ParseFunctionSend($$$) { - my ($interface, $fn) = @_; - my $name = $fn->{NAME}; + my ($interface, $fn, $name) = @_; my $uname = uc $name; - $res_hdr .= "\nstruct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r); -NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r); -"; + my $proto = "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)"; - $res .= " -struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r) -{ + $res_hdr .= "\n$proto;\n"; + + $res .= "$proto\n{\n"; + + if (has_property($fn, "todo")) { + $res .= "\treturn NULL;\n"; + } else { + $res .= " if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) { NDR_PRINT_IN_DEBUG($name, r); } - - return dcerpc_ndr_request_send(p, NULL, &ndr_table_$interface->{NAME}, NDR_$uname, mem_ctx, r); + + return dcerpc_ndr_request_send(p, NULL, &ndr_table_$interface->{NAME}, + NDR_$uname, true, mem_ctx, r); +"; + } + + $res .= "}\n\n"; } -NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r) +sub ParseFunctionSync($$$) { - struct rpc_request *req; + my ($interface, $fn, $name) = @_; + my $uname = uc $name; + + my $proto = "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)"; + + $res_hdr .= "\n$proto;\n"; + $res .= "$proto\n{\n"; + + if (has_property($fn, "todo")) { + $res .= "\treturn NT_STATUS_NOT_IMPLEMENTED;\n"; + } else { + $res .= " NTSTATUS status; - - req = dcerpc_$name\_send(p, mem_ctx, r); - if (req == NULL) return NT_STATUS_NO_MEMORY; - status = dcerpc_ndr_request_recv(req); + if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) { + NDR_PRINT_IN_DEBUG($name, r); + } + + status = dcerpc_ndr_request(p, NULL, &ndr_table_$interface->{NAME}, + NDR_$uname, mem_ctx, r); if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) { NDR_PRINT_OUT_DEBUG($name, r); @@ -58,8 +77,20 @@ NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name * $res .= " return status; -} "; + } + + $res .= "}\n\n"; +} + +##################################################################### +# parse a function +sub ParseFunction($$) +{ + my ($interface, $fn) = @_; + + ParseFunctionSend($interface, $fn, $fn->{NAME}); + ParseFunctionSync($interface, $fn, $fn->{NAME}); } my %done; @@ -103,7 +134,9 @@ sub Parse($$$$) if (is_intree()) { $res .= "#include \"includes.h\"\n"; } else { + $res .= "#ifndef _GNU_SOURCE\n"; $res .= "#define _GNU_SOURCE\n"; + $res .= "#endif\n"; $res .= "#include <stdio.h>\n"; $res .= "#include <stdbool.h>\n"; $res .= "#include <stdlib.h>\n"; diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index c9b48b017c..3e724c986d 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -9,13 +9,15 @@ package Parse::Pidl::Samba4::NDR::Parser; require Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(check_null_pointer GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint); +@EXPORT_OK = qw(check_null_pointer NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint); use strict; -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); +use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody); +use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid unmake_str); +use Parse::Pidl::CUtil qw(get_pointer_to get_value_of get_array_element); +use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array); +use Parse::Pidl::Samba4 qw(is_intree choose_header ArrayDynamicallyAllocated); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv); use Parse::Pidl qw(warning); use vars qw($VERSION); @@ -40,19 +42,21 @@ sub append_prefix($$) { my ($e, $var_name) = @_; my $pointers = 0; + my $arrays = 0; foreach my $l (@{$e->{LEVELS}}) { if ($l->{TYPE} eq "POINTER") { $pointers++; } elsif ($l->{TYPE} eq "ARRAY") { + $arrays++; if (($pointers == 0) and (not $l->{IS_FIXED}) and (not $l->{IS_INLINE})) { - return get_value_of($var_name); + return get_value_of($var_name); } } elsif ($l->{TYPE} eq "DATA") { if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { - return get_value_of($var_name) unless ($pointers); + return get_value_of($var_name) unless ($pointers or $arrays); } } } @@ -76,42 +80,6 @@ sub has_fast_array($$) return ($t->{NAME} eq "uint8") or ($t->{NAME} eq "string"); } -sub is_charset_array($$) -{ - my ($e,$l) = @_; - - return 0 if ($l->{TYPE} ne "ARRAY"); - - my $nl = GetNextLevel($e,$l); - - return 0 unless ($nl->{TYPE} eq "DATA"); - - return has_property($e, "charset"); -} - -sub get_pointer_to($) -{ - my $var_name = shift; - - if ($var_name =~ /^\*(.*)$/) { - return $1; - } elsif ($var_name =~ /^\&(.*)$/) { - return "&($var_name)"; - } else { - return "&$var_name"; - } -} - -sub get_value_of($) -{ - my $var_name = shift; - - if ($var_name =~ /^\&(.*)$/) { - return $1; - } else { - return "*$var_name"; - } -} #################################### # pidl() is our basic output routine @@ -190,93 +158,31 @@ sub fn_declare($$$$) ################################################################### # setup any special flags for an element or structure -sub start_flags($$) +sub start_flags($$$) { - my ($self, $e) = @_; + my ($self, $e, $ndr) = @_; my $flags = has_property($e, "flag"); if (defined $flags) { $self->pidl("{"); $self->indent; - $self->pidl("uint32_t _flags_save_$e->{TYPE} = ndr->flags;"); - $self->pidl("ndr_set_flags(&ndr->flags, $flags);"); + $self->pidl("uint32_t _flags_save_$e->{TYPE} = $ndr->flags;"); + $self->pidl("ndr_set_flags(&$ndr->flags, $flags);"); } } ################################################################### # end any special flags for an element or structure -sub end_flags($$) +sub end_flags($$$) { - my ($self, $e) = @_; + my ($self, $e, $ndr) = @_; my $flags = has_property($e, "flag"); if (defined $flags) { - $self->pidl("ndr->flags = _flags_save_$e->{TYPE};"); + $self->pidl("$ndr->flags = _flags_save_$e->{TYPE};"); $self->deindent; $self->pidl("}"); } } -sub GenerateStructEnv($$) -{ - my ($x, $v) = @_; - my %env; - - foreach my $e (@{$x->{ELEMENTS}}) { - $env{$e->{NAME}} = "$v->$e->{NAME}"; - } - - $env{"this"} = $v; - - return \%env; -} - -sub EnvSubstituteValue($$) -{ - my ($env,$s) = @_; - - # Substitute the value() values in the env - foreach my $e (@{$s->{ELEMENTS}}) { - next unless (defined(my $v = has_property($e, "value"))); - - $env->{$e->{NAME}} = ParseExpr($v, $env, $e); - } - - return $env; -} - -sub GenerateFunctionInEnv($;$) -{ - my ($fn, $base) = @_; - my %env; - - $base = "r->" unless defined($base); - - foreach my $e (@{$fn->{ELEMENTS}}) { - if (grep (/in/, @{$e->{DIRECTION}})) { - $env{$e->{NAME}} = $base."in.$e->{NAME}"; - } - } - - return \%env; -} - -sub GenerateFunctionOutEnv($;$) -{ - my ($fn, $base) = @_; - my %env; - - $base = "r->" unless defined($base); - - foreach my $e (@{$fn->{ELEMENTS}}) { - if (grep (/out/, @{$e->{DIRECTION}})) { - $env{$e->{NAME}} = $base."out.$e->{NAME}"; - } elsif (grep (/in/, @{$e->{DIRECTION}})) { - $env{$e->{NAME}} = $base."in.$e->{NAME}"; - } - } - - return \%env; -} - ##################################################################### # parse the data of an array - push side sub ParseArrayPushHeader($$$$$$) @@ -420,17 +326,17 @@ sub ParseArrayPullHeader($$$$$$) if ($l->{IS_CONFORMANT}) { $length = $size = "ndr_get_array_size($ndr, " . get_pointer_to($var_name) . ")"; - } elsif ($l->{IS_ZERO_TERMINATED}) { # Noheader arrays + } elsif ($l->{IS_ZERO_TERMINATED} and $l->{SIZE_IS} == 0 and $l->{LENGTH_IS} == 0) { # Noheader arrays $length = $size = "ndr_get_string_size($ndr, sizeof(*$var_name))"; } else { $length = $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, - "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"), + "return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"), check_fully_dereferenced($e, $env)); } if ((!$l->{IS_SURROUNDING}) and $l->{IS_CONFORMANT}) { - $self->pidl("NDR_CHECK(ndr_pull_array_size(ndr, " . get_pointer_to($var_name) . "));"); + $self->pidl("NDR_CHECK(ndr_pull_array_size($ndr, " . get_pointer_to($var_name) . "));"); } if ($l->{IS_VARYING}) { @@ -451,9 +357,9 @@ sub ParseArrayPullHeader($$$$$$) $self->defer_indent; my $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->defer(shift); }, - "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"), + "return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"), check_fully_dereferenced($e, $env)); - $self->defer("NDR_CHECK(ndr_check_array_size(ndr, (void*)" . get_pointer_to($var_name) . ", $size));"); + $self->defer("NDR_CHECK(ndr_check_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));"); $self->defer_deindent; $self->defer("}"); } @@ -463,15 +369,15 @@ sub ParseArrayPullHeader($$$$$$) $self->defer_indent; my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->defer(shift); }, - "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for length_is()\");"), + "return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for length_is()\");"), check_fully_dereferenced($e, $env)); - $self->defer("NDR_CHECK(ndr_check_array_length(ndr, (void*)" . get_pointer_to($var_name) . ", $length));"); + $self->defer("NDR_CHECK(ndr_check_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", $length));"); $self->defer_deindent; $self->defer("}"); } - if (not $l->{IS_FIXED} and not is_charset_array($e, $l)) { - $self->AllocateArrayLevel($e,$l,$ndr,$env,$size); + if (ArrayDynamicallyAllocated($e,$l) and not is_charset_array($e,$l)) { + $self->AllocateArrayLevel($e,$l,$ndr,$var_name,$size); } return $length; @@ -480,7 +386,7 @@ sub ParseArrayPullHeader($$$$$$) sub compression_alg($$) { my ($e, $l) = @_; - my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION}); + my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION}); return $alg; } @@ -488,7 +394,7 @@ sub compression_alg($$) sub compression_clen($$$) { my ($e, $l, $env) = @_; - my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION}); + my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION}); return ParseExpr($clen, $env, $e->{ORIGINAL}); } @@ -496,7 +402,7 @@ sub compression_clen($$$) sub compression_dlen($$$) { my ($e,$l,$env) = @_; - my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION}); + my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION}); return ParseExpr($dlen, $env, $e->{ORIGINAL}); } @@ -637,7 +543,7 @@ sub ParseElementPushLevel $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $subndr, $var_name, $env, 1, 1); $self->ParseSubcontextPushEnd($e, $l, $ndr, $env); } elsif ($l->{TYPE} eq "POINTER") { - $self->ParsePtrPush($e, $l, $var_name); + $self->ParsePtrPush($e, $l, $ndr, $var_name); } elsif ($l->{TYPE} eq "ARRAY") { my $length = $self->ParseArrayPushHeader($e, $l, $ndr, $var_name, $env); @@ -655,6 +561,8 @@ sub ParseElementPushLevel $self->ParseSwitchPush($e, $l, $ndr, $var_name, $env); } elsif ($l->{TYPE} eq "DATA") { $self->ParseDataPush($e, $l, $ndr, $var_name, $primitives, $deferred); + } elsif ($l->{TYPE} eq "TYPEDEF") { + $typefamily{$e->{DATA}->{TYPE}}->{PUSH_FN_BODY}->($self, $e->{DATA}, $ndr, $var_name); } } @@ -663,7 +571,7 @@ sub ParseElementPushLevel $self->pidl("if ($var_name) {"); $self->indent; if ($l->{POINTER_TYPE} eq "relative") { - $self->pidl("NDR_CHECK(ndr_push_relative_ptr2(ndr, $var_name));"); + $self->pidl("NDR_CHECK(ndr_push_relative_ptr2($ndr, $var_name));"); } } $var_name = get_value_of($var_name); @@ -678,9 +586,15 @@ sub ParseElementPushLevel my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL}); my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}"; - $var_name = $var_name . "[$counter]"; + my $array_pointless = ($length eq "0"); - if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) { + if ($array_pointless) { + warning($e->{ORIGINAL}, "pointless array `$e->{NAME}' will always have size 0"); + } + + $var_name = get_array_element($var_name, $counter); + + if ((($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) and not $array_pointless) { $self->pidl("for ($counter = 0; $counter < $length; $counter++) {"); $self->indent; $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 1, 0); @@ -688,7 +602,7 @@ sub ParseElementPushLevel $self->pidl("}"); } - if ($deferred and ContainsDeferred($e, $l)) { + if ($deferred and ContainsDeferred($e, $l) and not $array_pointless) { $self->pidl("for ($counter = 0; $counter < $length; $counter++) {"); $self->indent; $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 0, 1); @@ -723,7 +637,7 @@ sub ParseElementPush($$$$$$) $var_name = append_prefix($e, $var_name); - $self->start_flags($e); + $self->start_flags($e, $ndr); if (defined(my $value = has_property($e, "value"))) { $var_name = ParseExpr($value, $env, $e->{ORIGINAL}); @@ -731,7 +645,7 @@ sub ParseElementPush($$$$$$) $self->ParseElementPushLevel($e, $e->{LEVELS}[0], $ndr, $var_name, $env, $primitives, $deferred); - $self->end_flags($e); + $self->end_flags($e, $ndr); if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { $self->deindent; @@ -741,75 +655,100 @@ sub ParseElementPush($$$$$$) ##################################################################### # parse a pointer in a struct element or function -sub ParsePtrPush($$$$) +sub ParsePtrPush($$$$$) { - my ($self,$e,$l,$var_name) = @_; + my ($self,$e,$l,$ndr,$var_name) = @_; if ($l->{POINTER_TYPE} eq "ref") { $self->pidl("if ($var_name == NULL) {"); $self->indent; - $self->pidl("return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");"); + $self->pidl("return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");"); $self->deindent; $self->pidl("}"); if ($l->{LEVEL} eq "EMBEDDED") { $self->pidl("NDR_CHECK(ndr_push_ref_ptr(ndr));"); } } elsif ($l->{POINTER_TYPE} eq "relative") { - $self->pidl("NDR_CHECK(ndr_push_relative_ptr1(ndr, $var_name));"); + $self->pidl("NDR_CHECK(ndr_push_relative_ptr1($ndr, $var_name));"); } elsif ($l->{POINTER_TYPE} eq "unique") { - $self->pidl("NDR_CHECK(ndr_push_unique_ptr(ndr, $var_name));"); + $self->pidl("NDR_CHECK(ndr_push_unique_ptr($ndr, $var_name));"); } elsif ($l->{POINTER_TYPE} eq "full") { - $self->pidl("NDR_CHECK(ndr_push_full_ptr(ndr, $var_name));"); + $self->pidl("NDR_CHECK(ndr_push_full_ptr($ndr, $var_name));"); } else { die("Unhandled pointer type $l->{POINTER_TYPE}"); } } -sub ParseDataPrint($$$$) +sub need_pointer_to($$$) { - my ($self, $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}; + my ($e, $l, $scalar_only) = @_; + + 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)) { + return 1 if $scalar_only; + } + + my $arrays = 0; + + foreach my $tl (@{$e->{LEVELS}}) { + last if $l == $tl; + if ($tl->{TYPE} eq "ARRAY") { + $arrays++; } - if (not Parse::Pidl::Typelist::is_scalar($t) or - Parse::Pidl::Typelist::scalar_is_reference($t)) { + } + + if (Parse::Pidl::Typelist::scalar_is_reference($t)) { + return 1 unless $arrays; + } + + return 0; +} + +sub ParseDataPrint($$$$$) +{ + my ($self, $e, $l, $ndr, $var_name) = @_; + + if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) { + + if (need_pointer_to($e, $l, 1)) { $var_name = get_pointer_to($var_name); } - $self->pidl("ndr_print_$t(ndr, \"$e->{NAME}\", $var_name);"); + + $self->pidl(TypeFunctionName("ndr_print", $l->{DATA_TYPE})."($ndr, \"$e->{NAME}\", $var_name);"); } else { - $self->ParseTypePrint($l->{DATA_TYPE}, $var_name); + $self->ParseTypePrint($l->{DATA_TYPE}, $ndr, $var_name); } } ##################################################################### # print scalars in a structure element -sub ParseElementPrint($$$$) +sub ParseElementPrint($$$$$) { - my($self, $e, $var_name, $env) = @_; + my($self, $e, $ndr, $var_name, $env) = @_; return if (has_property($e, "noprint")); if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { - $self->pidl("ndr_print_$e->{REPRESENTATION_TYPE}(ndr, \"$e->{NAME}\", $var_name);"); + $self->pidl("ndr_print_$e->{REPRESENTATION_TYPE}($ndr, \"$e->{NAME}\", $var_name);"); return; } $var_name = append_prefix($e, $var_name); if (defined(my $value = has_property($e, "value"))) { - $var_name = "(ndr->flags & LIBNDR_PRINT_SET_VALUES)?" . ParseExpr($value,$env, $e->{ORIGINAL}) . ":$var_name"; + $var_name = "($ndr->flags & LIBNDR_PRINT_SET_VALUES)?" . ParseExpr($value,$env, $e->{ORIGINAL}) . ":$var_name"; } foreach my $l (@{$e->{LEVELS}}) { if ($l->{TYPE} eq "POINTER") { - $self->pidl("ndr_print_ptr(ndr, \"$e->{NAME}\", $var_name);"); - $self->pidl("ndr->depth++;"); + $self->pidl("ndr_print_ptr($ndr, \"$e->{NAME}\", $var_name);"); + $self->pidl("$ndr->depth++;"); if ($l->{POINTER_TYPE} ne "ref") { $self->pidl("if ($var_name) {"); $self->indent; @@ -830,32 +769,31 @@ sub ParseElementPrint($$$$) } if (is_charset_array($e,$l)) { - $self->pidl("ndr_print_string(ndr, \"$e->{NAME}\", $var_name);"); + $self->pidl("ndr_print_string($ndr, \"$e->{NAME}\", $var_name);"); last; } elsif (has_fast_array($e, $l)) { my $nl = GetNextLevel($e, $l); - $self->pidl("ndr_print_array_$nl->{DATA_TYPE}(ndr, \"$e->{NAME}\", $var_name, $length);"); + $self->pidl("ndr_print_array_$nl->{DATA_TYPE}($ndr, \"$e->{NAME}\", $var_name, $length);"); last; } else { my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}"; - $self->pidl("ndr->print(ndr, \"\%s: ARRAY(\%d)\", \"$e->{NAME}\", $length);"); - $self->pidl("ndr->depth++;"); + $self->pidl("$ndr->print($ndr, \"\%s: ARRAY(\%d)\", \"$e->{NAME}\", (int)$length);"); + $self->pidl("$ndr->depth++;"); $self->pidl("for ($counter=0;$counter<$length;$counter++) {"); $self->indent; $self->pidl("char *idx_$l->{LEVEL_INDEX}=NULL;"); - $self->pidl("asprintf(&idx_$l->{LEVEL_INDEX}, \"[\%d]\", $counter);"); - $self->pidl("if (idx_$l->{LEVEL_INDEX}) {"); + $self->pidl("if (asprintf(&idx_$l->{LEVEL_INDEX}, \"[\%d]\", $counter) != -1) {"); $self->indent; - $var_name = $var_name . "[$counter]"; + $var_name = get_array_element($var_name, $counter); } } elsif ($l->{TYPE} eq "DATA") { - $self->ParseDataPrint($e, $l, $var_name); + $self->ParseDataPrint($e, $l, $ndr, $var_name); } elsif ($l->{TYPE} eq "SWITCH") { my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return;"), check_fully_dereferenced($e, $env)); - $self->pidl("ndr_print_set_switch_value(ndr, " . get_pointer_to($var_name) . ", $switch_var);"); + $self->pidl("ndr_print_set_switch_value($ndr, " . get_pointer_to($var_name) . ", $switch_var);"); } } @@ -865,7 +803,7 @@ sub ParseElementPrint($$$$) $self->deindent; $self->pidl("}"); } - $self->pidl("ndr->depth--;"); + $self->pidl("$ndr->depth--;"); } elsif (($l->{TYPE} eq "ARRAY") and not is_charset_array($e,$l) and not has_fast_array($e,$l)) { @@ -874,7 +812,7 @@ sub ParseElementPrint($$$$) $self->pidl("}"); $self->deindent; $self->pidl("}"); - $self->pidl("ndr->depth--;"); + $self->pidl("$ndr->depth--;"); } } } @@ -886,7 +824,7 @@ sub ParseSwitchPull($$$$$$) my($self,$e,$l,$ndr,$var_name,$env) = @_; my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, - "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"), + "return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"), check_fully_dereferenced($e, $env)); $var_name = get_pointer_to($var_name); @@ -900,7 +838,7 @@ sub ParseSwitchPush($$$$$$) my($self,$e,$l,$ndr,$var_name,$env) = @_; my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, - "return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"), + "return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"), check_fully_dereferenced($e, $env)); $var_name = get_pointer_to($var_name); @@ -911,12 +849,11 @@ sub ParseDataPull($$$$$$$) { my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_; - if (not ref($l->{DATA_TYPE}) or - defined($l->{DATA_TYPE}->{NAME})) { + if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) { my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred); - if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { + if (need_pointer_to($e, $l, 0)) { $var_name = get_pointer_to($var_name); } @@ -926,13 +863,21 @@ sub ParseDataPull($$$$$$$) if (my $range = has_property($e, "range")) { $var_name = get_value_of($var_name); - my ($low, $high) = split(/ /, $range, 2); - $self->pidl("if ($var_name < $low || $var_name > $high) {"); + my $signed = Parse::Pidl::Typelist::is_signed($l->{DATA_TYPE}); + my ($low, $high) = split(/,/, $range, 2); + if ($low < 0 and not $signed) { + warning(0, "$low is invalid for the range of an unsigned type"); + } + if ($low == 0 and not $signed) { + $self->pidl("if ($var_name > $high) {"); + } else { + $self->pidl("if ($var_name < $low || $var_name > $high) {"); + } $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");"); $self->pidl("}"); } } else { - $self->ParseTypePull($l->{DATA_TYPE}, $var_name, $primitives, $deferred); + $self->ParseTypePull($l->{DATA_TYPE}, $ndr, $var_name, $primitives, $deferred); } } @@ -941,23 +886,17 @@ sub ParseDataPush($$$$$$$) my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_; 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}; - } - + + my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred); + # strings are passed by value rather than reference - if (not Parse::Pidl::Typelist::is_scalar($t) or - Parse::Pidl::Typelist::scalar_is_reference($t)) { + if (need_pointer_to($e, $l, 1)) { $var_name = get_pointer_to($var_name); } - my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred); - $self->pidl("NDR_CHECK(ndr_push_$t($ndr, $ndr_flags, $var_name));"); + $self->pidl("NDR_CHECK(".TypeFunctionName("ndr_push", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));"); } else { - $self->ParseTypePush($l->{DATA_TYPE}, $var_name, $primitives, $deferred); + $self->ParseTypePush($l->{DATA_TYPE}, $ndr, $var_name, $primitives, $deferred); } } @@ -986,15 +925,17 @@ sub CalcNdrFlags($$$) return undef; } -sub ParseMemCtxPullStart($$$$) +sub ParseMemCtxPullFlags($$$$) { - my ($self, $e, $l, $ptr_name) = @_; + my ($self, $e, $l) = @_; - my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}"; - my $mem_c_ctx = $ptr_name; - my $mem_c_flags = "0"; + return undef unless ($l->{TYPE} eq "POINTER" or $l->{TYPE} eq "ARRAY"); + + return undef unless ($l->{TYPE} ne "ARRAY" or ArrayDynamicallyAllocated($e,$l)); + return undef if has_fast_array($e, $l); + return undef if is_charset_array($e, $l); - return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED}); + my $mem_flags = "0"; if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) { my $nl = GetNextLevel($e, $l); @@ -1002,38 +943,39 @@ sub ParseMemCtxPullStart($$$$) my $next_is_string = (($nl->{TYPE} eq "DATA") and ($nl->{DATA_TYPE} eq "string")); if ($next_is_array or $next_is_string) { - return; - } else { - $mem_c_flags = "LIBNDR_FLAG_REF_ALLOC"; + return undef; + } elsif ($l->{LEVEL} eq "TOP") { + $mem_flags = "LIBNDR_FLAG_REF_ALLOC"; } } - $self->pidl("$mem_r_ctx = NDR_PULL_GET_MEM_CTX(ndr);"); - $self->pidl("NDR_PULL_SET_MEM_CTX(ndr, $mem_c_ctx, $mem_c_flags);"); + return $mem_flags; } -sub ParseMemCtxPullEnd($$$) +sub ParseMemCtxPullStart($$$$$) { - my ($self, $e, $l) = @_; + my ($self, $e, $l, $ndr, $ptr_name) = @_; my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}"; - my $mem_r_flags = "0"; + my $mem_c_ctx = $ptr_name; + my $mem_c_flags = $self->ParseMemCtxPullFlags($e, $l); - return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED}); + return unless defined($mem_c_flags); - if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) { - my $nl = GetNextLevel($e, $l); - my $next_is_array = ($nl->{TYPE} eq "ARRAY"); - my $next_is_string = (($nl->{TYPE} eq "DATA") and - ($nl->{DATA_TYPE} eq "string")); - if ($next_is_array or $next_is_string) { - return; - } else { - $mem_r_flags = "LIBNDR_FLAG_REF_ALLOC"; - } - } + $self->pidl("$mem_r_ctx = NDR_PULL_GET_MEM_CTX($ndr);"); + $self->pidl("NDR_PULL_SET_MEM_CTX($ndr, $mem_c_ctx, $mem_c_flags);"); +} - $self->pidl("NDR_PULL_SET_MEM_CTX(ndr, $mem_r_ctx, $mem_r_flags);"); +sub ParseMemCtxPullEnd($$$$) +{ + my ($self, $e, $l, $ndr) = @_; + + my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}"; + my $mem_r_flags = $self->ParseMemCtxPullFlags($e, $l); + + return unless defined($mem_r_flags); + + $self->pidl("NDR_PULL_SET_MEM_CTX($ndr, $mem_r_ctx, $mem_r_flags);"); } sub CheckStringTerminator($$$$$) @@ -1085,6 +1027,8 @@ sub ParseElementPullLevel $self->ParseSwitchPull($e, $l, $ndr, $var_name, $env); } elsif ($l->{TYPE} eq "DATA") { $self->ParseDataPull($e, $l, $ndr, $var_name, $primitives, $deferred); + } elsif ($l->{TYPE} eq "TYPEDEF") { + $typefamily{$e->{DATA}->{TYPE}}->{PULL_FN_BODY}->($self, $e->{DATA}, $ndr, $var_name); } } @@ -1096,21 +1040,21 @@ sub ParseElementPullLevel if ($l->{POINTER_TYPE} eq "relative") { $self->pidl("uint32_t _relative_save_offset;"); - $self->pidl("_relative_save_offset = ndr->offset;"); - $self->pidl("NDR_CHECK(ndr_pull_relative_ptr2(ndr, $var_name));"); + $self->pidl("_relative_save_offset = $ndr->offset;"); + $self->pidl("NDR_CHECK(ndr_pull_relative_ptr2($ndr, $var_name));"); } } - $self->ParseMemCtxPullStart($e, $l, $var_name); + $self->ParseMemCtxPullStart($e, $l, $ndr, $var_name); $var_name = get_value_of($var_name); $self->ParseElementPullLevel($e, GetNextLevel($e,$l), $ndr, $var_name, $env, 1, 1); - $self->ParseMemCtxPullEnd($e,$l); + $self->ParseMemCtxPullEnd($e, $l, $ndr); if ($l->{POINTER_TYPE} ne "ref") { if ($l->{POINTER_TYPE} eq "relative") { - $self->pidl("ndr->offset = _relative_save_offset;"); + $self->pidl("$ndr->offset = _relative_save_offset;"); } $self->deindent; $self->pidl("}"); @@ -1121,9 +1065,13 @@ sub ParseElementPullLevel my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}"; my $array_name = $var_name; - $var_name = $var_name . "[$counter]"; + if ($l->{IS_VARYING}) { + $length = "ndr_get_array_length($ndr, " . get_pointer_to($var_name) .")"; + } - $self->ParseMemCtxPullStart($e, $l, $array_name); + $var_name = get_array_element($var_name, $counter); + + $self->ParseMemCtxPullStart($e, $l, $ndr, $array_name); if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) { my $nl = GetNextLevel($e,$l); @@ -1147,7 +1095,7 @@ sub ParseElementPullLevel $self->pidl("}"); } - $self->ParseMemCtxPullEnd($e, $l); + $self->ParseMemCtxPullEnd($e, $l, $ndr); } elsif ($l->{TYPE} eq "SWITCH") { $self->ParseElementPullLevel($e, GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred); @@ -1177,11 +1125,11 @@ sub ParseElementPull($$$$$$) $var_name = append_prefix($e, $var_name); - $self->start_flags($e); + $self->start_flags($e, $ndr); $self->ParseElementPullLevel($e,$e->{LEVELS}[0],$ndr,$var_name,$env,$primitives,$deferred); - $self->end_flags($e); + $self->end_flags($e, $ndr); # Representation type is different from transmit_as if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { @@ -1202,28 +1150,28 @@ sub ParsePtrPull($$$$$) my $next_is_string = (($nl->{TYPE} eq "DATA") and ($nl->{DATA_TYPE} eq "string")); - if ($l->{POINTER_TYPE} eq "ref") { - if ($l->{LEVEL} eq "EMBEDDED") { - $self->pidl("NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));"); - } + if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP") { if (!$next_is_array and !$next_is_string) { - $self->pidl("if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {"); + $self->pidl("if ($ndr->flags & LIBNDR_FLAG_REF_ALLOC) {"); $self->pidl("\tNDR_PULL_ALLOC($ndr, $var_name);"); $self->pidl("}"); } return; + } elsif ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "EMBEDDED") { + $self->pidl("NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));"); } elsif (($l->{POINTER_TYPE} eq "unique") or ($l->{POINTER_TYPE} eq "relative") or ($l->{POINTER_TYPE} eq "full")) { $self->pidl("NDR_CHECK(ndr_pull_generic_ptr($ndr, &_ptr_$e->{NAME}));"); - $self->pidl("if (_ptr_$e->{NAME}) {"); - $self->indent; } else { die("Unhandled pointer type $l->{POINTER_TYPE}"); } + $self->pidl("if (_ptr_$e->{NAME}) {"); + $self->indent; + # Don't do this for arrays, they're allocated at the actual level # of the array unless ($next_is_array or $next_is_string) { @@ -1246,9 +1194,9 @@ sub ParsePtrPull($$$$$) $self->pidl("}"); } -sub ParseStructPushPrimitives($$$$) +sub ParseStructPushPrimitives($$$$$) { - my ($self, $struct, $varname, $env) = @_; + my ($self, $struct, $ndr, $varname, $env) = @_; # see if the structure contains a conformant array. If it # does, then it must be the last element of the structure, and @@ -1272,39 +1220,39 @@ sub ParseStructPushPrimitives($$$$) $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL}); } - $self->pidl("NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));"); + $self->pidl("NDR_CHECK(ndr_push_uint32($ndr, NDR_SCALARS, $size));"); } else { - $self->pidl("NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, $varname->$e->{NAME})));"); + $self->pidl("NDR_CHECK(ndr_push_uint32($ndr, NDR_SCALARS, ndr_string_array_size($ndr, $varname->$e->{NAME})));"); } } - $self->pidl("NDR_CHECK(ndr_push_align(ndr, $struct->{ALIGN}));"); + $self->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 - $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, $varname, ndr->offset));"); + $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset1($ndr, $varname, $ndr->offset));"); } - $self->ParseElementPush($_, "ndr", $env, 1, 0) foreach (@{$struct->{ELEMENTS}}); + $self->ParseElementPush($_, $ndr, $env, 1, 0) foreach (@{$struct->{ELEMENTS}}); } -sub ParseStructPushDeferred($$$) +sub ParseStructPushDeferred($$$$) { - my ($self, $struct, $varname, $env) = @_; + my ($self, $struct, $ndr, $varname, $env) = @_; if (defined($struct->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union - $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, $varname));"); + $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset2($ndr, $varname));"); } - $self->ParseElementPush($_, "ndr", $env, 0, 1) foreach (@{$struct->{ELEMENTS}}); + $self->ParseElementPush($_, $ndr, $env, 0, 1) foreach (@{$struct->{ELEMENTS}}); } ##################################################################### # parse a struct -sub ParseStructPush($$$) +sub ParseStructPush($$$$) { - my ($self, $struct, $varname) = @_; + my ($self, $struct, $ndr, $varname) = @_; return unless defined($struct->{ELEMENTS}); @@ -1312,63 +1260,63 @@ sub ParseStructPush($$$) EnvSubstituteValue($env, $struct); - $self->DeclareArrayVariables($_) foreach (@{$struct->{ELEMENTS}}); + $self->DeclareArrayVariablesNoZero($_, $env) foreach (@{$struct->{ELEMENTS}}); - $self->start_flags($struct); + $self->start_flags($struct, $ndr); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; - $self->ParseStructPushPrimitives($struct, $varname, $env); + $self->ParseStructPushPrimitives($struct, $ndr, $varname, $env); $self->deindent; $self->pidl("}"); $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); $self->indent; - $self->ParseStructPushDeferred($struct, $varname, $env); + $self->ParseStructPushDeferred($struct, $ndr, $varname, $env); $self->deindent; $self->pidl("}"); - $self->end_flags($struct); + $self->end_flags($struct, $ndr); } ##################################################################### # generate a push function for an enum -sub ParseEnumPush($$$) +sub ParseEnumPush($$$$) { - my($self,$enum,$varname) = @_; + my($self,$enum,$ndr,$varname) = @_; my($type_fn) = $enum->{BASE_TYPE}; - $self->start_flags($enum); - $self->pidl("NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, $varname));"); - $self->end_flags($enum); + $self->start_flags($enum, $ndr); + $self->pidl("NDR_CHECK(ndr_push_$type_fn($ndr, NDR_SCALARS, $varname));"); + $self->end_flags($enum, $ndr); } ##################################################################### # generate a pull function for an enum -sub ParseEnumPull($$$) +sub ParseEnumPull($$$$) { - my($self,$enum,$varname) = @_; + my($self,$enum,$ndr,$varname) = @_; my($type_fn) = $enum->{BASE_TYPE}; my($type_v_decl) = mapTypeName($type_fn); $self->pidl("$type_v_decl v;"); - $self->start_flags($enum); - $self->pidl("NDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));"); + $self->start_flags($enum, $ndr); + $self->pidl("NDR_CHECK(ndr_pull_$type_fn($ndr, NDR_SCALARS, &v));"); $self->pidl("*$varname = v;"); - $self->end_flags($enum); + $self->end_flags($enum, $ndr); } ##################################################################### # generate a print function for an enum -sub ParseEnumPrint($$$$) +sub ParseEnumPrint($$$$$) { - my($self,$enum,$name,$varname) = @_; + my($self,$enum,$ndr,$name,$varname) = @_; $self->pidl("const char *val = NULL;"); $self->pidl(""); - $self->start_flags($enum); + $self->start_flags($enum, $ndr); $self->pidl("switch ($varname) {"); $self->indent; @@ -1385,9 +1333,9 @@ sub ParseEnumPrint($$$$) $self->deindent; $self->pidl("}"); - $self->pidl("ndr_print_enum(ndr, name, \"$enum->{TYPE}\", val, $varname);"); + $self->pidl("ndr_print_enum($ndr, name, \"$enum->{TYPE}\", val, $varname);"); - $self->end_flags($enum); + $self->end_flags($enum, $ndr); } sub DeclEnum($$$$) @@ -1406,39 +1354,39 @@ $typefamily{ENUM} = { ##################################################################### # generate a push function for a bitmap -sub ParseBitmapPush($$$) +sub ParseBitmapPush($$$$) { - my($self,$bitmap,$varname) = @_; + my($self,$bitmap,$ndr,$varname) = @_; my($type_fn) = $bitmap->{BASE_TYPE}; - $self->start_flags($bitmap); + $self->start_flags($bitmap, $ndr); - $self->pidl("NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, $varname));"); + $self->pidl("NDR_CHECK(ndr_push_$type_fn($ndr, NDR_SCALARS, $varname));"); - $self->end_flags($bitmap); + $self->end_flags($bitmap, $ndr); } ##################################################################### # generate a pull function for an bitmap -sub ParseBitmapPull($$$) +sub ParseBitmapPull($$$$) { - my($self,$bitmap,$varname) = @_; + my($self,$bitmap,$ndr,$varname) = @_; my $type_fn = $bitmap->{BASE_TYPE}; my($type_decl) = mapTypeName($bitmap->{BASE_TYPE}); $self->pidl("$type_decl v;"); - $self->start_flags($bitmap); - $self->pidl("NDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));"); + $self->start_flags($bitmap, $ndr); + $self->pidl("NDR_CHECK(ndr_pull_$type_fn($ndr, NDR_SCALARS, &v));"); $self->pidl("*$varname = v;"); - $self->end_flags($bitmap); + $self->end_flags($bitmap, $ndr); } ##################################################################### # generate a print function for an bitmap -sub ParseBitmapPrintElement($$$$$) +sub ParseBitmapPrintElement($$$$$$) { - my($self,$e,$bitmap,$name,$varname) = @_; + my($self,$e,$bitmap,$ndr,$name,$varname) = @_; my($type_decl) = mapTypeName($bitmap->{BASE_TYPE}); my($type_fn) = $bitmap->{BASE_TYPE}; my($flag); @@ -1449,28 +1397,28 @@ sub ParseBitmapPrintElement($$$$$) die "Bitmap: \"$name\" invalid Flag: \"$e\""; } - $self->pidl("ndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, $varname);"); + $self->pidl("ndr_print_bitmap_flag($ndr, sizeof($type_decl), \"$flag\", $flag, $varname);"); } ##################################################################### # generate a print function for an bitmap -sub ParseBitmapPrint($$$$) +sub ParseBitmapPrint($$$$$) { - my($self,$bitmap,$name,$varname) = @_; + my($self,$bitmap,$ndr,$name,$varname) = @_; my($type_decl) = mapTypeName($bitmap->{TYPE}); my($type_fn) = $bitmap->{BASE_TYPE}; - $self->start_flags($bitmap); + $self->start_flags($bitmap, $ndr); - $self->pidl("ndr_print_$type_fn(ndr, name, $varname);"); + $self->pidl("ndr_print_$type_fn($ndr, name, $varname);"); - $self->pidl("ndr->depth++;"); + $self->pidl("$ndr->depth++;"); foreach my $e (@{$bitmap->{ELEMENTS}}) { - $self->ParseBitmapPrintElement($e, $bitmap, $name, $varname); + $self->ParseBitmapPrintElement($e, $bitmap, $ndr, $name, $varname); } - $self->pidl("ndr->depth--;"); + $self->pidl("$ndr->depth--;"); - $self->end_flags($bitmap); + $self->end_flags($bitmap, $ndr); } sub DeclBitmap($$$$) @@ -1489,9 +1437,9 @@ $typefamily{BITMAP} = { ##################################################################### # generate a struct print function -sub ParseStructPrint($$$$) +sub ParseStructPrint($$$$$) { - my($self,$struct,$name,$varname) = @_; + my($self,$struct,$ndr,$name,$varname) = @_; return unless defined $struct->{ELEMENTS}; @@ -1499,17 +1447,17 @@ sub ParseStructPrint($$$$) $self->DeclareArrayVariables($_) foreach (@{$struct->{ELEMENTS}}); - $self->pidl("ndr_print_struct(ndr, name, \"$name\");"); + $self->pidl("ndr_print_struct($ndr, name, \"$name\");"); - $self->start_flags($struct); + $self->start_flags($struct, $ndr); - $self->pidl("ndr->depth++;"); + $self->pidl("$ndr->depth++;"); - $self->ParseElementPrint($_, $env->{$_->{NAME}}, $env) + $self->ParseElementPrint($_, $ndr, $env->{$_->{NAME}}, $env) foreach (@{$struct->{ELEMENTS}}); - $self->pidl("ndr->depth--;"); + $self->pidl("$ndr->depth--;"); - $self->end_flags($struct); + $self->end_flags($struct, $ndr); } sub DeclarePtrVariables($$) @@ -1537,68 +1485,67 @@ sub DeclareArrayVariables($$) } } -sub need_decl_mem_ctx($$) +sub DeclareArrayVariablesNoZero($$$) { - my ($e,$l) = @_; - - return 0 if has_fast_array($e,$l); - return 0 if is_charset_array($e,$l); - return 1 if (($l->{TYPE} eq "ARRAY") and not $l->{IS_FIXED}); + my ($self,$e,$env) = @_; - if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) { - my $nl = GetNextLevel($e, $l); - my $next_is_array = ($nl->{TYPE} eq "ARRAY"); - my $next_is_string = (($nl->{TYPE} eq "DATA") and - ($nl->{DATA_TYPE} eq "string")); - return 0 if ($next_is_array or $next_is_string); + foreach my $l (@{$e->{LEVELS}}) { + next if has_fast_array($e,$l); + next if is_charset_array($e,$l); + if ($l->{TYPE} eq "ARRAY") { + my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL}); + if ($length eq "0") { + warning($e->{ORIGINAL}, "pointless array cntr: 'cntr_$e->{NAME}_$l->{LEVEL_INDEX}': length=$length"); + } else { + $self->pidl("uint32_t cntr_$e->{NAME}_$l->{LEVEL_INDEX};"); + } + } } - return 1 if ($l->{TYPE} eq "POINTER"); - - return 0; } sub DeclareMemCtxVariables($$) { my ($self,$e) = @_; foreach my $l (@{$e->{LEVELS}}) { - if (need_decl_mem_ctx($e, $l)) { + my $mem_flags = $self->ParseMemCtxPullFlags($e, $l); + if (defined($mem_flags)) { $self->pidl("TALLOC_CTX *_mem_save_$e->{NAME}_$l->{LEVEL_INDEX};"); } } } -sub ParseStructPullPrimitives($$$$) +sub ParseStructPullPrimitives($$$$$) { - my($self,$struct,$varname,$env) = @_; + my($self,$struct,$ndr,$varname,$env) = @_; if (defined $struct->{SURROUNDING_ELEMENT}) { - $self->pidl("NDR_CHECK(ndr_pull_array_size(ndr, &$varname->$struct->{SURROUNDING_ELEMENT}->{NAME}));"); + $self->pidl("NDR_CHECK(ndr_pull_array_size($ndr, &$varname->$struct->{SURROUNDING_ELEMENT}->{NAME}));"); } - $self->pidl("NDR_CHECK(ndr_pull_align(ndr, $struct->{ALIGN}));"); + $self->pidl("NDR_CHECK(ndr_pull_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 - $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, $varname, ndr->offset));"); + $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset1($ndr, $varname, $ndr->offset));"); } - $self->ParseElementPull($_, "ndr", $env, 1, 0) foreach (@{$struct->{ELEMENTS}}); + $self->ParseElementPull($_, $ndr, $env, 1, 0) foreach (@{$struct->{ELEMENTS}}); $self->add_deferred(); } -sub ParseStructPullDeferred($$$$) +sub ParseStructPullDeferred($$$$$) { - my ($self,$struct,$varname,$env) = @_; + my ($self,$struct,$ndr,$varname,$env) = @_; if (defined($struct->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union - $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, $varname));"); + $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset2($ndr, $varname));"); } foreach my $e (@{$struct->{ELEMENTS}}) { - $self->ParseElementPull($e, "ndr", $env, 0, 1); + $self->ParseElementPull($e, $ndr, $env, 0, 1); } $self->add_deferred(); @@ -1606,9 +1553,9 @@ sub ParseStructPullDeferred($$$$) ##################################################################### # parse a struct - pull side -sub ParseStructPull($$$) +sub ParseStructPull($$$$) { - my($self,$struct,$varname) = @_; + my($self,$struct,$ndr,$varname) = @_; return unless defined $struct->{ELEMENTS}; @@ -1619,22 +1566,22 @@ sub ParseStructPull($$$) $self->DeclareMemCtxVariables($e); } - $self->start_flags($struct); + $self->start_flags($struct, $ndr); my $env = GenerateStructEnv($struct, $varname); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; - $self->ParseStructPullPrimitives($struct,$varname,$env); + $self->ParseStructPullPrimitives($struct,$ndr,$varname,$env); $self->deindent; $self->pidl("}"); $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); $self->indent; - $self->ParseStructPullDeferred($struct,$varname,$env); + $self->ParseStructPullDeferred($struct,$ndr,$varname,$env); $self->deindent; $self->pidl("}"); - $self->end_flags($struct); + $self->end_flags($struct, $ndr); } ##################################################################### @@ -1647,7 +1594,7 @@ sub ParseStructNdrSize($$$$) if (my $flags = has_property($t, "flag")) { $self->pidl("flags |= $flags;"); } - $self->pidl("return ndr_size_struct($varname, flags, (ndr_push_flags_fn_t)ndr_push_$name);"); + $self->pidl("return ndr_size_struct($varname, flags, (ndr_push_flags_fn_t)ndr_push_$name, ic);"); } sub DeclStruct($$$$) @@ -1659,7 +1606,7 @@ sub DeclStruct($$$$) sub ArgsStructNdrSize($$$) { my ($d, $name, $varname) = @_; - return "const struct $name *$varname, int flags"; + return "const struct $name *$varname, struct smb_iconv_convenience *ic, int flags"; } $typefamily{STRUCT} = { @@ -1682,19 +1629,19 @@ sub ParseUnionNdrSize($$$) $self->pidl("flags |= $flags;"); } - $self->pidl("return ndr_size_union($varname, flags, level, (ndr_push_flags_fn_t)ndr_push_$name);"); + $self->pidl("return ndr_size_union($varname, flags, level, (ndr_push_flags_fn_t)ndr_push_$name, ic);"); } -sub ParseUnionPushPrimitives($$$) +sub ParseUnionPushPrimitives($$$$) { - my ($self, $e, $varname) = @_; + my ($self, $e, $ndr ,$varname) = @_; my $have_default = 0; - $self->pidl("int level = ndr_push_get_switch_value(ndr, $varname);"); + $self->pidl("int level = ndr_push_get_switch_value($ndr, $varname);"); if (defined($e->{SWITCH_TYPE})) { - $self->pidl("NDR_CHECK(ndr_push_$e->{SWITCH_TYPE}(ndr, NDR_SCALARS, level));"); + $self->pidl("NDR_CHECK(ndr_push_$e->{SWITCH_TYPE}($ndr, NDR_SCALARS, level));"); } $self->pidl("switch (level) {"); @@ -1703,42 +1650,42 @@ sub ParseUnionPushPrimitives($$$) if ($el->{CASE} eq "default") { $have_default = 1; } - $self->pidl("$el->{CASE}:"); + $self->pidl("$el->{CASE}: {"); if ($el->{TYPE} ne "EMPTY") { $self->indent; if (defined($e->{PROPERTIES}{relative_base})) { - $self->pidl("NDR_CHECK(ndr_push_align(ndr, $el->{ALIGN}));"); + $self->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 - $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, $varname, ndr->offset));"); + $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset1($ndr, $varname, $ndr->offset));"); } $self->DeclareArrayVariables($el); - $self->ParseElementPush($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0); + $self->ParseElementPush($el, $ndr, {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0); $self->deindent; } - $self->pidl("break;"); + $self->pidl("break; }"); $self->pidl(""); } if (! $have_default) { $self->pidl("default:"); - $self->pidl("\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); + $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); } $self->deindent; $self->pidl("}"); } -sub ParseUnionPushDeferred($$$) +sub ParseUnionPushDeferred($$$$) { - my ($self,$e,$varname) = @_; + my ($self,$e,$ndr,$varname) = @_; my $have_default = 0; - $self->pidl("int level = ndr_push_get_switch_value(ndr, $varname);"); + $self->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 - $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, $varname));"); + $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset2($ndr, $varname));"); } $self->pidl("switch (level) {"); $self->indent; @@ -1750,7 +1697,7 @@ sub ParseUnionPushDeferred($$$) $self->pidl("$el->{CASE}:"); if ($el->{TYPE} ne "EMPTY") { $self->indent; - $self->ParseElementPush($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1); + $self->ParseElementPush($el, $ndr, {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1); $self->deindent; } $self->pidl("break;"); @@ -1758,7 +1705,7 @@ sub ParseUnionPushDeferred($$$) } if (! $have_default) { $self->pidl("default:"); - $self->pidl("\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); + $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); } $self->deindent; $self->pidl("}"); @@ -1766,31 +1713,31 @@ sub ParseUnionPushDeferred($$$) ##################################################################### # parse a union - push side -sub ParseUnionPush($$$) +sub ParseUnionPush($$$$) { - my ($self,$e,$varname) = @_; + my ($self,$e,$ndr,$varname) = @_; my $have_default = 0; - $self->start_flags($e); + $self->start_flags($e, $ndr); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; - $self->ParseUnionPushPrimitives($e, $varname); + $self->ParseUnionPushPrimitives($e, $ndr, $varname); $self->deindent; $self->pidl("}"); $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); $self->indent; - $self->ParseUnionPushDeferred($e, $varname); + $self->ParseUnionPushDeferred($e, $ndr, $varname); $self->deindent; $self->pidl("}"); - $self->end_flags($e); + $self->end_flags($e, $ndr); } ##################################################################### # print a union -sub ParseUnionPrint($$$$) +sub ParseUnionPrint($$$$$) { - my ($self,$e,$name,$varname) = @_; + my ($self,$e,$ndr,$name,$varname) = @_; my $have_default = 0; $self->pidl("int level;"); @@ -1798,11 +1745,11 @@ sub ParseUnionPrint($$$$) $self->DeclareArrayVariables($el); } - $self->start_flags($e); + $self->start_flags($e, $ndr); - $self->pidl("level = ndr_print_get_switch_value(ndr, $varname);"); + $self->pidl("level = ndr_print_get_switch_value($ndr, $varname);"); - $self->pidl("ndr_print_union(ndr, name, level, \"$name\");"); + $self->pidl("ndr_print_union($ndr, name, level, \"$name\");"); $self->pidl("switch (level) {"); $self->indent; @@ -1813,7 +1760,7 @@ sub ParseUnionPrint($$$$) $self->pidl("$el->{CASE}:"); if ($el->{TYPE} ne "EMPTY") { $self->indent; - $self->ParseElementPrint($el, "$varname->$el->{NAME}", {}); + $self->ParseElementPrint($el, $ndr, "$varname->$el->{NAME}", {}); $self->deindent; } $self->pidl("break;"); @@ -1821,23 +1768,23 @@ sub ParseUnionPrint($$$$) } if (! $have_default) { $self->pidl("default:"); - $self->pidl("\tndr_print_bad_level(ndr, name, level);"); + $self->pidl("\tndr_print_bad_level($ndr, name, level);"); } $self->deindent; $self->pidl("}"); - $self->end_flags($e); + $self->end_flags($e, $ndr); } -sub ParseUnionPullPrimitives($$$$) +sub ParseUnionPullPrimitives($$$$$) { - my ($self,$e,$varname,$switch_type) = @_; + my ($self,$e,$ndr,$varname,$switch_type) = @_; my $have_default = 0; if (defined($switch_type)) { - $self->pidl("NDR_CHECK(ndr_pull_$switch_type(ndr, NDR_SCALARS, &_level));"); + $self->pidl("NDR_CHECK(ndr_pull_$switch_type($ndr, NDR_SCALARS, &_level));"); $self->pidl("if (_level != level) {"); - $self->pidl("\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $varname\", _level);"); + $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $varname\", _level);"); $self->pidl("}"); } @@ -1854,12 +1801,12 @@ sub ParseUnionPullPrimitives($$$$) $self->DeclarePtrVariables($el); $self->DeclareArrayVariables($el); if (defined($e->{PROPERTIES}{relative_base})) { - $self->pidl("NDR_CHECK(ndr_pull_align(ndr, $el->{ALIGN}));"); + $self->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 - $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, $varname, ndr->offset));"); + $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset1($ndr, $varname, $ndr->offset));"); } - $self->ParseElementPull($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0); + $self->ParseElementPull($el, $ndr, {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0); $self->deindent; } $self->pidl("break; }"); @@ -1867,21 +1814,21 @@ sub ParseUnionPullPrimitives($$$$) } if (! $have_default) { $self->pidl("default:"); - $self->pidl("\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); + $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); } $self->deindent; $self->pidl("}"); } -sub ParseUnionPullDeferred($$$) +sub ParseUnionPullDeferred($$$$) { - my ($self,$e,$varname) = @_; + my ($self,$e,$ndr,$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 - $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, $varname));"); + $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset2($ndr, $varname));"); } $self->pidl("switch (level) {"); $self->indent; @@ -1893,7 +1840,7 @@ sub ParseUnionPullDeferred($$$) $self->pidl("$el->{CASE}:"); if ($el->{TYPE} ne "EMPTY") { $self->indent; - $self->ParseElementPull($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1); + $self->ParseElementPull($el, $ndr, {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1); $self->deindent; } $self->pidl("break;"); @@ -1901,7 +1848,7 @@ sub ParseUnionPullDeferred($$$) } if (! $have_default) { $self->pidl("default:"); - $self->pidl("\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); + $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); } $self->deindent; $self->pidl("}"); @@ -1911,9 +1858,9 @@ sub ParseUnionPullDeferred($$$) ##################################################################### # parse a union - pull side -sub ParseUnionPull($$$) +sub ParseUnionPull($$$$) { - my ($self,$e,$varname) = @_; + my ($self,$e,$ndr,$varname) = @_; my $switch_type = $e->{SWITCH_TYPE}; $self->pidl("int level;"); @@ -1932,25 +1879,25 @@ sub ParseUnionPull($$$) $double_cases{"$el->{NAME}"} = 1; } - $self->start_flags($e); + $self->start_flags($e, $ndr); - $self->pidl("level = ndr_pull_get_switch_value(ndr, $varname);"); + $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);"); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; - $self->ParseUnionPullPrimitives($e,$varname,$switch_type); + $self->ParseUnionPullPrimitives($e,$ndr,$varname,$switch_type); $self->deindent; $self->pidl("}"); $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); $self->indent; - $self->ParseUnionPullDeferred($e,$varname); + $self->ParseUnionPullDeferred($e,$ndr,$varname); $self->deindent; $self->pidl("}"); $self->add_deferred(); - $self->end_flags($e); + $self->end_flags($e, $ndr); } sub DeclUnion($$$$) @@ -1962,7 +1909,7 @@ sub DeclUnion($$$$) sub ArgsUnionNdrSize($$) { my ($d,$name) = @_; - return "const union $name *r, uint32_t level, int flags"; + return "const union $name *r, uint32_t level, struct smb_iconv_convenience *ic, int flags"; } $typefamily{UNION} = { @@ -1976,29 +1923,37 @@ $typefamily{UNION} = { ##################################################################### # parse a typedef - push side -sub ParseTypedefPush($$$) +sub ParseTypedefPush($$$$) { - my($self,$e,$varname) = @_; + my($self,$e,$ndr,$varname) = @_; - $typefamily{$e->{DATA}->{TYPE}}->{PUSH_FN_BODY}->($self, $e->{DATA}, $varname); + my $env; + + $env->{$e->{NAME}} = $varname; + + $self->ParseElementPushLevel($e, $e->{LEVELS}[0], $ndr, $varname, $env, 1, 1); } ##################################################################### # parse a typedef - pull side -sub ParseTypedefPull($$$) +sub ParseTypedefPull($$$$) { - my($self,$e,$varname) = @_; + my($self,$e,$ndr,$varname) = @_; + + my $env; - $typefamily{$e->{DATA}->{TYPE}}->{PULL_FN_BODY}->($self, $e->{DATA}, $varname); + $env->{$e->{NAME}} = $varname; + + $self->ParseElementPullLevel($e, $e->{LEVELS}[0], $ndr, $varname, $env, 1, 1); } ##################################################################### # parse a typedef - print side -sub ParseTypedefPrint($$$$) +sub ParseTypedefPrint($$$$$) { - my($self,$e,$name,$varname) = @_; + my($self,$e,$ndr,$name,$varname) = @_; - $typefamily{$e->{DATA}->{TYPE}}->{PRINT_FN_BODY}->($self, $e->{DATA}, $name, $varname); + $typefamily{$e->{DATA}->{TYPE}}->{PRINT_FN_BODY}->($self, $e->{DATA}, $ndr, $name, $varname); } ##################################################################### @@ -2037,12 +1992,13 @@ $typefamily{TYPEDEF} = { sub ParseFunctionPrint($$) { my($self, $fn) = @_; + my $ndr = "ndr"; - $self->pidl_hdr("void ndr_print_$fn->{NAME}(struct ndr_print *ndr, const char *name, int flags, const struct $fn->{NAME} *r);"); + $self->pidl_hdr("void ndr_print_$fn->{NAME}(struct ndr_print *$ndr, const char *name, int flags, const struct $fn->{NAME} *r);"); return if has_property($fn, "noprint"); - $self->pidl("_PUBLIC_ void ndr_print_$fn->{NAME}(struct ndr_print *ndr, const char *name, int flags, const struct $fn->{NAME} *r)"); + $self->pidl("_PUBLIC_ void ndr_print_$fn->{NAME}(struct ndr_print *$ndr, const char *name, int flags, const struct $fn->{NAME} *r)"); $self->pidl("{"); $self->indent; @@ -2050,48 +2006,48 @@ sub ParseFunctionPrint($$) $self->DeclareArrayVariables($e); } - $self->pidl("ndr_print_struct(ndr, name, \"$fn->{NAME}\");"); - $self->pidl("ndr->depth++;"); + $self->pidl("ndr_print_struct($ndr, name, \"$fn->{NAME}\");"); + $self->pidl("$ndr->depth++;"); $self->pidl("if (flags & NDR_SET_VALUES) {"); - $self->pidl("\tndr->flags |= LIBNDR_PRINT_SET_VALUES;"); + $self->pidl("\t$ndr->flags |= LIBNDR_PRINT_SET_VALUES;"); $self->pidl("}"); $self->pidl("if (flags & NDR_IN) {"); $self->indent; - $self->pidl("ndr_print_struct(ndr, \"in\", \"$fn->{NAME}\");"); - $self->pidl("ndr->depth++;"); + $self->pidl("ndr_print_struct($ndr, \"in\", \"$fn->{NAME}\");"); + $self->pidl("$ndr->depth++;"); my $env = GenerateFunctionInEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->ParseElementPrint($e, $env->{$e->{NAME}}, $env); + $self->ParseElementPrint($e, $ndr, $env->{$e->{NAME}}, $env); } } - $self->pidl("ndr->depth--;"); + $self->pidl("$ndr->depth--;"); $self->deindent; $self->pidl("}"); $self->pidl("if (flags & NDR_OUT) {"); $self->indent; - $self->pidl("ndr_print_struct(ndr, \"out\", \"$fn->{NAME}\");"); - $self->pidl("ndr->depth++;"); + $self->pidl("ndr_print_struct($ndr, \"out\", \"$fn->{NAME}\");"); + $self->pidl("$ndr->depth++;"); $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - $self->ParseElementPrint($e, $env->{$e->{NAME}}, $env); + $self->ParseElementPrint($e, $ndr, $env->{$e->{NAME}}, $env); } } if ($fn->{RETURN_TYPE}) { - $self->pidl("ndr_print_$fn->{RETURN_TYPE}(ndr, \"result\", r->out.result);"); + $self->pidl("ndr_print_$fn->{RETURN_TYPE}($ndr, \"result\", r->out.result);"); } - $self->pidl("ndr->depth--;"); + $self->pidl("$ndr->depth--;"); $self->deindent; $self->pidl("}"); - $self->pidl("ndr->depth--;"); + $self->pidl("$ndr->depth--;"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -2102,8 +2058,9 @@ sub ParseFunctionPrint($$) sub ParseFunctionPush($$) { my($self, $fn) = @_; + my $ndr = "ndr"; - $self->fn_declare("push", $fn, "enum ndr_err_code ndr_push_$fn->{NAME}(struct ndr_push *ndr, int flags, const struct $fn->{NAME} *r)") or return; + $self->fn_declare("push", $fn, "enum ndr_err_code ndr_push_$fn->{NAME}(struct ndr_push *$ndr, int flags, const struct $fn->{NAME} *r)") or return; return if has_property($fn, "nopush"); @@ -2123,7 +2080,7 @@ sub ParseFunctionPush($$) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->ParseElementPush($e, "ndr", $env, 1, 1); + $self->ParseElementPush($e, $ndr, $env, 1, 1); } } @@ -2136,12 +2093,12 @@ sub ParseFunctionPush($$) $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - $self->ParseElementPush($e, "ndr", $env, 1, 1); + $self->ParseElementPush($e, $ndr, $env, 1, 1); } } if ($fn->{RETURN_TYPE}) { - $self->pidl("NDR_CHECK(ndr_push_$fn->{RETURN_TYPE}(ndr, NDR_SCALARS, r->out.result));"); + $self->pidl("NDR_CHECK(ndr_push_$fn->{RETURN_TYPE}($ndr, NDR_SCALARS, r->out.result));"); } $self->deindent; @@ -2154,16 +2111,14 @@ sub ParseFunctionPush($$) sub AllocateArrayLevel($$$$$$) { - my ($self,$e,$l,$ndr,$env,$size) = @_; - - my $var = ParseExpr($e->{NAME}, $env, $e->{ORIGINAL}); + my ($self,$e,$l,$ndr,$var,$size) = @_; my $pl = GetPrevLevel($e, $l); if (defined($pl) and $pl->{TYPE} eq "POINTER" and $pl->{POINTER_TYPE} eq "ref" and not $l->{IS_ZERO_TERMINATED}) { - $self->pidl("if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {"); + $self->pidl("if ($ndr->flags & LIBNDR_FLAG_REF_ALLOC) {"); $self->pidl("\tNDR_PULL_ALLOC_N($ndr, $var, $size);"); $self->pidl("}"); if (grep(/in/,@{$e->{DIRECTION}}) and @@ -2181,9 +2136,10 @@ sub AllocateArrayLevel($$$$$$) sub ParseFunctionPull($$) { my($self,$fn) = @_; + my $ndr = "ndr"; # pull function args - $self->fn_declare("pull", $fn, "enum ndr_err_code ndr_pull_$fn->{NAME}(struct ndr_pull *ndr, int flags, struct $fn->{NAME} *r)") or return; + $self->fn_declare("pull", $fn, "enum ndr_err_code ndr_pull_$fn->{NAME}(struct ndr_pull *$ndr, int flags, struct $fn->{NAME} *r)") or return; $self->pidl("{"); $self->indent; @@ -2220,7 +2176,7 @@ sub ParseFunctionPull($$) foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/in/, @{$e->{DIRECTION}})); - $self->ParseElementPull($e, "ndr", $env, 1, 1); + $self->ParseElementPull($e, $ndr, $env, 1, 1); } # allocate the "simple" out ref variables. FIXME: Shouldn't this have it's @@ -2238,17 +2194,17 @@ sub ParseFunctionPull($$) if ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") { my $size = ParseExprExt($e->{LEVELS}[1]->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, - "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"), + "return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"), check_fully_dereferenced($e, $env)); - $self->pidl("NDR_PULL_ALLOC_N(ndr, r->out.$e->{NAME}, $size);"); + $self->pidl("NDR_PULL_ALLOC_N($ndr, r->out.$e->{NAME}, $size);"); if (grep(/in/, @{$e->{DIRECTION}})) { - $self->pidl("memcpy(r->out.$e->{NAME}, r->in.$e->{NAME}, $size * sizeof(*r->in.$e->{NAME}));"); + $self->pidl("memcpy(r->out.$e->{NAME}, r->in.$e->{NAME}, ($size) * sizeof(*r->in.$e->{NAME}));"); } else { - $self->pidl("memset(r->out.$e->{NAME}, 0, $size * sizeof(*r->out.$e->{NAME}));"); + $self->pidl("memset(r->out.$e->{NAME}, 0, ($size) * sizeof(*r->out.$e->{NAME}));"); } } else { - $self->pidl("NDR_PULL_ALLOC(ndr, r->out.$e->{NAME});"); + $self->pidl("NDR_PULL_ALLOC($ndr, r->out.$e->{NAME});"); if (grep(/in/, @{$e->{DIRECTION}})) { $self->pidl("*r->out.$e->{NAME} = *r->in.$e->{NAME};"); @@ -2268,11 +2224,11 @@ sub ParseFunctionPull($$) $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { next unless grep(/out/, @{$e->{DIRECTION}}); - $self->ParseElementPull($e, "ndr", $env, 1, 1); + $self->ParseElementPull($e, $ndr, $env, 1, 1); } if ($fn->{RETURN_TYPE}) { - $self->pidl("NDR_CHECK(ndr_pull_$fn->{RETURN_TYPE}(ndr, NDR_SCALARS, &r->out.result));"); + $self->pidl("NDR_CHECK(ndr_pull_$fn->{RETURN_TYPE}($ndr, NDR_SCALARS, &r->out.result));"); } $self->add_deferred(); @@ -2285,6 +2241,41 @@ sub ParseFunctionPull($$) $self->pidl(""); } +sub AuthServiceStruct($$$) +{ + my ($self, $ifacename, $authservice) = @_; + my @a = split /,/, $authservice; + my $authservice_count = $#a + 1; + + $self->pidl("static const char * const $ifacename\_authservice_strings[] = {"); + foreach my $ap (@a) { + $self->pidl("\t$ap, "); + } + $self->pidl("};"); + $self->pidl(""); + + $self->pidl("static const struct ndr_interface_string_array $ifacename\_authservices = {"); + $self->pidl("\t.count\t= $authservice_count,"); + $self->pidl("\t.names\t= $ifacename\_authservice_strings"); + $self->pidl("};"); + $self->pidl(""); +} + +sub FunctionCallEntry($$) +{ + my ($self, $d) = @_; + return 0 if not defined($d->{OPNUM}); + $self->pidl("\t{"); + $self->pidl("\t\t\"$d->{NAME}\","); + $self->pidl("\t\tsizeof(struct $d->{NAME}),"); + $self->pidl("\t\t(ndr_push_flags_fn_t) ndr_push_$d->{NAME},"); + $self->pidl("\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},"); + $self->pidl("\t\t(ndr_print_function_t) ndr_print_$d->{NAME},"); + $self->pidl("\t\t".($d->{ASYNC}?"true":"false").","); + $self->pidl("\t},"); + return 1; +} + ##################################################################### # produce a function call table sub FunctionTable($$) @@ -2297,17 +2288,9 @@ sub FunctionTable($$) return unless defined ($interface->{PROPERTIES}->{uuid}); $self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {"); - foreach my $d (@{$interface->{FUNCTIONS}}) { - next if not defined($d->{OPNUM}); - $self->pidl("\t{"); - $self->pidl("\t\t\"$d->{NAME}\","); - $self->pidl("\t\tsizeof(struct $d->{NAME}),"); - $self->pidl("\t\t(ndr_push_flags_fn_t) ndr_push_$d->{NAME},"); - $self->pidl("\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},"); - $self->pidl("\t\t(ndr_print_function_t) ndr_print_$d->{NAME},"); - $self->pidl("\t\t".($d->{ASYNC}?"true":"false").","); - $self->pidl("\t},"); - $count++; + + foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) { + $count += $self->FunctionCallEntry($d); } $self->pidl("\t{ NULL, 0, NULL, NULL, NULL, false }"); $self->pidl("};"); @@ -2332,21 +2315,8 @@ sub FunctionTable($$) $interface->{PROPERTIES}->{authservice} = "\"host\""; } - my @a = split / /, $interface->{PROPERTIES}->{authservice}; - my $authservice_count = $#a + 1; - - $self->pidl("static const char * const $interface->{NAME}\_authservice_strings[] = {"); - foreach my $ap (@a) { - $self->pidl("\t$ap, "); - } - $self->pidl("};"); - $self->pidl(""); - - $self->pidl("static const struct ndr_interface_string_array $interface->{NAME}\_authservices = {"); - $self->pidl("\t.count\t= $endpoint_count,"); - $self->pidl("\t.names\t= $interface->{NAME}\_authservice_strings"); - $self->pidl("};"); - $self->pidl(""); + $self->AuthServiceStruct($interface->{NAME}, + $interface->{PROPERTIES}->{authservice}); $self->pidl("\nconst struct ndr_interface_table ndr_table_$interface->{NAME} = {"); $self->pidl("\t.name\t\t= \"$interface->{NAME}\","); @@ -2371,8 +2341,8 @@ sub HeaderImport my $self = shift; my @imports = @_; foreach (@imports) { - s/\.idl\"$//; - s/^\"//; + $_ = unmake_str($_); + s/\.idl$//; $self->pidl(choose_header("librpc/gen_ndr/ndr_$_\.h", "gen_ndr/ndr_$_.h")); } } @@ -2407,7 +2377,7 @@ sub HeaderInterface($$$) } if (defined $interface->{PROPERTIES}->{helper}) { - $self->HeaderInclude(split / /, $interface->{PROPERTIES}->{helper}); + $self->HeaderInclude(split /,/, $interface->{PROPERTIES}->{helper}); } if (defined $interface->{PROPERTIES}->{uuid}) { @@ -2428,7 +2398,7 @@ sub HeaderInterface($$$) foreach (@{$interface->{FUNCTIONS}}) { next if has_property($_, "noopnum"); - next if grep(/$_->{NAME}/,@{$interface->{INHERITED_FUNCTIONS}}); + next if grep(/^$_->{NAME}$/,@{$interface->{INHERITED_FUNCTIONS}}); my $u_name = uc $_->{NAME}; my $val = sprintf("0x%02x", $count); @@ -2452,81 +2422,86 @@ sub HeaderInterface($$$) } -sub ParseTypePush($$$$$) +sub ParseTypePush($$$$$$) { - my ($self,$e,$varname, $primitives, $deferred) = @_; + my ($self,$e, $ndr, $varname, $primitives, $deferred) = @_; # save the old relative_base_offset - $self->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}->($self, $e, $varname); + $self->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}->($self, $e, $ndr, $varname); # restore the old relative_base_offset - $self->pidl("ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);") if defined(has_property($e, "relative_base")); + $self->pidl("ndr_push_restore_relative_base_offset($ndr, _save_relative_base_offset);") if defined(has_property($e, "relative_base")); } sub ParseTypePushFunction($$$) { my ($self, $e, $varname) = @_; + my $ndr = "ndr"; my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "push", $e->{NAME}, $varname); - $self->fn_declare("push", $e, "enum ndr_err_code ".TypeFunctionName("ndr_push", $e)."(struct ndr_push *ndr, int ndr_flags, $args)") or return; + + $self->fn_declare("push", $e, "enum ndr_err_code ".TypeFunctionName("ndr_push", $e)."(struct ndr_push *$ndr, int ndr_flags, $args)") or return; $self->pidl("{"); $self->indent; - $self->ParseTypePush($e, $varname, 1, 1); + $self->ParseTypePush($e, $ndr, $varname, 1, 1); $self->pidl("return NDR_ERR_SUCCESS;"); $self->deindent; $self->pidl("}"); $self->pidl("");; } -sub ParseTypePull($$$$$) +sub ParseTypePull($$$$$$) { - my ($self, $e, $varname, $primitives, $deferred) = @_; + my ($self, $e, $ndr, $varname, $primitives, $deferred) = @_; # save the old relative_base_offset - $self->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}->($self, $e, $varname); + $self->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}->($self, $e, $ndr, $varname); # restore the old relative_base_offset - $self->pidl("ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);") if defined(has_property($e, "relative_base")); + $self->pidl("ndr_pull_restore_relative_base_offset($ndr, _save_relative_base_offset);") if defined(has_property($e, "relative_base")); } sub ParseTypePullFunction($$) { my ($self, $e, $varname) = @_; + my $ndr = "ndr"; my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "pull", $e->{NAME}, $varname); - $self->fn_declare("pull", $e, "enum ndr_err_code ".TypeFunctionName("ndr_pull", $e)."(struct ndr_pull *ndr, int ndr_flags, $args)") or return; + $self->fn_declare("pull", $e, "enum ndr_err_code ".TypeFunctionName("ndr_pull", $e)."(struct ndr_pull *$ndr, int ndr_flags, $args)") or return; $self->pidl("{"); $self->indent; - $self->ParseTypePull($e, $varname, 1, 1); + $self->ParseTypePull($e, $ndr, $varname, 1, 1); $self->pidl("return NDR_ERR_SUCCESS;"); $self->deindent; $self->pidl("}"); $self->pidl(""); } -sub ParseTypePrint($$$) +sub ParseTypePrint($$$$) { - my ($self, $e, $varname) = @_; + my ($self, $e, $ndr, $varname) = @_; - $typefamily{$e->{TYPE}}->{PRINT_FN_BODY}->($self, $e, $e->{NAME}, $varname); + $typefamily{$e->{TYPE}}->{PRINT_FN_BODY}->($self, $e, $ndr, $e->{NAME}, $varname); } sub ParseTypePrintFunction($$$) { my ($self, $e, $varname) = @_; + my $ndr = "ndr"; + my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "print", $e->{NAME}, $varname); $self->pidl_hdr("void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *ndr, const char *name, $args);"); return if (has_property($e, "noprint")); - $self->pidl("_PUBLIC_ void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *ndr, const char *name, $args)"); + $self->pidl("_PUBLIC_ void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *$ndr, const char *name, $args)"); $self->pidl("{"); $self->indent; - $self->ParseTypePrint($e, $varname); + $self->ParseTypePrint($e, $ndr, $varname); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -2565,6 +2540,8 @@ sub ParseInterface($$$) # Typedefs foreach my $d (@{$interface->{TYPES}}) { + next unless(typeHasBody($d)); + ($needed->{TypeFunctionName("ndr_push", $d)}) && $self->ParseTypePushFunction($d, "r"); ($needed->{TypeFunctionName("ndr_pull", $d)}) && $self->ParseTypePullFunction($d, "r"); ($needed->{TypeFunctionName("ndr_print", $d)}) && $self->ParseTypePrintFunction($d, "r"); @@ -2599,7 +2576,9 @@ sub GenerateIncludes($) if (is_intree()) { $self->pidl("#include \"includes.h\""); } else { + $self->pidl("#ifndef _GNU_SOURCE"); $self->pidl("#define _GNU_SOURCE"); + $self->pidl("#endif"); $self->pidl("#include <stdint.h>"); $self->pidl("#include <stdlib.h>"); $self->pidl("#include <stdio.h>"); @@ -2708,6 +2687,7 @@ sub NeededType($$$) NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "TYPEDEF"); if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "UNION") { + return unless defined($t->{ELEMENTS}); for my $e (@{$t->{ELEMENTS}}) { $e->{PARENT} = $t; if (has_property($e, "compression")) { @@ -2745,7 +2725,7 @@ sub TypeFunctionName($$) my ($prefix, $t) = @_; return "$prefix\_$t->{NAME}" if (ref($t) eq "HASH" and - ($t->{TYPE} eq "TYPEDEF" or $t->{TYPE} eq "DECLARE")); + $t->{TYPE} eq "TYPEDEF"); return "$prefix\_$t->{TYPE}_$t->{NAME}" if (ref($t) eq "HASH"); return "$prefix\_$t"; } diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm index e30102b4e1..bb0c18e13c 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm @@ -120,7 +120,8 @@ static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_C /* unravel the NDR for the packet */ ndr_err = ndr_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - dcerpc_log_packet(&ndr_table_$name, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + &ndr_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; @@ -144,7 +145,8 @@ pidl " } if (dce_call->fault_code != 0) { - dcerpc_log_packet(&ndr_table_$name, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + &ndr_table_$name, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); return NT_STATUS_NET_WRITE_FAULT; } @@ -167,7 +169,8 @@ pidl " } if (dce_call->fault_code != 0) { - dcerpc_log_packet(&ndr_table_$name, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + &ndr_table_$name, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); return NT_STATUS_NET_WRITE_FAULT; } diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm b/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm index 568dff5adf..a6b74a0ba4 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm @@ -271,7 +271,7 @@ sub Parser($$$$) $self->pidl(""); $self->pidl_hdr("/* autogenerated by pidl */"); $self->pidl_hdr("#include \"$baseheader\""); - $self->pidl_hdr(choose_header("tdr/tdr.h", "tdr.h")); + $self->pidl_hdr(choose_header("lib/tdr/tdr.h", "tdr.h")); $self->pidl_hdr(""); foreach (@$idl) { $self->ParserInterface($_) if ($_->{TYPE} eq "INTERFACE"); } diff --git a/tools/pidl/lib/Parse/Pidl/Typelist.pm b/tools/pidl/lib/Parse/Pidl/Typelist.pm index b2069c784b..12ffa92bf6 100644 --- a/tools/pidl/lib/Parse/Pidl/Typelist.pm +++ b/tools/pidl/lib/Parse/Pidl/Typelist.pm @@ -7,9 +7,9 @@ package Parse::Pidl::Typelist; require Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(hasType getType mapTypeName scalar_is_reference expandAlias - mapScalarType addType typeIs is_scalar enum_type_fn - bitmap_type_fn mapType +@EXPORT_OK = qw(hasType getType resolveType mapTypeName scalar_is_reference expandAlias + mapScalarType addType typeIs is_signed is_scalar enum_type_fn + bitmap_type_fn mapType typeHasBody ); use vars qw($VERSION); $VERSION = '0.01'; @@ -38,6 +38,7 @@ my %scalars = ( "dlong" => "int64_t", "udlong" => "uint64_t", "udlongr" => "uint64_t", + "double" => "double", "pointer" => "void*", "DATA_BLOB" => "DATA_BLOB", "string" => "const char *", @@ -59,6 +60,7 @@ my %aliases = ( "boolean8" => "uint8", "boolean32" => "uint32", "DWORD" => "uint32", + "uint" => "uint32", "int" => "int32", "WORD" => "uint16", "char" => "uint8", @@ -95,6 +97,20 @@ sub addType($) $types{$t->{NAME}} = $t; } +sub resolveType($) +{ + my ($ctype) = @_; + + if (not hasType($ctype)) { + # assume struct typedef + return { TYPE => "TYPEDEF", NAME => $ctype, DATA => { TYPE => "STRUCT" } }; + } else { + return getType($ctype); + } + + return $ctype; +} + sub getType($) { my $t = shift; @@ -130,16 +146,30 @@ sub hasType($) return 0; } +sub is_signed($) +{ + my $t = shift; + + return ($t eq "int8" + or $t eq "int16" + or $t eq "int32" + or $t eq "dlong" + or $t eq "int" + or $t eq "long" + or $t eq "short"); +} + sub is_scalar($) { sub is_scalar($); my $type = shift; - return 1 if (ref($type) eq "HASH" and $type->{TYPE} eq "SCALAR"); + return 1 if (ref($type) eq "HASH" and + ($type->{TYPE} eq "SCALAR" or $type->{TYPE} eq "ENUM" or + $type->{TYPE} eq "BITMAP")); if (my $dt = getType($type)) { - return is_scalar($dt->{DATA}) if ($dt->{TYPE} eq "TYPEDEF" or - $dt->{TYPE} eq "DECLARE"); + return is_scalar($dt->{DATA}) if ($dt->{TYPE} eq "TYPEDEF"); return 1 if ($dt->{TYPE} eq "SCALAR" or $dt->{TYPE} eq "ENUM" or $dt->{TYPE} eq "BITMAP"); } @@ -150,7 +180,7 @@ sub is_scalar($) sub scalar_is_reference($) { my $name = shift; - + return 1 if (grep(/^$name$/, @reference_scalars)); return 0; } @@ -161,6 +191,7 @@ sub RegisterScalars() addType({ NAME => $_, TYPE => "TYPEDEF", + BASEFILE => "<builtin>", DATA => { TYPE => "SCALAR", NAME => $_ @@ -208,16 +239,28 @@ sub bitmap_type_fn($) return "uint32"; } +sub typeHasBody($) +{ + sub typeHasBody($); + my ($e) = @_; + + if ($e->{TYPE} eq "TYPEDEF") { + return 0 unless(defined($e->{DATA})); + return typeHasBody($e->{DATA}); + } + + return defined($e->{ELEMENTS}); +} + 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 "struct $n" if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "INTERFACE"); return "union $n" if ($t->{TYPE} eq "UNION"); return mapScalarType(bitmap_type_fn($t)) if ($t->{TYPE} eq "BITMAP"); die("Unknown type $t->{TYPE}"); @@ -230,33 +273,51 @@ sub mapTypeName($) my $dt; $t = expandAlias($t); - unless ($dt or ($dt = getType($t))) { + if ($dt = getType($t)) { + return mapType($dt, $dt->{NAME}); + } elsif (ref($t) eq "HASH" and defined($t->{NAME})) { + return mapType($t, $t->{NAME}); + } else { # Best guess return "struct $t"; } - return mapType($dt, $dt->{NAME}); } -sub LoadIdl($) +sub LoadIdl($;$) { my $idl = shift; + my $basename = shift; 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, + BASEFILE => $basename, + }) 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 "UNION" - or $y->{TYPE} eq "STRUCT" - or $y->{TYPE} eq "ENUM" - or $y->{TYPE} eq "BITMAP"); + if ($y->{TYPE} eq "TYPEDEF" + or $y->{TYPE} eq "UNION" + or $y->{TYPE} eq "STRUCT" + or $y->{TYPE} eq "ENUM" + or $y->{TYPE} eq "BITMAP") { + $y->{BASEFILE} = $basename; + addType($y); + } } } } +sub GenerateTypeLib() +{ + return Parse::Pidl::Util::MyDumper(\%types); +} + RegisterScalars(); 1; diff --git a/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm b/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm index b53c56e741..5c37b4a0c4 100644 --- a/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm +++ b/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm @@ -52,6 +52,10 @@ use old_hf_name. This can be used in conjunction with HF_FIELD in order to make more than one element use the same filter name. +=item I<ETT_FIELD> ett + +Register a custom ett field + =item I<STRIP_PREFIX> prefix Remove the specified prefix from all function names (if present). @@ -70,6 +74,10 @@ Change description for the specified header field. `field' is the hf name of the Code to insert when generating the specified dissector. @HF@ and @PARAM@ will be substituted. +=item I<INCLUDE> filename + +Include conformance data from the specified filename in the dissector. + =item I<TFS> hf_name "true string" "false string" Override the text shown when a bitmap boolean value is enabled or disabled. @@ -313,6 +321,34 @@ sub handle_import }; } +sub handle_ett_field +{ + my $pos = shift @_; + my $data = shift @_; + my $ett = shift @_; + + unless(defined($ett)) { + error($pos, "incomplete ETT_FIELD command"); + return; + } + + push (@{$data->{ett}}, $ett); +} + +sub handle_include +{ + my $pos = shift @_; + my $data = shift @_; + my $fn = shift @_; + + unless(defined($fn)) { + error($pos, "incomplete INCLUDE command"); + return; + } + + ReadConformance($fn, $data); +} + my %field_handlers = ( TYPE => \&handle_type, NOEMIT => \&handle_noemit, @@ -320,11 +356,13 @@ my %field_handlers = ( PARAM_VALUE => \&handle_param_value, HF_FIELD => \&handle_hf_field, HF_RENAME => \&handle_hf_rename, + ETT_FIELD => \&handle_ett_field, TFS => \&handle_tfs, STRIP_PREFIX => \&handle_strip_prefix, PROTOCOL => \&handle_protocol, FIELD_DESCRIPTION => \&handle_fielddescription, - IMPORT => \&handle_import + IMPORT => \&handle_import, + INCLUDE => \&handle_include ); sub ReadConformance($$) diff --git a/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm b/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm index 9ba7fc5d34..a9ad555cca 100644 --- a/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm +++ b/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm @@ -940,6 +940,10 @@ sub Parse($$$$$) $self->{res}->{headers} .= "#include \"$h_basename\"\n"; $self->pidl_code(""); + if (defined($self->{conformance}->{ett})) { + register_ett($self,$_) foreach(@{$self->{conformance}->{ett}}) + } + # Wireshark protocol registration foreach (@$ndr) { @@ -1053,16 +1057,16 @@ sub DumpHfDeclaration($) sub make_str_or_null($) { - my $str = shift; - if (substr($str, 0, 1) eq "\"") { - $str = substr($str, 1, length($str)-2); - } - $str =~ s/^\s*//; - $str =~ s/\s*$//; - if ($str eq "") { - return "NULL"; - } - return make_str($str); + my $str = shift; + if (substr($str, 0, 1) eq "\"") { + $str = substr($str, 1, length($str)-2); + } + $str =~ s/^\s*//; + $str =~ s/\s*$//; + if ($str eq "") { + return "NULL"; + } + return make_str($str); } sub DumpHfList($) diff --git a/tools/pidl/pidl b/tools/pidl/pidl index 4150ff7720..bc0bb3524b 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] [--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]] [--python[=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]] [--typelib=[OUTPUT]] [<idlfile>.idl]... =head1 DESCRIPTION @@ -52,6 +52,10 @@ both marshalling/unmarshalling and debugging purposes). =item I<--help> Show list of available options. + +=item I<--version> + +Show pidl version =item I<--outputdir OUTNAME> @@ -88,6 +92,10 @@ Generate a C file and C header containing TDR parsers. The filename for the parser defaults to tdr_OUTNAME.c. The header filename will be the parser filename with the extension changed from .c to .h. +=item I<--typelib> + +Write type information to the specified file. + =item I<--server> Generate boilerplate for the RPC server that implements @@ -395,12 +403,13 @@ pidl README by Andrew Tridgell. use strict; use FindBin qw($RealBin $Script); -use lib "$RealBin"; use lib "$RealBin/lib"; +use lib "$RealBin/../share/perl5"; use Getopt::Long; use File::Basename; -use Parse::Pidl; +use Parse::Pidl qw ( $VERSION ); use Parse::Pidl::Util; +use Parse::Pidl::ODL; ##################################################################### # save a data structure into a file @@ -449,6 +458,7 @@ sub FileSave($$) my(@opt_incdirs) = (); my($opt_help) = 0; +my($opt_version) = 0; my($opt_parse_idl_tree) = 0; my($opt_dump_idl_tree); my($opt_dump_ndr_tree); @@ -462,22 +472,26 @@ my($opt_samba3_ndr_client); my($opt_samba3_ndr_server); my($opt_template) = 0; my($opt_client); +my($opt_typelib); my($opt_server); my($opt_ndr_parser); my($opt_tdr_parser); my($opt_ws_parser); -my($opt_swig); -my($opt_ejs); +my($opt_python); my($opt_quiet) = 0; my($opt_outputdir) = '.'; my($opt_verbose) = 0; my($opt_warn_compat) = 0; +my($opt_dcom_proxy); +my($opt_com_header); ######################################### # display help text sub ShowHelp() { -print "perl IDL parser and code generator +print "perl IDL parser and code generator\n"; +ShowVersion(); +print" Copyright (C) Andrew Tridgell <tridge\@samba.org> Copyright (C) Jelmer Vernooij <jelmer\@samba.org> @@ -485,6 +499,7 @@ Usage: $Script [options] [--] <idlfile> [<idlfile>...] Generic Options: --help this help page + --version show pidl version --outputdir=OUTDIR put output in OUTDIR/ [.] --warn-compat warn about incompatibility with other compilers --quiet be quiet @@ -497,16 +512,18 @@ Debugging: --dump-ndr-tree[=FILE] dump internal NDR data tree to file [BASENAME.ndr] --dump-idl regenerate IDL file --diff run diff on original IDL and dumped output + --typelib print type information Samba 4 output: --header[=OUTFILE] create generic header file [BASENAME.h] --ndr-parser[=OUTFILE] create a C NDR parser [ndr_BASENAME.c] --client[=OUTFILE] create a C NDR client [ndr_BASENAME_c.c] --tdr-parser[=OUTFILE] create a C TDR parser [tdr_BASENAME.c] - --ejs[=OUTFILE] create ejs wrapper file [BASENAME_ejs.c] - --swig[=OUTFILE] create swig wrapper file [BASENAME.i] + --python[=OUTFILE] create python wrapper file [py_BASENAME.c] --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 @@ -520,9 +537,17 @@ Wireshark parsers: exit(0); } +######################################### +# Display version +sub ShowVersion() +{ + print "perl IDL version $VERSION\n"; +} + # main program my $result = GetOptions ( 'help|h|?' => \$opt_help, + 'version' => \$opt_version, 'outputdir=s' => \$opt_outputdir, 'dump-idl' => \$opt_dump_idl, 'dump-idl-tree:s' => \$opt_dump_idl_tree, @@ -532,14 +557,16 @@ my $result = GetOptions ( 'samba3-ndr-server:s' => \$opt_samba3_ndr_server, 'header:s' => \$opt_header, 'server:s' => \$opt_server, + 'typelib:s' => \$opt_typelib, 'tdr-parser:s' => \$opt_tdr_parser, 'template' => \$opt_template, 'ndr-parser:s' => \$opt_ndr_parser, 'client:s' => \$opt_client, 'ws-parser:s' => \$opt_ws_parser, - 'ejs' => \$opt_ejs, + 'python' => \$opt_python, '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, @@ -555,6 +582,11 @@ if ($opt_help) { exit(0); } +if ($opt_version) { + ShowVersion(); + exit(0); +} + sub process_file($) { my $idl_file = shift; @@ -574,10 +606,11 @@ sub process_file($) $pidl = Parse::Pidl::IDL::parse_file($idl_file, \@opt_incdirs); defined @$pidl || die "Failed to parse $idl_file"; - require Parse::Pidl::Typelist; - Parse::Pidl::Typelist::LoadIdl($pidl); } - + + require Parse::Pidl::Typelist; + Parse::Pidl::Typelist::LoadIdl($pidl, $basename); + if (defined($opt_dump_idl_tree)) { my($pidl_file) = ($opt_dump_idl_tree or "$outputdir/$basename.pidl"); SaveStructure($pidl_file, $pidl) or die "Failed to save $pidl_file\n"; @@ -595,22 +628,41 @@ 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, dirname($idl_file), \@opt_incdirs); + if (defined($opt_ws_parser) or defined($opt_client) or defined($opt_server) or defined($opt_header) or defined($opt_ndr_parser) or - defined($opt_ejs) or + defined($opt_python) or defined($opt_dump_ndr_tree) or defined($opt_samba3_header) or defined($opt_samba3_parser) or defined($opt_samba3_server) or - defined($opt_swig) or defined($opt_samba3_ndr_client) or defined($opt_samba3_ndr_server)) { require Parse::Pidl::NDR; @@ -642,19 +694,12 @@ sub process_file($) FileSave($c_header, $hdrd); } - if (defined($opt_swig)) { - require Parse::Pidl::Samba4::SWIG; - my($filename) = ($opt_swig or "$outputdir/$basename.i"); - my $code = Parse::Pidl::Samba4::SWIG::Parse($ndr, $basename, "$outputdir/ndr_$basename\_c.h", $gen_header); - FileSave($filename, $code); - } - - if (defined($opt_ejs)) { - require Parse::Pidl::Samba4::EJS; - my $generator = new Parse::Pidl::Samba4::EJS(); - my ($hdr,$prsr) = $generator->Parse($ndr, $h_filename); - FileSave("$outputdir/ndr_$basename\_ejs.c", $prsr); - FileSave("$outputdir/ndr_$basename\_ejs.h", $hdr); + if (defined($opt_python)) { + require Parse::Pidl::Samba4::Python; + my $generator = new Parse::Pidl::Samba4::Python(); + my ($prsr) = $generator->Parse($basename, $ndr, + "$outputdir/ndr_$basename\_c.h", $h_filename); + FileSave("$outputdir/py_$basename.c", $prsr); } if (defined($opt_server)) { @@ -699,6 +744,12 @@ sub process_file($) FileSave($tdr_header, $hdr); } + if (defined($opt_typelib)) { + my $typelib = ($opt_typelib or "$outputdir/$basename.tlb"); + require Parse::Pidl::Typelist; + FileSave($typelib, Parse::Pidl::Typelist::GenerateTypeLib()); + } + if ($opt_template) { require Parse::Pidl::Samba4::Template; print Parse::Pidl::Samba4::Template::Parse($pidl); diff --git a/tools/pidl/tests/Util.pm b/tools/pidl/tests/Util.pm index 82ab130e5a..cfc5cf3a99 100644 --- a/tools/pidl/tests/Util.pm +++ b/tools/pidl/tests/Util.pm @@ -13,6 +13,8 @@ use strict; use FindBin qw($RealBin); use lib "$RealBin/../lib"; +use Parse::Pidl::Samba4 qw(is_intree); + use Parse::Pidl; my $warnings = ""; undef &Parse::Pidl::warning; @@ -66,8 +68,12 @@ sub test_samba4_ndr SKIP: { - skip "no samba environment available, skipping compilation", 3 - if (system("pkg-config --exists ndr") != 0); + my $flags; + if (system("pkg-config --exists ndr") == 0 and !is_intree()) { + $flags = `pkg-config --libs --cflags ndr`; + } else { + skip "no samba environment available, skipping compilation", 3; + } my $main = " #define uint_t unsigned int @@ -134,8 +140,6 @@ $c $cc = "cc"; } - my $flags = `pkg-config --libs --cflags ndr samba-config`; - my $cmd = "$cc $cflags -x c - -o $outfile $flags $ldflags"; $cmd =~ s/\n//g; open CC, "|$cmd"; diff --git a/tools/pidl/tests/header.pl b/tools/pidl/tests/header.pl index 8d0dccf507..db59484444 100755 --- a/tools/pidl/tests/header.pl +++ b/tools/pidl/tests/header.pl @@ -4,12 +4,14 @@ use strict; use warnings; -use Test::More tests => 16; +use Test::More tests => 27; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use Parse::Pidl::Util qw(MyDumper); -use Parse::Pidl::Samba4::Header; +use Parse::Pidl::Samba4::Header qw( + GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv + EnvSubstituteValue); use Parse::Pidl::IDL qw(parse_string); use Parse::Pidl::NDR; @@ -56,3 +58,51 @@ like(parse_idl("interface p { typedef struct x { int p; } x; };"), like(parse_idl("cpp_quote(\"some-foo\")"), qr/some-foo/sm, "cpp quote"); + +# 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"], 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" }); + + diff --git a/tools/pidl/tests/ndr.pl b/tools/pidl/tests/ndr.pl index 1512f19d52..53b8cb89e3 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 => 34; +use Test::More tests => 47; use FindBin qw($RealBin); use lib "$RealBin"; use Util; @@ -22,7 +22,7 @@ my $e = { 'PARENT' => { TYPE => 'STRUCT' }, 'LINE' => 42 }; -is_deeply(GetElementLevelTable($e), [ +is_deeply(GetElementLevelTable($e, "unique"), [ { 'IS_DEFERRED' => 0, 'LEVEL_INDEX' => 0, @@ -33,7 +33,7 @@ is_deeply(GetElementLevelTable($e), [ } ]); -my $ne = ParseElement($e, undef); +my $ne = ParseElement($e, "unique"); is($ne->{ORIGINAL}, $e); is($ne->{NAME}, "v"); is($ne->{ALIGN}, 1); @@ -60,7 +60,7 @@ $e = { 'TYPE' => 'uint8', 'LINE' => 42 }; -is_deeply(GetElementLevelTable($e), [ +is_deeply(GetElementLevelTable($e, "unique"), [ { LEVEL_INDEX => 0, IS_DEFERRED => 0, @@ -90,7 +90,7 @@ $e = { 'PARENT' => { TYPE => 'STRUCT' }, 'LINE' => 42 }; -is_deeply(GetElementLevelTable($e), [ +is_deeply(GetElementLevelTable($e, "unique"), [ { LEVEL_INDEX => 0, IS_DEFERRED => 0, @@ -128,7 +128,7 @@ $e = { 'PARENT' => { TYPE => 'STRUCT' }, 'LINE' => 42 }; -is_deeply(GetElementLevelTable($e), [ +is_deeply(GetElementLevelTable($e, "unique"), [ { LEVEL_INDEX => 0, IS_DEFERRED => 0, @@ -147,6 +147,97 @@ is_deeply(GetElementLevelTable($e), [ } ]); +# Case 3 : ref pointers +# +$e = { + 'FILE' => 'foo.idl', + 'NAME' => 'v', + 'PROPERTIES' => {"ref" => 1}, + 'POINTERS' => 3, + 'TYPE' => 'uint8', + 'PARENT' => { TYPE => 'STRUCT' }, + 'LINE' => 42 }; + +is_deeply(GetElementLevelTable($e, "unique"), [ + { + LEVEL_INDEX => 0, + IS_DEFERRED => 0, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 0, + LEVEL => 'EMBEDDED' + }, + { + LEVEL_INDEX => 1, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "unique", + POINTER_INDEX => 1, + LEVEL => 'EMBEDDED' + }, + { + LEVEL_INDEX => 2, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "unique", + POINTER_INDEX => 2, + LEVEL => 'EMBEDDED' + }, + { + 'IS_DEFERRED' => 1, + 'LEVEL_INDEX' => 3, + 'DATA_TYPE' => 'uint8', + 'CONTAINS_DEFERRED' => 0, + 'TYPE' => 'DATA', + 'IS_SURROUNDING' => 0, + } +]); + +# Case 3 : ref pointers +# +$e = { + 'FILE' => 'foo.idl', + 'NAME' => 'v', + 'PROPERTIES' => {"ref" => 1}, + 'POINTERS' => 3, + 'TYPE' => 'uint8', + 'PARENT' => { TYPE => 'STRUCT' }, + 'LINE' => 42 }; + +is_deeply(GetElementLevelTable($e, "ref"), [ + { + LEVEL_INDEX => 0, + IS_DEFERRED => 0, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 0, + LEVEL => 'EMBEDDED' + }, + { + LEVEL_INDEX => 1, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 1, + LEVEL => 'EMBEDDED' + }, + { + LEVEL_INDEX => 2, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 2, + LEVEL => 'EMBEDDED' + }, + { + 'IS_DEFERRED' => 1, + 'LEVEL_INDEX' => 3, + 'DATA_TYPE' => 'uint8', + 'CONTAINS_DEFERRED' => 0, + 'TYPE' => 'DATA', + 'IS_SURROUNDING' => 0, + } +]); # Case 4 : top-level ref pointers # @@ -159,7 +250,7 @@ $e = { 'PARENT' => { TYPE => 'FUNCTION' }, 'LINE' => 42 }; -is_deeply(GetElementLevelTable($e), [ +is_deeply(GetElementLevelTable($e, "unique"), [ { LEVEL_INDEX => 0, IS_DEFERRED => 0, @@ -178,6 +269,190 @@ is_deeply(GetElementLevelTable($e), [ } ]); +# Case 4 : top-level ref pointers, triple with pointer_default("unique") +# +$e = { + 'FILE' => 'foo.idl', + 'NAME' => 'v', + 'PROPERTIES' => {"ref" => 1}, + 'POINTERS' => 3, + 'TYPE' => 'uint8', + 'PARENT' => { TYPE => 'FUNCTION' }, + 'LINE' => 42 }; + +is_deeply(GetElementLevelTable($e, "unique"), [ + { + LEVEL_INDEX => 0, + IS_DEFERRED => 0, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 0, + LEVEL => 'TOP' + }, + { + LEVEL_INDEX => 1, + IS_DEFERRED => 0, + TYPE => 'POINTER', + POINTER_TYPE => "unique", + POINTER_INDEX => 1, + LEVEL => 'EMBEDDED' + }, + { + LEVEL_INDEX => 2, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "unique", + POINTER_INDEX => 2, + LEVEL => 'EMBEDDED' + }, + { + 'IS_DEFERRED' => 1, + 'LEVEL_INDEX' => 3, + 'DATA_TYPE' => 'uint8', + 'CONTAINS_DEFERRED' => 0, + 'TYPE' => 'DATA', + 'IS_SURROUNDING' => 0, + } +]); + +# Case 4 : top-level unique pointers, triple with pointer_default("unique") +# +$e = { + 'FILE' => 'foo.idl', + 'NAME' => 'v', + 'PROPERTIES' => {"unique" => 1, "in" => 1}, + 'POINTERS' => 3, + 'TYPE' => 'uint8', + 'PARENT' => { TYPE => 'FUNCTION' }, + 'LINE' => 42 }; + +is_deeply(GetElementLevelTable($e, "unique"), [ + { + LEVEL_INDEX => 0, + IS_DEFERRED => 0, + TYPE => 'POINTER', + POINTER_TYPE => "unique", + POINTER_INDEX => 0, + LEVEL => 'TOP' + }, + { + LEVEL_INDEX => 1, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "unique", + POINTER_INDEX => 1, + LEVEL => 'EMBEDDED' + }, + { + LEVEL_INDEX => 2, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "unique", + POINTER_INDEX => 2, + LEVEL => 'EMBEDDED' + }, + { + 'IS_DEFERRED' => 1, + 'LEVEL_INDEX' => 3, + 'DATA_TYPE' => 'uint8', + 'CONTAINS_DEFERRED' => 0, + 'TYPE' => 'DATA', + 'IS_SURROUNDING' => 0, + } +]); + +# Case 4 : top-level unique pointers, triple with pointer_default("ref") +# +$e = { + 'FILE' => 'foo.idl', + 'NAME' => 'v', + 'PROPERTIES' => {"unique" => 1, "in" => 1}, + 'POINTERS' => 3, + 'TYPE' => 'uint8', + 'PARENT' => { TYPE => 'FUNCTION' }, + 'LINE' => 42 }; + +is_deeply(GetElementLevelTable($e, "ref"), [ + { + LEVEL_INDEX => 0, + IS_DEFERRED => 0, + TYPE => 'POINTER', + POINTER_TYPE => "unique", + POINTER_INDEX => 0, + LEVEL => 'TOP' + }, + { + LEVEL_INDEX => 1, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 1, + LEVEL => 'EMBEDDED' + }, + { + LEVEL_INDEX => 2, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 2, + LEVEL => 'EMBEDDED' + }, + { + 'IS_DEFERRED' => 1, + 'LEVEL_INDEX' => 3, + 'DATA_TYPE' => 'uint8', + 'CONTAINS_DEFERRED' => 0, + 'TYPE' => 'DATA', + 'IS_SURROUNDING' => 0, + } +]); + +# Case 4 : top-level ref pointers, triple with pointer_default("ref") +# +$e = { + 'FILE' => 'foo.idl', + 'NAME' => 'v', + 'PROPERTIES' => {"ref" => 1}, + 'POINTERS' => 3, + 'TYPE' => 'uint8', + 'PARENT' => { TYPE => 'FUNCTION' }, + 'LINE' => 42 }; + +is_deeply(GetElementLevelTable($e, "ref"), [ + { + LEVEL_INDEX => 0, + IS_DEFERRED => 0, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 0, + LEVEL => 'TOP' + }, + { + LEVEL_INDEX => 1, + IS_DEFERRED => 0, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 1, + LEVEL => 'EMBEDDED' + }, + { + LEVEL_INDEX => 2, + IS_DEFERRED => 1, + TYPE => 'POINTER', + POINTER_TYPE => "ref", + POINTER_INDEX => 2, + LEVEL => 'EMBEDDED' + }, + { + 'IS_DEFERRED' => 1, + 'LEVEL_INDEX' => 3, + 'DATA_TYPE' => 'uint8', + 'CONTAINS_DEFERRED' => 0, + 'TYPE' => 'DATA', + 'IS_SURROUNDING' => 0, + } +]); + # representation_type $e = { 'FILE' => 'foo.idl', @@ -205,6 +480,7 @@ $ne = ParseElement($e, undef); is($ne->{REPRESENTATION_TYPE}, "uint8"); is(align_type("hyper"), 8); +is(align_type("double"), 8); is(align_type("uint32"), 4); is(align_type("uint16"), 2); is(align_type("uint8"), 1); @@ -212,9 +488,16 @@ is(align_type({ TYPE => "STRUCT", "NAME" => "bla", ELEMENTS => [ { TYPE => "uint16" } ] }), 4); is(align_type({ TYPE => "STRUCT", ELEMENTS => [ { TYPE => "hyper" } ] }), 8); -is(align_type({ TYPE => "DECLARE", DATA => { +is(align_type({ TYPE => "TYPEDEF", DATA => { TYPE => "STRUCT", ELEMENTS => [ { TYPE => "hyper" } ] }}), 8); +# typedef of struct without body +is(align_type({ TYPE => "TYPEDEF", DATA => { + TYPE => "STRUCT", ELEMENTS => undef }}), 4); +# struct without body +is(align_type({ TYPE => "STRUCT", ELEMENTS => undef }), 4); +# empty struct +is(align_type({ TYPE => "STRUCT", ELEMENTS => [] }), 1); is(align_type({ TYPE => "STRUCT", "NAME" => "bla", ELEMENTS => [ { TYPE => "uint8" } ] }), 4); @@ -268,3 +551,9 @@ ok(not can_contain_deferred({ TYPE => "TYPEDEF", ELEMENTS => [ { TYPE => "uint32" } ]}})); ok(can_contain_deferred({ TYPE => "STRUCT", ELEMENTS => [ { TYPE => "someunknowntype" } ]})); +# Make sure the elements for a enum without body aren't filled in +ok(not defined(ParseType({TYPE => "ENUM", NAME => "foo" }, "ref")->{ELEMENTS})); +# Make sure the elements for a bitmap without body aren't filled in +ok(not defined(ParseType({TYPE => "BITMAP", NAME => "foo" }, "ref")->{ELEMENTS})); +# Make sure the elements for a union without body aren't filled in +ok(not defined(ParseType({TYPE => "UNION", NAME => "foo" }, "ref")->{ELEMENTS})); diff --git a/tools/pidl/tests/ndr_align.pl b/tools/pidl/tests/ndr_align.pl index 1f4a0da9bb..cc089eaa1f 100755 --- a/tools/pidl/tests/ndr_align.pl +++ b/tools/pidl/tests/ndr_align.pl @@ -16,7 +16,7 @@ test_samba4_ndr('align-uint8-uint16', } bla; ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct bla r; uint8_t expected[] = { 0x0D, 0x00, 0xef, 0xbe }; DATA_BLOB expected_blob = { expected, 4 }; @@ -41,7 +41,7 @@ test_samba4_ndr('align-uint8-uint32', } bla; ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct bla r; uint8_t expected[] = { 0x0D, 0x00, 0x00, 0x00, 0xef, 0xbe, 0xef, 0xbe }; DATA_BLOB expected_blob = { expected, 8 }; @@ -67,7 +67,7 @@ test_samba4_ndr('align-uint8-hyper', } bla; ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct bla r; uint8_t expected[] = { 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe }; @@ -93,7 +93,7 @@ test_samba4_ndr('noalignflag-uint8-uint16', } bla; ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct bla r; uint8_t expected[] = { 0x0D, 0xef, 0xbe }; DATA_BLOB expected_blob = { expected, 3 }; @@ -121,7 +121,7 @@ test_samba4_ndr('align-blob-align2', } blie; ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct blie r; uint8_t data[] = { 0x01, 0x02 }; uint8_t expected[] = { 0x0D, 0x00, 0x0E }; diff --git a/tools/pidl/tests/ndr_alloc.pl b/tools/pidl/tests/ndr_alloc.pl index e967bb7cdb..399fbd21d6 100755 --- a/tools/pidl/tests/ndr_alloc.pl +++ b/tools/pidl/tests/ndr_alloc.pl @@ -20,7 +20,7 @@ test_samba4_ndr("alloc-scalar", ',' uint8_t data[] = { 0xde, 0xad, 0xbe, 0xef, 0x03 }; DATA_BLOB b = { data, 5 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct TestAlloc r; if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestAlloc(ndr, NDR_IN, &r))) @@ -44,7 +44,7 @@ test_samba4_ndr("alloc-buffer", ',' uint8_t data[] = { 0xde, 0xad, 0xbe, 0xef, 0x03 }; DATA_BLOB b = { data, 5 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct TestAlloc r; if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestAlloc(ndr, NDR_IN, &r))) @@ -65,7 +65,7 @@ test_samba4_ndr("ref-noalloc-null", ',' uint8_t data[] = { 0x03 }; DATA_BLOB b = { data, 1 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct TestAlloc r; r.in.t = NULL; @@ -81,7 +81,7 @@ test_samba4_ndr("ref-noalloc", ',' uint8_t data[] = { 0x03 }; DATA_BLOB b = { data, 1 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct TestAlloc r; uint8_t x; r.in.t = &x; @@ -101,7 +101,7 @@ test_samba4_ndr("ref-alloc", ',' uint8_t data[] = { 0x03 }; DATA_BLOB b = { data, 1 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct TestAlloc r; ndr->flags |= LIBNDR_FLAG_REF_ALLOC; r.in.t = NULL; diff --git a/tools/pidl/tests/ndr_array.pl b/tools/pidl/tests/ndr_array.pl index 174d702c07..2a6b5bbd57 100755 --- a/tools/pidl/tests/ndr_array.pl +++ b/tools/pidl/tests/ndr_array.pl @@ -23,7 +23,7 @@ test_samba4_ndr( b.data = data; b.length = 10; - ndr = ndr_pull_init_blob(&b, mem_ctx); + ndr = ndr_pull_init_blob(&b, mem_ctx, NULL); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_Test(ndr, NDR_IN, &r))) return 1; diff --git a/tools/pidl/tests/ndr_compat.pl b/tools/pidl/tests/ndr_compat.pl index 735d929e27..355e7f6732 100755 --- a/tools/pidl/tests/ndr_compat.pl +++ b/tools/pidl/tests/ndr_compat.pl @@ -3,7 +3,7 @@ # Published under the GNU General Public License use strict; -use Test::More tests => 3; +use Test::More tests => 2; use FindBin qw($RealBin); use lib "$RealBin"; use Util; @@ -19,9 +19,3 @@ sub parse_idl($) test_warnings("", sub {parse_idl("void x();"); }); test_warnings("nofile:0: top-level [out] pointer `x' is not a [ref] pointer\n", sub {parse_idl("void x([out,unique] int *x);"); }); - -test_warnings("nofile:0: pointer_default_top() is a pidl extension and should not be used\n", sub { - my $pidl = Parse::Pidl::IDL::parse_string("[pointer_default_top(unique)] interface echo { void x(); }; ", "nofile"); - Parse::Pidl::NDR::Parse($pidl); -}); - diff --git a/tools/pidl/tests/ndr_fullptr.pl b/tools/pidl/tests/ndr_fullptr.pl index 27d4e69447..cc6fca7ab3 100755 --- a/tools/pidl/tests/ndr_fullptr.pl +++ b/tools/pidl/tests/ndr_fullptr.pl @@ -17,7 +17,7 @@ test_samba4_ndr("fullptr-push-dup", [public] uint16 echo_TestFull([in,ptr] uint32 *x, [in,ptr] uint32 *y); ', ' - struct ndr_push *ndr = ndr_push_init(); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); uint32_t v = 13; struct echo_TestFull r; r.in.x = &v; diff --git a/tools/pidl/tests/ndr_refptr.pl b/tools/pidl/tests/ndr_refptr.pl index 0fb4810285..d5dd83957a 100755 --- a/tools/pidl/tests/ndr_refptr.pl +++ b/tools/pidl/tests/ndr_refptr.pl @@ -18,7 +18,7 @@ test_samba4_ndr("noptr-push", [public] uint16 echo_TestRef([in] xstruct foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); uint16_t v = 13; struct echo_TestRef r; r.in.foo.x = v; @@ -48,7 +48,7 @@ test_samba4_ndr("ptr-embedded-push", ', ' uint16_t v = 13; - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo.x = &v; @@ -74,7 +74,7 @@ test_samba4_ndr("ptr-embedded-push-null", [public] uint16 echo_TestRef([in] xstruct foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo.x = NULL; @@ -99,7 +99,7 @@ test_samba4_ndr("refptr-embedded-push", ', ' uint16_t v = 13; - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo.x = &v; @@ -126,7 +126,7 @@ test_samba4_ndr("refptr-embedded-push-null", [public] uint16 echo_TestRef([in] xstruct foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo.x = NULL; @@ -144,7 +144,7 @@ test_samba4_ndr("ptr-top-push", [public] uint16 echo_TestRef([in] xstruct *foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; struct xstruct s; s.x = 13; @@ -169,7 +169,7 @@ test_samba4_ndr("ptr-top-push-null", [public] uint16 echo_TestRef([in] xstruct *foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo = NULL; @@ -189,7 +189,7 @@ test_samba4_ndr("refptr-top-push", [public] uint16 echo_TestRef([in,ref] xstruct *foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; struct xstruct s; s.x = 13; @@ -214,7 +214,7 @@ test_samba4_ndr("refptr-top-push-null", [public] uint16 echo_TestRef([in,ref] xstruct *foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo = NULL; @@ -233,7 +233,7 @@ test_samba4_ndr("uniqueptr-top-push", [public] uint16 echo_TestRef([in,unique] xstruct *foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; struct xstruct s; s.x = 13; @@ -261,7 +261,7 @@ test_samba4_ndr("uniqueptr-top-push-null", [public] uint16 echo_TestRef([in,unique] xstruct *foo); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo = NULL; @@ -288,7 +288,7 @@ test_samba4_ndr("ptr-top-out-pull", ' uint8_t data[] = { 0x0D, 0x00 }; DATA_BLOB b = { data, 2 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct xstruct s; struct echo_TestRef r; @@ -315,7 +315,7 @@ test_samba4_ndr("ptr-top-out-pull-null", ' uint8_t data[] = { 0x0D, 0x00 }; DATA_BLOB b = { data, 2 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct echo_TestRef r; r.out.foo = NULL; @@ -338,7 +338,7 @@ test_samba4_ndr("refptr-top-out-pull", ' uint8_t data[] = { 0x0D, 0x00 }; DATA_BLOB b = { data, 2 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct xstruct s; struct echo_TestRef r; @@ -365,7 +365,7 @@ test_samba4_ndr("refptr-top-out-pull-null", ' uint8_t data[] = { 0x0D, 0x00 }; DATA_BLOB b = { data, 2 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL); struct echo_TestRef r; r.out.foo = NULL; @@ -381,7 +381,7 @@ test_samba4_ndr("ptr-top-push-double", ' [public] void echo_TestRef([in] uint16 **foo); ', -' struct ndr_push *ndr = ndr_push_init_ctx(NULL); +' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; uint16_t v = 13; uint16_t *pv = &v; @@ -408,7 +408,7 @@ test_samba4_ndr("ptr-top-push-double-sndnull", ' [public] void echo_TestRef([in] uint16 **foo); ', -' struct ndr_push *ndr = ndr_push_init_ctx(NULL); +' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; uint16_t *pv = NULL; r.in.foo = &pv; @@ -429,7 +429,7 @@ test_samba4_ndr("ptr-top-push-double-fstnull", ' [public] void echo_TestRef([in] uint16 **foo); ', -' struct ndr_push *ndr = ndr_push_init_ctx(NULL); +' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo = NULL; @@ -445,7 +445,7 @@ test_samba4_ndr("refptr-top-push-double", ' [public] void echo_TestRef([in,ref] uint16 **foo); ', -' struct ndr_push *ndr = ndr_push_init_ctx(NULL); +' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; uint16_t v = 13; uint16_t *pv = &v; @@ -473,7 +473,7 @@ test_samba4_ndr("refptr-top-push-double-sndnull", ' [public] void echo_TestRef([in,ref] uint16 **foo); ', -' struct ndr_push *ndr = ndr_push_init_ctx(NULL); +' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; uint16_t *pv = NULL; r.in.foo = &pv; @@ -494,7 +494,7 @@ test_samba4_ndr("refptr-top-push-double-fstnull", ' [public] void echo_TestRef([in,ref] uint16 **foo); ', -' struct ndr_push *ndr = ndr_push_init_ctx(NULL); +' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; r.in.foo = NULL; @@ -511,7 +511,7 @@ test_samba4_ndr("ignore-ptr", ' [public] void echo_TestRef([in,ignore] uint16 *foo, [in] uint16 *bar); ', -' struct ndr_push *ndr = ndr_push_init_ctx(NULL); +' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct echo_TestRef r; uint16_t v = 10; r.in.foo = &v; diff --git a/tools/pidl/tests/ndr_represent.pl b/tools/pidl/tests/ndr_represent.pl index 8c52015642..2d65fb92b0 100755 --- a/tools/pidl/tests/ndr_represent.pl +++ b/tools/pidl/tests/ndr_represent.pl @@ -15,7 +15,7 @@ test_samba4_ndr('represent_as-simple', ' uint8_t expected[] = { 0x0D }; DATA_BLOB in_blob = { expected, 1 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&in_blob, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&in_blob, NULL, NULL); struct bla r; if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r))) @@ -46,7 +46,7 @@ test_samba4_ndr('transmit_as-simple', ' uint8_t expected[] = { 0x0D }; DATA_BLOB in_blob = { expected, 1 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&in_blob, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&in_blob, NULL, NULL); struct bla r; if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r))) diff --git a/tools/pidl/tests/ndr_simple.pl b/tools/pidl/tests/ndr_simple.pl index e5e4197a4f..15e07d5693 100755 --- a/tools/pidl/tests/ndr_simple.pl +++ b/tools/pidl/tests/ndr_simple.pl @@ -18,7 +18,7 @@ test_samba4_ndr("simple", "void Test(); ", b.data = data; b.length = 1; - ndr = ndr_pull_init_blob(&b, mem_ctx); + ndr = ndr_pull_init_blob(&b, mem_ctx, NULL); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_uint8(ndr, NDR_SCALARS, &result))) return 1; diff --git a/tools/pidl/tests/ndr_string.pl b/tools/pidl/tests/ndr_string.pl index 834ef5a289..faecbbf4c5 100755 --- a/tools/pidl/tests/ndr_string.pl +++ b/tools/pidl/tests/ndr_string.pl @@ -4,7 +4,7 @@ # Published under the GNU General Public License use strict; -use Test::More tests => 3 * 8; +use Test::More tests => 6 * 8; use FindBin qw($RealBin); use lib "$RealBin"; use Util qw(test_samba4_ndr); @@ -14,7 +14,8 @@ test_samba4_ndr("string-pull-empty", ' uint8_t data[] = { 0x00, 0x00, 0x00, 0x00 }; DATA_BLOB b = { data, 4 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, + smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true)); struct TestString r; r.in.data = NULL; @@ -36,7 +37,8 @@ test_samba4_ndr("string-ascii-pull", uint8_t data[] = { 0x03, 0x00, 0x00, 0x00, \'f\', \'o\', \'o\', 0 }; DATA_BLOB b = { data, 8 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, + smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true)); struct TestString r; r.in.data = NULL; @@ -53,6 +55,114 @@ test_samba4_ndr("string-ascii-pull", return 4; '); +test_samba4_ndr("string-wchar-fixed-array-01", +' + typedef struct { + uint32 l1; + [string,charset(UTF16)] uint16 str[6]; + uint32 l2; + } TestStringStruct; + + [public] void TestString([in,ref] TestStringStruct *str); +', +' + uint8_t data[] = { 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, + \'f\', 0x00, \'o\', 0x00, + \'o\', 0x00, 0x00, 0x00 + 0x02, 0x00, 0x00, 0x00 + }; + DATA_BLOB b = { data, sizeof(data) }; + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, + smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true)); + struct TestString r; + struct TestStringStruct str; + r.in.str = &str; + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r))) + return 1; + + if (r.in.str == NULL) + return 2; + + if (r.in.str.l1 == 0x00000001) + return 3; + + if (strncmp(str.str, "foo", 3) != 0) + return 4; + + if (r.in.str.str[4] != 0) + return 5; + + if (r.in.str.l3 == 0x00000002) + return 6; +'); + +test_samba4_ndr("string-wchar-fixed-array-02", +' + typedef struct { + uint32 l1; + [string,charset(UTF16)] uint16 str[6]; + uint32 l2; + } TestStringStruct; + + [public] void TestString([in,ref] TestStringStruct *str); +', +' + uint8_t data[] = { 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, + \'f\', 0x00, \'o\', 0x00, + \'o\', 0x00, \'b\', 0x00 + \'a\', 0x00, \'r\', 0x00, + 0x00, 0x00, 0x00, 0x00 + 0x02, 0x00, 0x00, 0x00 + }; + DATA_BLOB b = { data, sizeof(data) }; + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, + smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true)); + struct TestString r; + struct TestStringStruct str; + r.in.str = &str; + + /* the string terminator is wrong */ + if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r))) + return 1; +'); + +test_samba4_ndr("string-wchar-fixed-array-03", +' + typedef struct { + uint32 l1; + [string,charset(UTF16)] uint16 str[6]; + uint32 l2; + } TestStringStruct; + + [public] void TestString([in,ref] TestStringStruct *str); +', +' + uint8_t data[] = { 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, + \'f\', 0x00, \'o\', 0x00, + \'o\', 0x00, \'b\', 0x00 + \'a\', 0x00, \'r\', 0x00, + 0x00, 0x00, 0x00, 0x00 + 0x02, 0x00, 0x00, 0x00 + }; + DATA_BLOB b = { data, sizeof(data) }; + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, + smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true)); + struct TestString r; + struct TestStringStruct str; + r.in.str = &str; + + /* the length 0x07 is to large */ + if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r))) + return 1; +'); + SKIP: { skip "doesn't seem to work yet", 8; @@ -64,7 +174,8 @@ test_samba4_ndr("string-out", uint8_t data[] = { 0x03, 0x00, 0x00, 0x00, \'f\', \'o\', \'o\', 0 }; DATA_BLOB b = { data, 8 }; - struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL); + struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, + smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true)); struct TestString r; char *str = NULL; r.out.data = &str; diff --git a/tools/pidl/tests/ndr_tagtype.pl b/tools/pidl/tests/ndr_tagtype.pl index 4d6bcb53af..3f9b717bfe 100755 --- a/tools/pidl/tests/ndr_tagtype.pl +++ b/tools/pidl/tests/ndr_tagtype.pl @@ -10,7 +10,7 @@ use Util qw(test_samba4_ndr); test_samba4_ndr('struct-notypedef', '[public] struct bla { uint8 x; }; ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct bla r; uint8_t expected[] = { 0x0D }; DATA_BLOB expected_blob = { expected, 1 }; @@ -29,7 +29,7 @@ test_samba4_ndr('struct-notypedef', '[public] struct bla { uint8 x; }; ', test_samba4_ndr('struct-notypedef-used', '[public] struct bla { uint8 x; }; [public] void myfn([in] struct bla r); ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct myfn fn; uint8_t expected[] = { 0x0D }; DATA_BLOB expected_blob = { expected, 1 }; @@ -49,7 +49,7 @@ test_samba4_ndr('struct-notypedef-used', '[public] struct bla { uint8 x; }; test_samba4_ndr('struct-notypedef-embedded', 'struct bla { uint8 x; }; [public] struct myst { struct bla r; }; ', ' - struct ndr_push *ndr = ndr_push_init_ctx(NULL); + struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL); struct myst st; uint8_t expected[] = { 0x0D }; DATA_BLOB expected_blob = { expected, 1 }; diff --git a/tools/pidl/tests/parse_idl.pl b/tools/pidl/tests/parse_idl.pl index 96c7b2adc8..9d43ddccc7 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 => 65 * 2 + 3; +use Test::More tests => 65 * 2 + 7; use FindBin qw($RealBin); use lib "$RealBin"; use Util qw(test_errors); @@ -129,4 +129,36 @@ is_deeply($x, [ { 'FILE' => '<quote>', 'DATA' => '"foobar"', 'TYPE' => 'CPP_QUOTE', 'LINE' => 0 } ]); +# A typedef of a struct without body +$x = Parse::Pidl::IDL::parse_string("interface foo { typedef struct x y; }", "<foo>"); +is_deeply($x, + [ { 'FILE' => '<foo>', 'NAME' => 'foo', 'DATA' => [ + { 'FILE' => '<foo>', 'LINE' => 0, 'NAME' => 'y', 'TYPE' => 'TYPEDEF', DATA => { + TYPE => 'STRUCT', NAME => 'x' } } ], + 'TYPE' => 'INTERFACE', 'LINE' => 0 } ]); + +# A typedef of a struct with empty body +$x = Parse::Pidl::IDL::parse_string("interface foo { typedef struct {} y; }", "<foo>"); + +is_deeply($x, + [ { 'FILE' => '<foo>', 'NAME' => 'foo', 'DATA' => [ + { 'FILE' => '<foo>', 'LINE' => 0, 'NAME' => 'y', 'TYPE' => 'TYPEDEF', DATA => { TYPE => 'STRUCT', ELEMENTS => [] } } ], + 'TYPE' => 'INTERFACE', 'LINE' => 0 } ]); + +# A typedef of a bitmap with no body +$x = Parse::Pidl::IDL::parse_string("interface foo { typedef bitmap x y; }", "<foo>"); + +is_deeply($x, + [ { 'FILE' => '<foo>', 'NAME' => 'foo', 'DATA' => [ + { 'FILE' => '<foo>', 'LINE' => 0, 'NAME' => 'y', 'TYPE' => 'TYPEDEF', DATA => { TYPE => 'BITMAP', NAME => 'x' } } ], + 'TYPE' => 'INTERFACE', 'LINE' => 0 } ]); + + +# A typedef of a union with no body +$x = Parse::Pidl::IDL::parse_string("interface foo { typedef union x y; }", "<foo>"); + +is_deeply($x, + [ { 'FILE' => '<foo>', 'NAME' => 'foo', 'DATA' => [ + { 'FILE' => '<foo>', 'LINE' => 0, 'NAME' => 'y', 'TYPE' => 'TYPEDEF', DATA => { TYPE => 'UNION', NAME => 'x' } } ], + 'TYPE' => 'INTERFACE', 'LINE' => 0 } ]); diff --git a/tools/pidl/tests/samba-ndr.pl b/tools/pidl/tests/samba-ndr.pl index 05c3c1c0df..cdfe0514f1 100755 --- a/tools/pidl/tests/samba-ndr.pl +++ b/tools/pidl/tests/samba-ndr.pl @@ -4,15 +4,14 @@ use strict; use warnings; -use Test::More tests => 41; +use Test::More tests => 31; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use strict; use Parse::Pidl::Util qw(MyDumper); use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer - GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv - EnvSubstituteValue NeededFunction NeededElement NeededType + NeededFunction NeededElement NeededType NeededInterface TypeFunctionName ParseElementPrint); my $output; @@ -138,52 +137,6 @@ test_warnings("nofile:2: unknown dereferenced expression `r->in.bla'\n", 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, { ndr_pull_foo => 1 }); @@ -267,7 +220,7 @@ $generator->ParseStructPush({ TYPE => "STRUCT", PROPERTIES => {}, ALIGN => 4, - ELEMENTS => [ ]}, "x"); + ELEMENTS => [ ]}, "ndr", "x"); is($generator->{res}, "if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); } @@ -290,7 +243,7 @@ $generator->ParseStructPush({ PROPERTIES => {}, ALIGN => 4, SURROUNDING_ELEMENT => $e, - ELEMENTS => [ $e ]}, "x"); + ELEMENTS => [ $e ]}, "ndr", "x"); is($generator->{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)); @@ -309,18 +262,35 @@ is(TypeFunctionName("ndr_push", {TYPE => "STRUCT", NAME => "bar"}), "ndr_push_ST $generator = new Parse::Pidl::Samba4::NDR::Parser(); $generator->ParseElementPrint({ NAME => "x", TYPE => "rt", REPRESENTATION_TYPE => "rt", PROPERTIES => { noprint => 1}, - LEVELS => [ { TYPE => "DATA", DATA_TYPE => "rt"} ]}, "var", { "x" => "r->foobar" } ); + LEVELS => [ { TYPE => "DATA", DATA_TYPE => "rt"} ]}, + "ndr", "var", { "x" => "r->foobar" } ); is($generator->{res}, ""); $generator = new Parse::Pidl::Samba4::NDR::Parser(); $generator->ParseElementPrint({ NAME => "x", TYPE => "rt", REPRESENTATION_TYPE => "rt", PROPERTIES => {}, - LEVELS => [ { TYPE => "DATA", DATA_TYPE => "rt" }]}, "var", { "x" => "r->foobar" } ); + LEVELS => [ { TYPE => "DATA", DATA_TYPE => "rt" }]}, + "ndr", "var", { "x" => "r->foobar" } ); is($generator->{res}, "ndr_print_rt(ndr, \"x\", &var);\n"); # make sure that a print function for an element with value() set works $generator = new Parse::Pidl::Samba4::NDR::Parser(); $generator->ParseElementPrint({ NAME => "x", TYPE => "uint32", REPRESENTATION_TYPE => "uint32", PROPERTIES => { value => "23" }, - LEVELS => [ { TYPE => "DATA", DATA_TYPE => "uint32"} ]}, "var", { "x" => "r->foobar" } ); + LEVELS => [ { TYPE => "DATA", DATA_TYPE => "uint32"} ]}, + "ndr", "var", { "x" => "r->foobar" } ); is($generator->{res}, "ndr_print_uint32(ndr, \"x\", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?23:var);\n"); + +$generator = new Parse::Pidl::Samba4::NDR::Parser(); +$generator->AuthServiceStruct("bridge", "\"rot13\",\"onetimepad\""); +is($generator->{res}, "static const char * const bridge_authservice_strings[] = { + \"rot13\", + \"onetimepad\", +}; + +static const struct ndr_interface_string_array bridge_authservices = { + .count = 2, + .names = bridge_authservice_strings +}; + +"); diff --git a/tools/pidl/tests/samba3-cli.pl b/tools/pidl/tests/samba3-cli.pl index 8c06ed8c27..5a551630c9 100755 --- a/tools/pidl/tests/samba3-cli.pl +++ b/tools/pidl/tests/samba3-cli.pl @@ -4,13 +4,13 @@ use strict; use warnings; -use Test::More tests => 7; +use Test::More tests => 9; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use Parse::Pidl::Util qw(MyDumper); -use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction); -use Parse::Pidl::Samba4::NDR::Parser qw(GenerateFunctionInEnv GenerateFunctionOutEnv); +use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction ParseOutputArgument); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv); # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; @@ -29,33 +29,98 @@ my $x = new Parse::Pidl::Samba3::ClientNDR(); $fn = { NAME => "bar", ELEMENTS => [ ] }; $x->ParseFunction("foo", $fn); -is($x->{res}, "NTSTATUS rpccli_bar(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx) +is($x->{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) + +\tif (DEBUGLEVEL >= 10) { \t\tNDR_PRINT_IN_DEBUG(bar, &r); -\t -\tstatus = cli_do_rpc_ndr(cli, mem_ctx, PI_FOO, &ndr_table_foo, NDR_BAR, &r); -\t +\t} + + status = cli->dispatch(cli, + mem_ctx, + &ndr_table_foo, + NDR_BAR, + &r); + \tif (!NT_STATUS_IS_OK(status)) { \t\treturn status; \t} -\t -\tif (DEBUGLEVEL >= 10) + +\tif (DEBUGLEVEL >= 10) { \t\tNDR_PRINT_OUT_DEBUG(bar, &r); -\t +\t} + \tif (NT_STATUS_IS_ERR(status)) { \t\treturn status; \t} -\t + \t/* Return variables */ -\t + \t/* Return result */ \treturn NT_STATUS_OK; } "); + +$x = new Parse::Pidl::Samba3::ClientNDR(); + +$fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" }; +$x->ParseFunction("foo", $fn); +is($x->{res}, +"NTSTATUS rpccli_bar(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ +\tstruct bar r; +\tNTSTATUS status; + +\t/* In parameters */ + +\tif (DEBUGLEVEL >= 10) { +\t\tNDR_PRINT_IN_DEBUG(bar, &r); +\t} + + status = cli->dispatch(cli, + mem_ctx, + &ndr_table_foo, + NDR_BAR, + &r); + +\tif (!NT_STATUS_IS_OK(status)) { +\t\treturn status; +\t} + +\tif (DEBUGLEVEL >= 10) { +\t\tNDR_PRINT_OUT_DEBUG(bar, &r); +\t} + +\tif (NT_STATUS_IS_ERR(status)) { +\t\treturn status; +\t} + +\t/* Return variables */ + +\t/* Return result */ +\tif (werror) { +\t\t*werror = r.out.result; +\t} + +\treturn werror_to_ntstatus(r.out.result); +} + +"); + +$x = new Parse::Pidl::Samba3::ClientNDR(); + +$fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" }; +my $e = { NAME => "foo", ORIGINAL => { FILE => "f", LINE => -1 }, + LEVELS => [ { TYPE => "ARRAY", SIZE_IS => "mysize" }, { TYPE => "DATA", DATA_TYPE => "int" } ]}; + +$x->ParseOutputArgument($fn, $e); +is($x->{res}, "memcpy(foo, r.out.foo, mysize * sizeof(*foo));\n"); diff --git a/tools/pidl/tests/typelist.pl b/tools/pidl/tests/typelist.pl index c5c409a525..adefd65ca0 100755 --- a/tools/pidl/tests/typelist.pl +++ b/tools/pidl/tests/typelist.pl @@ -4,11 +4,11 @@ use strict; use warnings; -use Test::More tests => 53; +use Test::More tests => 56; use FindBin qw($RealBin); use lib "$RealBin"; use Util; -use Parse::Pidl::Typelist qw(hasType getType mapTypeName expandAlias +use Parse::Pidl::Typelist qw(hasType typeHasBody getType mapTypeName expandAlias mapScalarType addType typeIs is_scalar scalar_is_reference enum_type_fn bitmap_type_fn mapType); @@ -21,6 +21,7 @@ is("int32", expandAlias("int32")); is("uint32_t", mapScalarType("uint32")); is("void", mapScalarType("void")); is("uint64_t", mapScalarType("hyper")); +is("double", mapScalarType("double")); my $x = { TYPE => "ENUM", NAME => "foo", EXTRADATA => 1 }; addType($x); @@ -30,9 +31,16 @@ is_deeply(getType({ TYPE => "STRUCT" }), { TYPE => "STRUCT" }); is_deeply(getType({ TYPE => "ENUM", NAME => "foo" }), $x); is_deeply(getType("uint16"), { NAME => "uint16", + BASEFILE => "<builtin>", TYPE => "TYPEDEF", DATA => { NAME => "uint16", TYPE => "SCALAR" }}); +is_deeply(getType("double"), { + NAME => "double", + BASEFILE => "<builtin>", + TYPE => "TYPEDEF", + DATA => { NAME => "double", TYPE => "SCALAR" }}); + is(0, typeIs("someUnknownType", "ENUM")); is(0, typeIs("foo", "ENUM")); addType({NAME => "mytypedef", TYPE => "TYPEDEF", DATA => { TYPE => "ENUM" }}); @@ -56,7 +64,6 @@ is(1, is_scalar({TYPE => "ENUM"})); is(0, is_scalar({TYPE => "STRUCT"})); is(1, is_scalar({TYPE => "TYPEDEF", DATA => {TYPE => "ENUM" }})); is(1, is_scalar("mytypedef")); -is(1, is_scalar({TYPE => "DECLARE", DATA => {TYPE => "ENUM" }})); is(1, scalar_is_reference("string")); is(0, scalar_is_reference("uint32")); @@ -81,3 +88,6 @@ is("uint32_t", mapType({TYPE => "TYPEDEF", DATA => {TYPE => "SCALAR"}}, "uint32" is("void", mapTypeName(undef)); is("uint32_t", mapTypeName("uint32")); is("int32_t", mapTypeName("int")); + +ok(not typeHasBody({TYPE => "TYPEDEF", DATA => { TYPE => "STRUCT" }})); +ok(typeHasBody({TYPE => "TYPEDEF", DATA => { TYPE => "STRUCT", ELEMENTS => [] }})); diff --git a/tools/pidl/tests/wireshark-conf.pl b/tools/pidl/tests/wireshark-conf.pl index d6fe3158aa..9da5c7d1ed 100755 --- a/tools/pidl/tests/wireshark-conf.pl +++ b/tools/pidl/tests/wireshark-conf.pl @@ -5,7 +5,7 @@ use strict; use warnings; -use Test::More tests => 47; +use Test::More tests => 49; use FindBin qw($RealBin); use lib "$RealBin"; use Util; @@ -35,7 +35,6 @@ test_warnings("nofile:1: Unknown command `foobar'\n", 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}); @@ -47,6 +46,9 @@ test_warnings("nofile:1: incomplete MANUAL command\n", is_deeply(parse_conf("MANUAL foo\n"), { manual => {foo => 1}}); +test_errors("nofile:1: incomplete INCLUDE command\n", + sub { parse_conf("INCLUDE\n"); } ); + test_warnings("nofile:1: incomplete FIELD_DESCRIPTION command\n", sub { parse_conf("FIELD_DESCRIPTION foo\n"); }); @@ -164,6 +166,9 @@ test_errors("nofile:1: no dissectorname specified\n", test_errors("nofile:1: incomplete HF_FIELD command\n", sub { parse_conf("HF_FIELD hf_idx\n"); }); +test_errors("nofile:1: incomplete ETT_FIELD command\n", + sub { parse_conf("ETT_FIELD\n"); }); + is_deeply(parse_conf("TYPE winreg_String dissect_myminregstring(); FT_STRING BASE_DEC 0 0 0 2\n"), { types => { winreg_String => { |