sync pidl from samba TODO tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm tools/pidl/lib...
authorStefan Metzmacher <metze@samba.org>
Sat, 19 Mar 2022 02:14:26 +0000 (03:14 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 3 Feb 2023 09:28:37 +0000 (10:28 +0100)
45 files changed:
tools/pidl/idl.yp
tools/pidl/lib/Parse/Pidl.pm
tools/pidl/lib/Parse/Pidl/CUtil.pm
tools/pidl/lib/Parse/Pidl/Compat.pm
tools/pidl/lib/Parse/Pidl/Dump.pm
tools/pidl/lib/Parse/Pidl/Expr.pm
tools/pidl/lib/Parse/Pidl/IDL.pm
tools/pidl/lib/Parse/Pidl/NDR.pm
tools/pidl/lib/Parse/Pidl/ODL.pm
tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
tools/pidl/lib/Parse/Pidl/Samba4.pm
tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm
tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm
tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm
tools/pidl/lib/Parse/Pidl/Samba4/Header.pm
tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
tools/pidl/lib/Parse/Pidl/Samba4/Python.pm
tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm
tools/pidl/lib/Parse/Pidl/Samba4/Template.pm
tools/pidl/lib/Parse/Pidl/Typelist.pm
tools/pidl/lib/Parse/Pidl/Util.pm
tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm
tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
tools/pidl/lib/wscript_build [deleted file]
tools/pidl/pidl
tools/pidl/tests/Util.pm
tools/pidl/tests/ndr_align.pl
tools/pidl/tests/ndr_alloc.pl
tools/pidl/tests/ndr_array.pl
tools/pidl/tests/ndr_compat.pl
tools/pidl/tests/ndr_fullptr.pl
tools/pidl/tests/ndr_refptr.pl
tools/pidl/tests/ndr_represent.pl
tools/pidl/tests/ndr_simple.pl
tools/pidl/tests/ndr_string.pl
tools/pidl/tests/ndr_tagtype.pl
tools/pidl/tests/parse_idl.pl
tools/pidl/tests/samba-ndr.pl
tools/pidl/tests/samba3-cli.pl
tools/pidl/tests/tdr.pl
tools/pidl/tests/test_util.pl
tools/pidl/wscript

index 08f982a94b975d6d32bccc7478837b7fb5a1ffa3..c8a65f6f629328e752c26eecfe5a6cd42d05b446 100644 (file)
@@ -611,7 +611,7 @@ again:
        for ($parser->YYData->{INPUT}) {
                if (/^\#/) {
                        # Linemarker format is described at
-                       # https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
+                       # http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
                        if (s/^\# (\d+) \"(.*?)\"(( \d+){1,4}|)//) {
                                $parser->YYData->{LINE} = $1-1;
                                $parser->YYData->{FILE} = $2;
index 40e3673908e0c54d680ec3667a6cec5083b0c93e..e4c39b3d063afe22e65e4479b0a9028110acfa41 100644 (file)
@@ -12,7 +12,7 @@ require Exporter;
 @EXPORT_OK = qw(warning error fatal $VERSION);
 
 use strict;
-
+use warnings;
 use vars qw ( $VERSION );
 
 $VERSION = '0.02';
index 9deb6ee1779ab3beac27f24ea734b74f8c8f6266..ccd8fcc3d820593128b064b434dcb99329e59b5f 100644 (file)
@@ -11,6 +11,7 @@ use vars qw($VERSION);
 $VERSION = '0.01';
 
 use strict;
+use warnings;
 
 sub get_pointer_to($)
 {
index b8abcb8819568d1887e456d9a6a6da8ac683b463..062a53b8beaf94b450b9c0ca8ca11a212e2cc870 100644 (file)
@@ -8,6 +8,7 @@ package Parse::Pidl::Compat;
 use Parse::Pidl qw(warning);
 use Parse::Pidl::Util qw(has_property);
 use strict;
+use warnings;
 
 use vars qw($VERSION);
 $VERSION = '0.01';
index 4e623db673a24233d2bb091e147ee1f879be6240..5d241b812c59aa16c5afac3ea7e3be7e12b41ebb 100644 (file)
@@ -27,6 +27,7 @@ $VERSION = '0.01';
 @EXPORT_OK = qw(DumpType DumpTypedef DumpStruct DumpEnum DumpBitmap DumpUnion DumpFunction);
 
 use strict;
+use warnings;
 use Parse::Pidl::Util qw(has_property);
 
 my($res);
index 24581d29f4902288b04a1b5b74a5db068c77e004..967d687670edfe0b55a73408daa89045f0f97fea 100644 (file)
@@ -10,6 +10,7 @@
 package Parse::Pidl::Expr;
 use vars qw ( @ISA );
 use strict;
+use warnings;
 
 @ISA= qw ( Parse::Yapp::Driver );
 use Parse::Yapp::Driver;
index 6927c892556b8bc6f5d174091b7e5c45d140b77e..28bdf2f9d8491be67f0215de2f229607cdcae0e5 100644 (file)
@@ -10,6 +10,7 @@
 package Parse::Pidl::IDL;
 use vars qw ( @ISA );
 use strict;
+use warnings;
 
 @ISA= qw ( Parse::Yapp::Driver );
 use Parse::Yapp::Driver;
index 003156e3a11ef7efce7195afe0cb4e12c4ba183d..d17d0b404ed0e3122bbef5129597c4b6a3a4bf86 100644 (file)
@@ -38,6 +38,7 @@ $VERSION = '0.01';
 @EXPORT_OK = qw(GetElementLevelTable ParseElement ReturnTypeElement ValidElement align_type mapToScalar ParseType can_contain_deferred is_charset_array);
 
 use strict;
+use warnings;
 use Parse::Pidl qw(warning fatal);
 use Parse::Pidl::Typelist qw(hasType getType typeIs expandAlias mapScalarType is_fixed_size_scalar);
 use Parse::Pidl::Util qw(has_property property_matches);
@@ -80,7 +81,8 @@ my $scalar_alignment = {
        'ipv4address' => 4,
        'ipv6address' => 4, #16?
        'dnsp_name' => 1,
-       'dnsp_string' => 1
+       'dnsp_string' => 1,
+       'HRESULT' => 4,
 };
 
 sub GetElementLevelTable($$$)
@@ -115,7 +117,7 @@ sub GetElementLevelTable($$$)
                warning($e, "[out] argument `$e->{NAME}' not a pointer") if ($needptrs > $e->{POINTERS});
        }
 
-       my $allow_pipe = ($e->{PARENT}->{TYPE} eq "FUNCTION");
+       my $allow_pipe = (($e->{PARENT}->{TYPE} // '') eq "FUNCTION");
        my $is_pipe = typeIs($e->{TYPE}, "PIPE");
 
        if ($is_pipe) {
@@ -468,7 +470,12 @@ sub align_type($)
        my ($e) = @_;
 
        if (ref($e) eq "HASH" and $e->{TYPE} eq "SCALAR") {
-               return $scalar_alignment->{$e->{NAME}};
+               my $ret = $scalar_alignment->{$e->{NAME}};
+               if (not defined $ret) {
+                       warning($e, "no scalar alignment for $e->{NAME}!");
+                       return 0;
+               }
+               return $ret;
        }
 
        return 0 if ($e eq "EMPTY");
@@ -903,7 +910,7 @@ sub ParseInterface($)
 
        return { 
                NAME => $idl->{NAME},
-               UUID => lc(has_property($idl, "uuid")),
+               UUID => lc(has_property($idl, "uuid") // ''),
                VERSION => $version,
                TYPE => "INTERFACE",
                PROPERTIES => $idl->{PROPERTIES},
@@ -1094,6 +1101,7 @@ my %property_list = (
        "gensize"               => ["TYPEDEF", "STRUCT", "UNION"],
        "value"                 => ["ELEMENT"],
        "flag"                  => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
+       "max_recursion"         => ["ELEMENT"],
 
        # generic
        "public"                => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
index 14e77fa93f249b6039d459bed4261b358695ded7..12f869c662e67a6585e1b16d60feb0fb82d02579 100644 (file)
@@ -10,6 +10,7 @@ use Parse::Pidl::Util qw(has_property unmake_str);
 use Parse::Pidl::Typelist qw(hasType getType);
 use File::Basename;
 use strict;
+use warnings;
 
 use vars qw($VERSION);
 $VERSION = '0.01';
index 6acf1c5af2cb30140d88b3437fb619f569f0f834..816440ef0330358888854ce60be0321de5cc3a0c 100644 (file)
@@ -6,12 +6,10 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba3::ClientNDR;
-
-use Exporter;
-@ISA = qw(Exporter);
-@EXPORT_OK = qw(ParseFunction $res $res_hdr);
+use base Parse::Pidl::Base;
 
 use strict;
+use warnings;
 use Parse::Pidl qw(fatal warning error);
 use Parse::Pidl::Util qw(has_property ParseExpr genpad);
 use Parse::Pidl::NDR qw(ContainsPipe);
@@ -19,13 +17,10 @@ use Parse::Pidl::Typelist qw(mapTypeName);
 use Parse::Pidl::Samba4 qw(DeclLong);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
 
+
 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} .= $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 new($)
index c87d17a5a78c1ab21b70fc7e25cdd85875a0efc6..d93d519726074a36312eecdc387ada4346fe60e1 100644 (file)
@@ -11,6 +11,7 @@ use Exporter;
 @EXPORT_OK = qw(DeclLevel);
 
 use strict;
+use warnings;
 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);
@@ -103,7 +104,7 @@ sub CallWithStruct($$$$$$)
                if (grep(/out/, @{$_->{DIRECTION}})) { $hasout = 1; }
        }
 
-       pidl "ZERO_STRUCT(r->out);" if ($hasout);
+       pidl "NDR_ZERO_STRUCT(r->out);" if ($hasout);
 
        foreach (@{$fn->{ELEMENTS}}) {
                my @dir = @{$_->{DIRECTION}};
index b720ab901596c125c808fb9a3e4e62249c2b1eed..6b3f221887fbc318478bebda1ff974b00192bd68 100644 (file)
@@ -14,6 +14,7 @@ use Parse::Pidl::NDR qw(GetNextLevel);
 use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
 use Parse::Pidl qw(fatal error);
 use strict;
+use warnings;
 
 use vars qw($VERSION);
 $VERSION = '0.01';
index de7d4547a5b020cbb97f990c5f6ab7289a82c6b0..159f417236f27c375d2446ced4485462890dfb71 100644 (file)
@@ -10,6 +10,7 @@ use vars qw($VERSION);
 $VERSION = '0.01';
 
 use strict;
+use warnings;
 
 sub GetArgumentProtoList($)
 {
index 35e6e3f0d1969210e6f3f2275eb3c1968cd456fa..1630cf235dc969aec2e4e8ad199ce4d65d4ee9cf 100644 (file)
@@ -14,6 +14,7 @@ use vars qw($VERSION);
 $VERSION = '0.01';
 
 use strict;
+use warnings;
 
 my($res);
 
@@ -101,7 +102,7 @@ static $tn dcom_proxy_$interface->{NAME}_$name(struct $interface->{NAME} *d, TAL
                return status;
        }
 
-       ZERO_STRUCT(r.in.ORPCthis);
+       NDR_ZERO_STRUCT(r.in.ORPCthis);
        r.in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION;
        r.in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION;
 ";
index 239f5baaeedf96883e37553d652cfc2036d9d495..7198038357246121dc229240550da44d54cfd15a 100644 (file)
@@ -9,6 +9,7 @@ package Parse::Pidl::Samba4::COM::Stub;
 
 use Parse::Pidl::Util qw(has_property);
 use strict;
+use warnings;
 
 use vars qw($VERSION);
 $VERSION = '0.01';
@@ -125,8 +126,6 @@ static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_C
         /* unravel the NDR for the packet */
        status = dcerpc_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r);
        if (!NT_STATUS_IS_OK(status)) {
-               dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
-                                 &dce_call->pkt.u.request.stub_and_verifier);
                dce_call->fault_code = DCERPC_FAULT_NDR;
                return NT_STATUS_NET_WRITE_FAULT;
        }
@@ -152,8 +151,6 @@ pidl "
        }
 
        if (dce_call->fault_code != 0) {
-               dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
-                                 &dce_call->pkt.u.request.stub_and_verifier);
                return NT_STATUS_NET_WRITE_FAULT;
        }
 
@@ -175,8 +172,6 @@ pidl "
        }
 
        if (dce_call->fault_code != 0) {
-               dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
-                                 &dce_call->pkt.u.request.stub_and_verifier);
                return NT_STATUS_NET_WRITE_FAULT;
        }
 
index e9b7bee040c922db15ded9dd1db73c9a9b3b718b..b818dce30ca517a82108b8f2f3aa0799d83c074c 100644 (file)
@@ -11,6 +11,7 @@ require Exporter;
 @EXPORT_OK = qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
 
 use strict;
+use warnings;
 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 ParseExpr);
index 040cd5a4bd337586a15edd9d32488876d755d781..58ec389a9f3a3cc0cfefff06b074aeb49ddf753c 100644 (file)
@@ -5,10 +5,7 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba4::NDR::Client;
-
-use Exporter;
-@ISA = qw(Exporter);
-@EXPORT_OK = qw(Parse);
+use parent Parse::Pidl::Base;
 
 use Parse::Pidl qw(fatal warning error);
 use Parse::Pidl::Util qw(has_property ParseExpr genpad);
@@ -17,18 +14,14 @@ use Parse::Pidl::Typelist qw(mapTypeName);
 use Parse::Pidl::Samba4 qw(choose_header is_intree DeclLong);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
 
+
 use vars qw($VERSION);
 $VERSION = '0.01';
 
 use strict;
+use warnings;
 
-sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
-sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
-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 pidl_both($$) { my ($self, $txt) = @_; $self->{hdr} .= "$txt\n"; $self->{res_hdr} .= "$txt\n"; }
 sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
-
 sub new($)
 {
        my ($class) = shift;
@@ -496,7 +489,7 @@ sub ParseFunction_Send($$$$)
 
        if (defined($fn->{RETURN_TYPE})) {
                $self->pidl("/* Result */");
-               $self->pidl("ZERO_STRUCT(state->orig.out.result);");
+               $self->pidl("NDR_ZERO_STRUCT(state->orig.out.result);");
                $self->pidl("");
        }
 
@@ -585,7 +578,7 @@ sub ParseFunction_Done($$$$)
        }
 
        $self->pidl("/* Reset temporary structure */");
-       $self->pidl("ZERO_STRUCT(state->tmp);");
+       $self->pidl("NDR_ZERO_STRUCT(state->tmp);");
        $self->pidl("");
 
        $self->pidl("tevent_req_done(req);");
@@ -698,7 +691,7 @@ sub ParseFunction_Sync($$$$)
 
        if (defined($fn->{RETURN_TYPE})) {
                $self->pidl("/* Result */");
-               $self->pidl("ZERO_STRUCT(r.out.result);");
+               $self->pidl("NDR_ZERO_STRUCT(r.out.result);");
                $self->pidl("");
        }
 
index cfcd29e25a7b07c2e608a7a7f6a4b28d800ef88b..b92d8537b5c281ee43bde9dc472c1fdca08ae78f 100644 (file)
@@ -6,14 +6,22 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba4::NDR::Parser;
+use parent Parse::Pidl::Base;
 
 require Exporter;
-@ISA = qw(Exporter);
+push @ISA, qw(Exporter);
 @EXPORT_OK = qw(check_null_pointer NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint);
 
 use strict;
+use warnings;
 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::Util qw(has_property
+                        ParseExpr
+                        ParseExprExt
+                        print_uuid
+                        unmake_str
+                        parse_int
+                        parse_range);
 use Parse::Pidl::CUtil qw(get_pointer_to get_value_of get_array_element);
 use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
 use Parse::Pidl::Samba4 qw(is_intree choose_header ArrayDynamicallyAllocated);
@@ -76,25 +84,23 @@ sub has_fast_array($$)
 
        my $t = getType($nl->{DATA_TYPE});
 
-       # Only uint8 and string have fast array functions at the moment
-       return ($t->{NAME} eq "uint8") or ($t->{NAME} eq "string");
+       # Only uint8 has a fast array function at the moment
+       return ($t->{NAME} eq "uint8");
 }
 
-
-####################################
-# pidl() is our basic output routine
-sub pidl($$)
+sub is_public_struct
 {
-       my ($self, $d) = @_;
-       if ($d) {
-               $self->{res} .= $self->{tabs};
-               $self->{res} .= $d;
+       my ($d) = @_;
+       if (!has_property($d, "public")) {
+               return 0;
+       }
+       my $t = $d;
+       if ($d->{TYPE} eq "TYPEDEF") {
+               $t = $d->{DATA};
        }
-       $self->{res} .="\n";
+       return $t->{TYPE} eq "STRUCT";
 }
 
-sub pidl_hdr($$) { my ($self, $d) = @_; $self->{res_hdr} .= "$d\n"; }
-
 ####################################
 # defer() is like pidl(), but adds to 
 # a deferred buffer which is then added to the 
@@ -123,18 +129,6 @@ sub add_deferred($)
        $self->{defer_tabs} = "";
 }
 
-sub indent($)
-{
-       my ($self) = @_;
-       $self->{tabs} .= "\t";
-}
-
-sub deindent($)
-{
-       my ($self) = @_;
-       $self->{tabs} = substr($self->{tabs}, 0, -1);
-}
-
 #####################################################################
 # declare a function public or static, depending on its attributes
 sub fn_declare($$$$)
@@ -346,22 +340,29 @@ sub ParseArrayPullGetSize($$$$$$)
 
        my $size;
 
-       if ($l->{IS_CONFORMANT}) {
-               $size = "ndr_get_array_size($ndr, " . get_pointer_to($var_name) . ")";
+       my $array_size = "size_$e->{NAME}_$l->{LEVEL_INDEX}";
+
+       if ($l->{IS_CONFORMANT} and (defined($l->{SIZE_IS}) or not $l->{IS_ZERO_TERMINATED})) {
+               $self->pidl("NDR_CHECK(ndr_get_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_size));");
+
+       } elsif ($l->{IS_CONFORMANT}) {
+               # This will be the last use of the array_size token
+               $self->pidl("NDR_CHECK(ndr_steal_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_size));");
+
        } elsif ($l->{IS_ZERO_TERMINATED} and $l->{SIZE_IS} == 0 and $l->{LENGTH_IS} == 0) { # Noheader arrays
                $size = "ndr_get_string_size($ndr, sizeof(*$var_name))";
+               $self->pidl("$array_size = $size;");
+
        } else {
                $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()\");"),
                        check_fully_dereferenced($e, $env));
+               $self->pidl("$array_size = $size;");
        }
 
-       $self->pidl("size_$e->{NAME}_$l->{LEVEL_INDEX} = $size;");
-       my $array_size = "size_$e->{NAME}_$l->{LEVEL_INDEX}";
-
        if (my $range = has_property($e, "range")) {
-               my ($low, $high) = split(/,/, $range, 2);
+               my ($low, $high) = parse_range($range);
                if ($low < 0) {
                        warning(0, "$low is invalid for the range of an array size");
                }
@@ -391,12 +392,16 @@ sub ParseArrayPullGetLength($$$$$$;$)
                return $array_size;
        }
 
-       my $length = "ndr_get_array_length($ndr, " . get_pointer_to($var_name) .")";
-       $self->pidl("length_$e->{NAME}_$l->{LEVEL_INDEX} = $length;");
        my $array_length = "length_$e->{NAME}_$l->{LEVEL_INDEX}";
+       if ($l->{IS_VARYING} and (defined($l->{LENGTH_IS}) or not $l->{IS_ZERO_TERMINATED})) {
+               $self->pidl("NDR_CHECK(ndr_get_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_length));");
+       } else {
+               # This will be the last use of the array_length token
+               $self->pidl("NDR_CHECK(ndr_steal_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_length));");
+       }
 
        if (my $range = has_property($e, "range")) {
-               my ($low, $high) = split(/,/, $range, 2);
+               my ($low, $high) = parse_range($range);
                if ($low < 0) {
                        warning(0, "$low is invalid for the range of an array size");
                }
@@ -444,7 +449,14 @@ sub ParseArrayPullHeader($$$$$$)
                        check_null_pointer($e, $env, sub { $self->defer(shift); },
                                           "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));");
+               if (ContainsDeferred($e, $l)) {
+                       # We will be needing the array_size token in
+                       # the NDR_BUFFERS call, so don't steal it now
+                       $self->defer("NDR_CHECK(ndr_check_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+               } else {
+                       # This will be deferred until after the last ndr_get_array_size()
+                       $self->defer("NDR_CHECK(ndr_check_steal_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+               }
                $self->defer_deindent;
                $self->defer("}");
        }
@@ -456,7 +468,8 @@ sub ParseArrayPullHeader($$$$$$)
                        check_null_pointer($e, $env, sub { $self->defer(shift); },
                                           "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));");
+               # This will be deferred until after the last ndr_get_array_length()
+               $self->defer("NDR_CHECK(ndr_check_steal_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", $length));");
                $self->defer_deindent;
                $self->defer("}");
        }
@@ -647,8 +660,6 @@ sub ParseElementPushLevel
                                $self->pidl("NDR_CHECK(ndr_push_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));");
                                return;
                        } 
-               } elsif ($l->{TYPE} eq "SWITCH") {
-                       $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") {
@@ -709,6 +720,14 @@ sub ParseElementPushLevel
                        $self->pidl("}");
                }
        } elsif ($l->{TYPE} eq "SWITCH") {
+               my $nl = GetNextLevel($e,$l);
+               my $needs_deferred_switch = is_deferred_switch_non_empty($nl);
+
+               # Avoid setting a switch value if it will not be
+               # consumed again in the NDR_BUFFERS pull
+               if ($needs_deferred_switch or !$deferred) {
+                       $self->ParseSwitchPush($e, $l, $ndr, $var_name, $env);
+               }
                $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, $primitives, $deferred);
        }
 }
@@ -993,15 +1012,22 @@ sub ParseDataPull($$$$$$$)
 
                $var_name = get_pointer_to($var_name);
 
+               if (my $depth = has_property($e, "max_recursion")) {
+                       my $d = parse_int($depth);
+                       $self->pidl("NDR_RECURSION_CHECK($ndr, $d);");
+               }
                $self->pidl("NDR_CHECK(".TypeFunctionName("ndr_pull", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));");
+               if (has_property($e, "max_recursion")) {
+                       $self->pidl("NDR_RECURSION_UNWIND($ndr);");
+               }
 
                my $pl = GetPrevLevel($e, $l);
 
                my $range = has_property($e, "range");
-               if ($range and $pl->{TYPE} ne "ARRAY") {
+               if ($range and (not $pl or $pl->{TYPE} ne "ARRAY")) {
                        $var_name = get_value_of($var_name);
                        my $signed = Parse::Pidl::Typelist::is_signed($l->{DATA_TYPE});
-                       my ($low, $high) = split(/,/, $range, 2);
+                       my ($low, $high) = parse_range($range);
                        if ($low < 0 and not $signed) {
                                warning(0, "$low is invalid for the range of an unsigned type");
                        }
@@ -1134,7 +1160,7 @@ sub ParseElementPullLevel
        if (has_property($e, "skip") or has_property($e, "skip_noinit")) {
                $self->pidl("/* [skip] '$var_name' */");
                if (not has_property($e, "skip_noinit")) {
-                       $self->pidl("ZERO_STRUCT($var_name);");
+                       $self->pidl("NDR_ZERO_STRUCT($var_name);");
                }
                return;
        }
@@ -1174,8 +1200,6 @@ sub ParseElementPullLevel
                        }
                } elsif ($l->{TYPE} eq "POINTER") {
                        $self->ParsePtrPull($e, $l, $ndr, $var_name);
-               } elsif ($l->{TYPE} eq "SWITCH") {
-                       $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") {
@@ -1247,16 +1271,28 @@ sub ParseElementPullLevel
 
                if ($deferred and ContainsDeferred($e, $l)) {
                        $self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
+                       $self->defer("for ($counter = 0; $counter < ($length); $counter++) {");
+                       $self->defer_indent;
                        $self->indent;
                        $self->ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 0, 1);
                        $self->deindent;
+                       $self->defer_deindent;
                        $self->pidl("}");
+                       $self->defer("}");
                }
 
                $self->ParseMemCtxPullEnd($e, $l, $ndr);
 
        } elsif ($l->{TYPE} eq "SWITCH") {
-               $self->ParseElementPullLevel($e, GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
+               my $nl = GetNextLevel($e,$l);
+               my $needs_deferred_switch = is_deferred_switch_non_empty($nl);
+
+               # Avoid setting a switch value if it will not be
+               # consumed again in the NDR_BUFFERS pull
+               if ($needs_deferred_switch or !$deferred) {
+                       $self->ParseSwitchPull($e, $l, $ndr, $var_name, $env);
+               }
+               $self->ParseElementPullLevel($e, $nl, $ndr, $var_name, $env, $primitives, $deferred);
        }
 }
 
@@ -1431,7 +1467,9 @@ sub ParseStructPushPrimitives($$$$$)
 
        $self->ParseElementPush($_, $ndr, $env, 1, 0) foreach (@{$struct->{ELEMENTS}});
 
-       $self->pidl("NDR_CHECK(ndr_push_trailer_align($ndr, $struct->{ALIGN}));");
+       if (not defined($struct->{SURROUNDING_ELEMENT})) {
+               $self->pidl("NDR_CHECK(ndr_push_trailer_align($ndr, $struct->{ALIGN}));");
+       }
 }
 
 sub ParseStructPushDeferred($$$$)
@@ -1764,7 +1802,9 @@ sub ParseStructPullPrimitives($$$$$)
 
        $self->add_deferred();
 
-       $self->pidl("NDR_CHECK(ndr_pull_trailer_align($ndr, $struct->{ALIGN}));");
+       if (not defined($struct->{SURROUNDING_ELEMENT})) {
+               $self->pidl("NDR_CHECK(ndr_pull_trailer_align($ndr, $struct->{ALIGN}));");
+       }
 }
 
 sub ParseStructPullDeferred($$$$$)
@@ -1833,6 +1873,9 @@ sub ParseStructNdrSize($$$$)
 sub DeclStruct($$$$)
 {
        my ($e,$t,$name,$varname) = @_;
+       if ($t eq "base") {
+               return "struct $name $varname";
+       }
        return ($t ne "pull"?"const ":"") . "struct $name *$varname";
 }
 
@@ -1871,8 +1914,6 @@ sub ParseUnionPushPrimitives($$$$)
 
        my $have_default = 0;
 
-       $self->pidl("uint32_t level = ndr_push_get_switch_value($ndr, $varname);");
-
        if (defined($e->{SWITCH_TYPE})) {
                if (defined($e->{ALIGN})) {
                        $self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
@@ -1917,7 +1958,7 @@ sub ParseUnionPushPrimitives($$$$)
        }
        if (! $have_default) {
                $self->pidl("default:");
-               $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u at \%s\", level, __location__);");
+               $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);");
        }
        $self->deindent;
        $self->pidl("}");
@@ -1929,7 +1970,6 @@ sub ParseUnionPushDeferred($$$$)
 
        my $have_default = 0;
 
-       $self->pidl("uint32_t 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
@@ -1953,7 +1993,7 @@ sub ParseUnionPushDeferred($$$$)
        }
        if (! $have_default) {
                $self->pidl("default:");
-               $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u at \%s\", level, __location__);");
+               $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);");
        }
        $self->deindent;
        $self->pidl("}");
@@ -1966,17 +2006,28 @@ sub ParseUnionPush($$$$)
        my ($self,$e,$ndr,$varname) = @_;
        my $have_default = 0;
 
+       $self->pidl("uint32_t level;");
        $self->start_flags($e, $ndr);
 
        $self->pidl("NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);");
        $self->pidl("if (ndr_flags & NDR_SCALARS) {");
        $self->indent;
+       $self->pidl("/* This token is not used again (except perhaps below in the NDR_BUFFERS case) */");
+       $self->pidl("NDR_CHECK(ndr_push_steal_switch_value($ndr, $varname, &level));");
+
        $self->ParseUnionPushPrimitives($e, $ndr, $varname);
        $self->deindent;
        $self->pidl("}");
         if (is_deferred_switch_non_empty($e)) {
                 $self->pidl("if (ndr_flags & NDR_BUFFERS) {");
                 $self->indent;
+                # In case we had ndr_flags of NDR_SCALERS|NDR_BUFFERS
+                $self->pidl("if (!(ndr_flags & NDR_SCALARS)) {");
+                $self->indent;
+                $self->pidl("/* We didn't get it above, and the token is not needed after this. */");
+                $self->pidl("NDR_CHECK(ndr_push_steal_switch_value($ndr, $varname, &level));");
+                $self->deindent;
+                $self->pidl("}");
                 $self->ParseUnionPushDeferred($e, $ndr, $varname);
                 $self->deindent;
                 $self->pidl("}");
@@ -1998,7 +2049,7 @@ sub ParseUnionPrint($$$$$)
 
        $self->start_flags($e, $ndr);
 
-       $self->pidl("level = ndr_print_get_switch_value($ndr, $varname);");
+       $self->pidl("level = ndr_print_steal_switch_value($ndr, $varname);");
 
        $self->pidl("ndr_print_union($ndr, name, level, \"$name\");");
 
@@ -2088,11 +2139,6 @@ sub ParseUnionPullDeferred($$$$)
        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("switch (level) {");
        $self->indent;
        foreach my $el (@{$e->{ELEMENTS}}) {
@@ -2103,6 +2149,11 @@ sub ParseUnionPullDeferred($$$$)
                $self->pidl("$el->{CASE}:");
                if ($el->{TYPE} ne "EMPTY") {
                        $self->indent;
+                       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->ParseElementPull($el, $ndr, {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1);
                        $self->deindent;
                }
@@ -2149,20 +2200,21 @@ sub ParseUnionPull($$$$)
        $self->pidl("NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);");
        $self->pidl("if (ndr_flags & NDR_SCALARS) {");
        $self->indent;
-       if (! $needs_deferred_switch) {
-               $self->pidl("/* This token is not used again */");
-               $self->pidl("level = ndr_pull_steal_switch_value($ndr, $varname);");
-       } else {
-               $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);");
-       }
+       $self->pidl("/* This token is not used again (except perhaps below in the NDR_BUFFERS case) */");
+       $self->pidl("NDR_CHECK(ndr_pull_steal_switch_value($ndr, $varname, &level));");
        $self->ParseUnionPullPrimitives($e,$ndr,$varname,$switch_type);
        $self->deindent;
        $self->pidl("}");
        if ($needs_deferred_switch) {
                $self->pidl("if (ndr_flags & NDR_BUFFERS) {");
                $self->indent;
-               $self->pidl("/* The token is not needed after this. */");
-               $self->pidl("level = ndr_pull_steal_switch_value($ndr, $varname);");
+               # In case we had ndr_flags of NDR_SCALERS|NDR_BUFFERS
+               $self->pidl("if (!(ndr_flags & NDR_SCALARS)) {");
+               $self->indent;
+               $self->pidl("/* We didn't get it above, and the token is not needed after this. */");
+               $self->pidl("NDR_CHECK(ndr_pull_steal_switch_value($ndr, $varname, &level));");
+               $self->deindent;
+               $self->pidl("}");
                $self->ParseUnionPullDeferred($e,$ndr,$varname);
                $self->deindent;
                $self->pidl("}");
@@ -2175,6 +2227,9 @@ sub ParseUnionPull($$$$)
 sub DeclUnion($$$$)
 {
        my ($e,$t,$name,$varname) = @_;
+       if ($t eq "base") {
+               return "union $name $varname";
+       }
        return ($t ne "pull"?"const ":"") . "union $name *$varname";
 }
 
@@ -2551,7 +2606,7 @@ sub ParseFunctionPull($$)
        # out to be too tricky (tridge)
        foreach my $e (@{$fn->{ELEMENTS}}) {
                next unless grep(/out/, @{$e->{DIRECTION}});
-               $self->pidl("ZERO_STRUCT(r->out);");
+               $self->pidl("NDR_ZERO_STRUCT(r->out);");
                $self->pidl("");
                last;
        }
@@ -2600,7 +2655,7 @@ sub ParseFunctionPull($$)
                        if (grep(/in/, @{$e->{DIRECTION}})) {
                                $self->pidl("*r->out.$e->{NAME} = *r->in.$e->{NAME};");
                        } else {
-                               $self->pidl("ZERO_STRUCTP(r->out.$e->{NAME});");
+                               $self->pidl("NDR_ZERO_STRUCTP(r->out.$e->{NAME});");
                        }
                }
        }
@@ -2612,6 +2667,31 @@ sub ParseFunctionPull($$)
        $self->pidl("if (flags & NDR_OUT) {");
        $self->indent;
 
+       $self->pidl("#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION");
+
+       # This for fuzzers of ndr_pull where the out elements refer to
+       # in elements in size_is or length_is.
+       #
+       # Not actually very harmful but also not useful outsie a fuzzer
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               next unless (grep(/in/, @{$e->{DIRECTION}}));
+               next unless ($e->{LEVELS}[0]->{TYPE} eq "POINTER" and
+                            $e->{LEVELS}[0]->{POINTER_TYPE} eq "ref");
+               next if (($e->{LEVELS}[1]->{TYPE} eq "DATA") and
+                                ($e->{LEVELS}[1]->{DATA_TYPE} eq "string"));
+               next if ($e->{LEVELS}[1]->{TYPE} eq "PIPE");
+               next if ($e->{LEVELS}[1]->{TYPE} eq "ARRAY");
+
+               $self->pidl("if (r->in.$e->{NAME} == NULL) {");
+               $self->indent;
+               $self->pidl("NDR_PULL_ALLOC($ndr, r->in.$e->{NAME});");
+               $self->pidl("NDR_ZERO_STRUCTP(r->in.$e->{NAME});");
+               $self->deindent;
+               $self->pidl("}");
+       }
+
+       $self->pidl("#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */");
+
        $env = GenerateFunctionOutEnv($fn);
        foreach my $e (@{$fn->{ELEMENTS}}) {
                next unless grep(/out/, @{$e->{DIRECTION}});
@@ -2676,7 +2756,7 @@ sub ParseGeneratePipeArray($$$)
                $self->deindent;
                $self->pidl("},");
        }
-       $self->pidl("{ NULL, NULL, 0, NULL, NULL, NULL }");
+       $self->pidl("{ .name = NULL }");
        $self->deindent;
        $self->pidl("};");
        $self->pidl("");
@@ -2752,27 +2832,57 @@ sub FunctionCallEntry($$)
        return 1;
 }
 
+sub StructEntry($$)
+{
+       my ($self, $d) = @_;
+       my $type_decl = $typefamily{$d->{TYPE}}->{DECL}->($d, "base", $d->{NAME}, "");
+
+       $self->pidl("\t{");
+       $self->pidl("\t\t.name = \"$d->{NAME}\",");
+       $self->pidl("\t\t.struct_size = sizeof($type_decl),");
+       $self->pidl("\t\t.ndr_push = (ndr_push_flags_fn_t) ndr_push_$d->{NAME},");
+       $self->pidl("\t\t.ndr_pull = (ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},");
+       $self->pidl("\t\t.ndr_print = (ndr_print_function_t) ndr_print_flags_$d->{NAME},");
+       $self->pidl("\t},");
+       return 1;
+}
+
 #####################################################################
 # produce a function call table
 sub FunctionTable($$)
 {
        my($self,$interface) = @_;
        my $count = 0;
+       my $count_public_structs = 0;
        my $uname = uc $interface->{NAME};
 
-       return if ($#{$interface->{FUNCTIONS}}+1 == 0);
-       return unless defined ($interface->{PROPERTIES}->{uuid});
+       foreach my $d (@{$interface->{TYPES}}) {
+               next unless (is_public_struct($d));
+               $count_public_structs += 1;
+       }
+       return if ($#{$interface->{FUNCTIONS}}+1 == 0 and
+                  $count_public_structs == 0);
 
        foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
                $self->FunctionCallPipes($d);
        }
 
+       $self->pidl("static const struct ndr_interface_public_struct $interface->{NAME}\_public_structs[] = {");
+
+       foreach my $d (@{$interface->{TYPES}}) {
+               next unless (is_public_struct($d));
+               $self->StructEntry($d);
+       }
+       $self->pidl("\t{ .name = NULL }");
+       $self->pidl("};");
+       $self->pidl("");
+
        $self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {");
 
        foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
                $count += $self->FunctionCallEntry($d);
        }
-       $self->pidl("\t{ NULL, 0, NULL, NULL, NULL }");
+       $self->pidl("\t{ .name = NULL }");
        $self->pidl("};");
        $self->pidl("");
 
@@ -2795,18 +2905,22 @@ sub FunctionTable($$)
                $interface->{PROPERTIES}->{authservice} = "\"host\"";
        }
 
-       $self->AuthServiceStruct($interface->{NAME}, 
+       $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}\",");
-       $self->pidl("\t.syntax_id\t= {");
-       $self->pidl("\t\t" . print_uuid($interface->{UUID}) .",");
-       $self->pidl("\t\tNDR_$uname\_VERSION");
-       $self->pidl("\t},");
-       $self->pidl("\t.helpstring\t= NDR_$uname\_HELPSTRING,");
+       if (defined $interface->{PROPERTIES}->{uuid}) {
+               $self->pidl("\t.syntax_id\t= {");
+               $self->pidl("\t\t" . print_uuid($interface->{UUID}) .",");
+               $self->pidl("\t\tNDR_$uname\_VERSION");
+               $self->pidl("\t},");
+               $self->pidl("\t.helpstring\t= NDR_$uname\_HELPSTRING,");
+       }
        $self->pidl("\t.num_calls\t= $count,");
        $self->pidl("\t.calls\t\t= $interface->{NAME}\_calls,");
+       $self->pidl("\t.num_public_structs\t= $count_public_structs,");
+       $self->pidl("\t.public_structs\t\t= $interface->{NAME}\_public_structs,");
        $self->pidl("\t.endpoints\t= &$interface->{NAME}\_endpoints,");
        $self->pidl("\t.authservices\t= &$interface->{NAME}\_authservices");
        $self->pidl("};");
@@ -2871,7 +2985,15 @@ sub HeaderInterface($$$)
 
                if(!defined $interface->{PROPERTIES}->{helpstring}) { $interface->{PROPERTIES}->{helpstring} = "NULL"; }
                $self->pidl_hdr("#define NDR_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}");
+       }
 
+       my $count_public_structs = 0;
+       foreach my $d (@{$interface->{TYPES}}) {
+               next unless (has_property($d, "public"));
+               $count_public_structs += 1;
+       }
+       if ($#{$interface->{FUNCTIONS}}+1 > 0 or
+                  $count_public_structs > 0) {
                $self->pidl_hdr("extern const struct ndr_interface_table ndr_table_$interface->{NAME};");
        }
 
@@ -2975,6 +3097,18 @@ sub ParseTypePrintFunction($$$)
 
        $self->pidl_hdr("void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *ndr, const char *name, $args);");
 
+       if (is_public_struct($e)) {
+                $self->pidl("static void ".TypeFunctionName("ndr_print_flags", $e).
+                             "(struct ndr_print *$ndr, const char *name, int unused, $args)"
+                             );
+               $self->pidl("{");
+               $self->indent;
+               $self->pidl(TypeFunctionName("ndr_print", $e)."($ndr, name, $varname);");
+               $self->deindent;
+               $self->pidl("}");
+               $self->pidl("");
+       }
+
        return if (has_property($e, "noprint"));
 
        $self->pidl("_PUBLIC_ void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *$ndr, const char *name, $args)");
@@ -3054,7 +3188,16 @@ sub ParseInterface($$$)
                ($needed->{"ndr_print_$d->{NAME}"}) && $self->ParseFunctionPrint($d);
        }
 
+        # Allow compilation of generated files where replacement functions
+        # for structures declared nopull/nopush have not been provided.
+        #
+        # This makes sense when only the print functions are used
+        #
+        # Otherwise the ndr_table XXX will reference these
+
+        $self->pidl("#ifndef SKIP_NDR_TABLE_$interface->{NAME}");
        $self->FunctionTable($interface);
+        $self->pidl("#endif /* SKIP_NDR_TABLE_$interface->{NAME} */");
 
        $self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */");
 }
index ad36f000077c6486cc94e8ac66e9589f3ad5e937..73359987f93b11b80d7ddb265e566a1426dbcf39 100644 (file)
@@ -7,6 +7,7 @@
 package Parse::Pidl::Samba4::NDR::Server;
 
 use strict;
+use warnings;
 use Parse::Pidl::Util;
 
 use vars qw($VERSION);
@@ -81,10 +82,10 @@ sub Boilerplate_Iface($)
        my $if_version = $interface->{VERSION};
 
        pidl "
-static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version)
+static NTSTATUS $name\__op_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
 {
 #ifdef DCESRV_INTERFACE_$uname\_BIND
-       return DCESRV_INTERFACE_$uname\_BIND(dce_call,iface);
+       return DCESRV_INTERFACE_$uname\_BIND(context,iface);
 #else
        return NT_STATUS_OK;
 #endif
@@ -120,9 +121,6 @@ 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(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;
        }
@@ -145,9 +143,6 @@ pidl "
        }
 
        if (dce_call->fault_code != 0) {
-               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;
        }
 
@@ -169,9 +164,6 @@ pidl "
        }
 
        if (dce_call->fault_code != 0) {
-               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;
        }
 
@@ -201,6 +193,7 @@ static const struct dcesrv_interface dcesrv\_$name\_interface = {
        .dispatch           = $name\__op_dispatch,
        .reply              = $name\__op_reply,
        .ndr_push           = $name\__op_ndr_push,
+       .local              = NULL,
 #ifdef DCESRV_INTERFACE_$uname\_FLAGS
        .flags              = DCESRV_INTERFACE_$uname\_FLAGS
 #else
@@ -223,12 +216,22 @@ sub Boilerplate_Ep_Server($)
 static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
 {
        int i;
+#ifdef DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT
+       const char *ncacn_np_secondary_endpoint =
+               DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT;
+#else
+       const char *ncacn_np_secondary_endpoint = NULL;
+#endif
 
        for (i=0;i<ndr_table_$name.endpoints->count;i++) {
                NTSTATUS ret;
                const char *name = ndr_table_$name.endpoints->names[i];
 
-               ret = dcesrv_interface_register(dce_ctx, name, &dcesrv_$name\_interface, NULL);
+               ret = dcesrv_interface_register(dce_ctx,
+                                               name,
+                                               ncacn_np_secondary_endpoint,
+                                               &dcesrv_$name\_interface,
+                                               NULL);
                if (!NT_STATUS_IS_OK(ret)) {
                        DEBUG(1,(\"$name\_op_init_server: failed to register endpoint \'%s\'\\n\",name));
                        return ret;
@@ -238,6 +241,11 @@ static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const str
        return NT_STATUS_OK;
 }
 
+static NTSTATUS $name\__op_shutdown_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
+{
+       return NT_STATUS_OK;
+}
+
 static bool $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version)
 {
        if (dcesrv_$name\_interface.syntax_id.if_version == if_version &&
@@ -266,11 +274,19 @@ NTSTATUS dcerpc_server_$name\_init(TALLOC_CTX *ctx)
            /* fill in our name */
            .name = \"$name\",
 
+           /* Initialization flag */
+           .initialized = false,
+
            /* fill in all the operations */
 #ifdef DCESRV_INTERFACE_$uname\_INIT_SERVER
            .init_server = DCESRV_INTERFACE_$uname\_INIT_SERVER,
 #else
            .init_server = $name\__op_init_server,
+#endif
+#ifdef DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER
+           .shutdown_server = DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER,
+#else
+           .shutdown_server = $name\__op_shutdown_server,
 #endif
            .interface_by_uuid = $name\__op_interface_by_uuid,
            .interface_by_name = $name\__op_interface_by_name
index f418ac489aeace76bb60e2a875b5660f6955ba0a..5c4d3e8e0877a713dabc50296fb503f662b3318d 100644 (file)
@@ -4,11 +4,10 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba4::Python;
-
-use Exporter;
-@ISA = qw(Exporter);
+use parent Parse::Pidl::Base;
 
 use strict;
+use warnings;
 use Parse::Pidl qw(warning fatal error);
 use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias bitmap_type_fn enum_type_fn);
 use Parse::Pidl::Util qw(has_property ParseExpr unmake_str);
@@ -17,6 +16,7 @@ use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
 use Parse::Pidl::Samba4 qw(ArrayDynamicallyAllocated);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
 
+
 use vars qw($VERSION);
 $VERSION = '0.01';
 
@@ -34,41 +34,11 @@ sub new($) {
        bless($self, $class);
 }
 
-sub pidl_hdr ($$)
-{
-       my $self = shift;
-       $self->{res_hdr} .= shift;
-}
-
-sub pidl($$)
-{
-       my ($self, $d) = @_;
-       if ($d) {
-               if ((!($d =~ /^#/))) {
-                       $self->{res} .= $self->{tabs};
-               }
-               $self->{res} .= $d;
-       }
-       $self->{res} .= "\n";
-}
-
-sub indent($)
-{
-       my ($self) = @_;
-       $self->{tabs} .= "\t";
-}
-
-sub deindent($)
-{
-       my ($self) = @_;
-       $self->{tabs} = substr($self->{tabs}, 0, -1);
-}
-
 sub PrettifyTypeName($$)
 {
        my ($name, $basename) = @_;
 
-       $basename =~ s/^.*\.([^.]+)$/\1/;
+       $basename =~ s/^.*\.([^.]+)$/$1/;
 
        $name =~ s/^$basename\_//;
 
@@ -83,7 +53,7 @@ sub Import
        foreach (@imports) {
                $_ = unmake_str($_);
                s/\.idl$//;
-               $self->pidl_hdr("#include \"librpc/gen_ndr/$_\.h\"\n");
+               $self->pidl_hdr("#include \"librpc/gen_ndr/$_\.h\"");
                $self->register_module_import("samba.dcerpc.$_");
        }
 }
@@ -201,6 +171,14 @@ sub PythonElementGetSet($$$$$$) {
        $self->indent;
        $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(obj);");
        $self->pidl("PyObject *py_$e->{NAME};");
+       my $l = $e->{LEVELS}[0];
+       if ($l->{TYPE} eq "POINTER") {
+               $self->pidl("if ($varname == NULL) {");
+               $self->indent;
+               $self->pidl("Py_RETURN_NONE;");
+               $self->deindent;
+               $self->pidl("}");
+       }
        $self->ConvertObjectToPython("pytalloc_get_mem_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}", "return NULL;");
        $self->pidl("return py_$e->{NAME};");
        $self->deindent;
@@ -212,7 +190,6 @@ sub PythonElementGetSet($$$$$$) {
        $self->indent;
        $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
        my $mem_ctx = "pytalloc_get_mem_ctx(py_obj)";
-       my $l = $e->{LEVELS}[0];
        my $nl = GetNextLevel($e, $l);
        if ($l->{TYPE} eq "POINTER" and
                not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and
@@ -279,7 +256,7 @@ sub PythonStruct($$$$$$)
        # If the struct is not public there ndr_pull/ndr_push functions will
        # be static so not callable from here
        if (has_property($d, "public")) {
-               $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj)");
+               $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj,  PyObject *Py_UNUSED(ignored))");
                $self->pidl("{");
                $self->indent;
                $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
@@ -313,7 +290,7 @@ sub PythonStruct($$$$$$)
                $self->pidl("{");
                $self->indent;
                $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
-               $self->pidl("DATA_BLOB blob;");
+               $self->pidl("DATA_BLOB blob = {.data = NULL, .length = 0};");
                $self->pidl("Py_ssize_t blob_length = 0;");
                $self->pidl("enum ndr_err_code err;");
                $self->pidl("const char * const kwnames[] = { \"data_blob\", \"allow_remaining\", NULL };");
@@ -359,7 +336,7 @@ sub PythonStruct($$$$$$)
                $self->pidl("}");
                $self->pidl("");
 
-               $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj)");
+               $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
                $self->pidl("{");
                $self->indent;
                $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
@@ -367,7 +344,7 @@ sub PythonStruct($$$$$$)
                $self->pidl("char *retstr;");
                $self->pidl("");
                $self->pidl("retstr = ndr_print_struct_string(pytalloc_get_mem_ctx(py_obj), (ndr_print_fn_t)ndr_print_$name, \"$name\", object);");
-               $self->pidl("ret = PyStr_FromString(retstr);");
+               $self->pidl("ret = PyUnicode_FromString(retstr);");
                $self->pidl("talloc_free(retstr);");
                $self->pidl("");
                $self->pidl("return ret;");
@@ -379,7 +356,7 @@ sub PythonStruct($$$$$$)
                $self->pidl("static PyMethodDef $py_methods\[] = {");
                $self->indent;
                $self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.ndr_pack(object) -> blob\\nNDR pack\" },");
-               $self->pidl("{ \"__ndr_unpack__\", (PyCFunction)py_$name\_ndr_unpack, METH_VARARGS|METH_KEYWORDS, \"S.ndr_unpack(class, blob, allow_remaining=False) -> None\\nNDR unpack\" },");
+               $self->pidl("{ \"__ndr_unpack__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack), METH_VARARGS|METH_KEYWORDS, \"S.ndr_unpack(class, blob, allow_remaining=False) -> None\\nNDR unpack\" },");
                $self->pidl("{ \"__ndr_print__\", (PyCFunction)py_$name\_ndr_print, METH_NOARGS, \"S.ndr_print(object) -> None\\nNDR print\" },");
                $self->pidl("{ NULL, NULL, 0, NULL }");
                $self->deindent;
@@ -387,7 +364,7 @@ sub PythonStruct($$$$$$)
                $self->pidl("");
        }
 
-       $self->pidl_hdr("static PyTypeObject $name\_Type;\n");
+       $self->pidl_hdr("static PyTypeObject $name\_Type;");
        $self->pidl("");
        my $docstring = $self->DocString($d, $name);
        my $typeobject = "$name\_Type";
@@ -491,7 +468,62 @@ sub PythonFunctionStruct($$$$)
        $self->pidl("static PyObject *py_$name\_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
        $self->pidl("{");
        $self->indent;
-       $self->pidl("return pytalloc_new($cname, type);");
+
+       # This creates a new, zeroed C structure and python object.
+       # Thse may not be valid or sensible values, but this is as
+       # well as we can do.
+
+       $self->pidl("PyObject *self = pytalloc_new($cname, type);");
+
+       # If there are any children that are ref pointers, we need to
+       # allocate something for them to point to just as the pull
+       # routine will when parsing the stucture from NDR.
+       #
+       # We then make those pointers point to zeroed memory
+       #
+       # A ref pointer is a pointer in the C structure but a scalar
+       # on the wire. It is for a remote function like:
+       #
+       # int foo(int *i)
+       #
+       # This may be called with the pointer by reference eg foo(&i)
+       #
+       # That is why this only goes as far as the next level; deeply
+       # nested pointer chains will end in a NULL.
+
+       my @ref_elements;
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               if (has_property($e, "ref") && ! has_property($e, "charset")) {
+                       if (!has_property($e, 'in') && !has_property($e, 'out')) {
+                               die "ref pointer that is not in or out";
+                       }
+                       push @ref_elements, $e;
+               }
+       }
+       if (@ref_elements) {
+               $self->pidl("$cname *_self = ($cname *)pytalloc_get_ptr(self);");
+               $self->pidl("TALLOC_CTX *mem_ctx = pytalloc_get_mem_ctx(self);");
+               foreach my $e (@ref_elements) {
+                       my $ename = $e->{NAME};
+                       my $t = mapTypeName($e->{TYPE});
+                       my $p = $e->{ORIGINAL}->{POINTERS} // 1;
+                       if ($p > 1) {
+                               $self->pidl("/* a pointer to a NULL pointer */");
+                               $t .= ' ' . '*' x ($p - 1);
+                       }
+
+                       # We checked in the loop above that each ref
+                       # pointer is in or out (or both)
+                       if (has_property($e, 'in')) {
+                               $self->pidl("_self->in.$ename = talloc_zero(mem_ctx, $t);");
+                       }
+
+                       if (has_property($e, 'out')) {
+                               $self->pidl("_self->out.$ename = talloc_zero(mem_ctx, $t);");
+                       }
+               }
+       }
+       $self->pidl("return self;");
        $self->deindent;
        $self->pidl("}");
        $self->pidl("");
@@ -501,12 +533,12 @@ sub PythonFunctionStruct($$$$)
        my $ndr_call = "const struct ndr_interface_call *call = NULL;";
        my $object_ptr = "$cname *object = ($cname *)pytalloc_get_ptr(py_obj);";
 
-       $self->pidl("static PyObject *py_$name\_ndr_opnum(PyTypeObject *type)");
+       $self->pidl("static PyObject *py_$name\_ndr_opnum(PyTypeObject *type, PyObject *Py_UNUSED(ignored))");
        $self->pidl("{");
        $self->indent;
        $self->pidl("");
        $self->pidl("");
-       $self->pidl("return PyInt_FromLong($fn->{OPNUM});");
+       $self->pidl("return PyLong_FromLong($fn->{OPNUM});");
        $self->deindent;
        $self->pidl("}");
        $self->pidl("");
@@ -809,7 +841,7 @@ sub PythonFunctionStruct($$$$)
        $self->pidl("call = &ndr_table_$iface\.calls[$fn->{OPNUM}];");
        $self->pidl("");
        $self->pidl("retstr = ndr_print_function_string(pytalloc_get_mem_ctx(py_obj), call->ndr_print, name, ndr_inout_flags, object);");
-       $self->pidl("ret = PyStr_FromString(retstr);");
+       $self->pidl("ret = PyUnicode_FromString(retstr);");
        $self->pidl("TALLOC_FREE(retstr);");
        $self->pidl("");
        $self->pidl("return ret;");
@@ -817,7 +849,7 @@ sub PythonFunctionStruct($$$$)
        $self->pidl("}");
        $self->pidl("");
 
-       $self->pidl("static PyObject *py_$name\_ndr_print_in(PyObject *py_obj)");
+       $self->pidl("static PyObject *py_$name\_ndr_print_in(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
        $self->pidl("{");
        $self->indent;
        $self->pidl("return py_$name\_ndr_print(py_obj, \"$name\_in\", NDR_IN);");
@@ -825,7 +857,7 @@ sub PythonFunctionStruct($$$$)
        $self->pidl("}");
        $self->pidl("");
 
-       $self->pidl("static PyObject *py_$name\_ndr_print_out(PyObject *py_obj)");
+       $self->pidl("static PyObject *py_$name\_ndr_print_out(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
        $self->pidl("{");
        $self->indent;
        $self->pidl("return py_$name\_ndr_print(py_obj, \"$name\_out\", NDR_OUT);");
@@ -840,19 +872,19 @@ sub PythonFunctionStruct($$$$)
        $self->indent;
        $self->pidl("\"$modulename.$prettyname.opnum() -> ".sprintf("%d (0x%02x)", $fn->{OPNUM}, $fn->{OPNUM})." \" },");
        $self->deindent;
-       $self->pidl("{ \"__ndr_pack_in__\", (PyCFunction)py_$name\_ndr_pack_in, METH_VARARGS|METH_KEYWORDS,");
+       $self->pidl("{ \"__ndr_pack_in__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_pack_in), METH_VARARGS|METH_KEYWORDS,");
        $self->indent;
        $self->pidl("\"S.ndr_pack_in(object, bigendian=False, ndr64=False) -> blob\\nNDR pack input\" },");
        $self->deindent;
-       $self->pidl("{ \"__ndr_pack_out__\", (PyCFunction)py_$name\_ndr_pack_out, METH_VARARGS|METH_KEYWORDS,");
+       $self->pidl("{ \"__ndr_pack_out__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_pack_out), METH_VARARGS|METH_KEYWORDS,");
        $self->indent;
        $self->pidl("\"S.ndr_pack_out(object, bigendian=False, ndr64=False) -> blob\\nNDR pack output\" },");
        $self->deindent;
-       $self->pidl("{ \"__ndr_unpack_in__\", (PyCFunction)py_$name\_ndr_unpack_in, METH_VARARGS|METH_KEYWORDS,");
+       $self->pidl("{ \"__ndr_unpack_in__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack_in), METH_VARARGS|METH_KEYWORDS,");
        $self->indent;
        $self->pidl("\"S.ndr_unpack_in(class, blob, bigendian=False, ndr64=False, allow_remaining=False) -> None\\nNDR unpack input\" },");
        $self->deindent;
-       $self->pidl("{ \"__ndr_unpack_out__\", (PyCFunction)py_$name\_ndr_unpack_out, METH_VARARGS|METH_KEYWORDS,");
+       $self->pidl("{ \"__ndr_unpack_out__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack_out), METH_VARARGS|METH_KEYWORDS,");
        $self->indent;
        $self->pidl("\"S.ndr_unpack_out(class, blob, bigendian=False, ndr64=False, allow_remaining=False) -> None\\nNDR unpack output\" },");
        $self->deindent;
@@ -863,7 +895,7 @@ sub PythonFunctionStruct($$$$)
        $self->pidl("};");
        $self->pidl("");
 
-       $self->pidl_hdr("static PyTypeObject $name\_Type;\n");
+       $self->pidl_hdr("static PyTypeObject $name\_Type;");
        $self->pidl("");
        my $docstring = $self->DocString($fn, $name);
        my $typeobject = "$name\_Type";
@@ -1235,7 +1267,7 @@ sub PythonType($$$$)
                $self->pidl("PyObject *in = NULL;");
                $self->pidl("$typename *out = NULL;");
                $self->pidl("");
-               $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"OiO:import\",");
+               $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"OiO:export\",");
                $self->indent;
                $self->pidl("discard_const_p(char *, kwnames),");
                $self->pidl("&mem_ctx_obj,");
@@ -1269,12 +1301,12 @@ sub PythonType($$$$)
                $py_methods = "py_$d->{NAME}_methods";
                $self->pidl("static PyMethodDef $py_methods\[] = {");
                $self->indent;
-               $self->pidl("{ \"__import__\", (PyCFunction)py_$d->{NAME}\_import,");
+               $self->pidl("{ \"__import__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$d->{NAME}\_import),");
                $self->indent;
                $self->pidl("METH_VARARGS|METH_KEYWORDS|METH_CLASS,");
                $self->pidl("\"T.__import__(mem_ctx, level, in) => ret.\" },");
                $self->deindent;
-               $self->pidl("{ \"__export__\", (PyCFunction)py_$d->{NAME}\_export,");
+               $self->pidl("{ \"__export__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$d->{NAME}\_export),");
                $self->indent;
                $self->pidl("METH_VARARGS|METH_KEYWORDS|METH_CLASS,");
                $self->pidl("\"T.__export__(mem_ctx, level, in) => ret.\" },");
@@ -1294,7 +1326,7 @@ sub PythonType($$$$)
                $self->pidl("");
 
                $self->pidl("");
-               $self->pidl_hdr("static PyTypeObject $typeobject;\n");
+               $self->pidl_hdr("static PyTypeObject $typeobject;");
                $self->pidl("static PyTypeObject $typeobject = {");
                $self->indent;
                $self->pidl("PyVarObject_HEAD_INIT(NULL, 0)");
@@ -1349,7 +1381,7 @@ sub Interface($$$)
        }
 
        if (defined $interface->{PROPERTIES}->{uuid}) {
-               $self->pidl_hdr("static PyTypeObject $interface->{NAME}_InterfaceType;\n");
+               $self->pidl_hdr("static PyTypeObject $interface->{NAME}_InterfaceType;");
                $self->pidl("");
 
                my @fns = ();
@@ -1387,7 +1419,7 @@ sub Interface($$$)
                        my ($infn, $outfn, $callfn, $prettyname, $docstring, $opnum) = @$d;
                        $self->pidl("{ \"$prettyname\", $docstring, (py_dcerpc_call_fn)$callfn, (py_data_pack_fn)$infn, (py_data_unpack_fn)$outfn, $opnum, &ndr_table_$interface->{NAME} },");
                }
-               $self->pidl("{ NULL }");
+               $self->pidl("{0}");
                $self->deindent;
                $self->pidl("};");
                $self->pidl("");
@@ -1446,9 +1478,9 @@ sub Interface($$$)
 
                $self->pidl("");
 
-               my $signature = "\"$interface->{NAME}_abstract_syntax()\\n\"";
+               $signature = "\"$interface->{NAME}_abstract_syntax()\\n\"";
 
-               my $docstring = $self->DocString($interface, $interface->{NAME}."_syntax");
+               $docstring = $self->DocString($interface, $interface->{NAME}."_syntax");
 
                if ($docstring) {
                        $docstring = "$signature$docstring";
@@ -1482,7 +1514,7 @@ sub Interface($$$)
                                                     ""]);
        }
 
-       $self->pidl_hdr("\n");
+       $self->pidl_hdr("");
 }
 
 sub register_module_method($$$$$)
@@ -1715,21 +1747,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
                $self->pidl("}");
                $self->pidl("if (test_var > uint_max) {");
                $self->indent;
-               $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %llu\",\\");
-               $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);");
-               $self->pidl($fail);
-               $self->deindent;
-               $self->pidl("}");
-               $self->pidl("$target = test_var;");
-               $self->deindent;
-               $self->pidl("} else if (PyInt_Check($cvar)) {");
-               $self->indent;
-               $self->pidl("long test_var;");
-               $self->pidl("test_var = PyInt_AsLong($cvar);");
-               $self->pidl("if (test_var < 0 || test_var > uint_max) {");
-               $self->indent;
-               $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %ld\",\\");
-               $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);");
+               $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s within range 0 - %llu, got %llu\",\\");
+               $self->pidl("  PyLong_Type.tp_name, uint_max, test_var);");
                $self->pidl($fail);
                $self->deindent;
                $self->pidl("}");
@@ -1737,8 +1756,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
                $self->deindent;
                $self->pidl("} else {");
                $self->indent;
-               $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
-               $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name);");
+               $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s\",\\");
+               $self->pidl("  PyLong_Type.tp_name);");
                $self->pidl($fail);
                $self->deindent;
                $self->pidl("}");
@@ -1767,21 +1786,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
                $self->pidl("}");
                $self->pidl("if (test_var < int_min || test_var > int_max) {");
                $self->indent;
-               $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %lld\",\\");
-               $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
-               $self->pidl($fail);
-               $self->deindent;
-               $self->pidl("}");
-               $self->pidl("$target = test_var;");
-               $self->deindent;
-               $self->pidl("} else if (PyInt_Check($cvar)) {");
-               $self->indent;
-               $self->pidl("long test_var;");
-               $self->pidl("test_var = PyInt_AsLong($cvar);");
-               $self->pidl("if (test_var < int_min || test_var > int_max) {");
-               $self->indent;
-               $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %ld\",\\");
-               $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
+               $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s within range %lld - %lld, got %lld\",\\");
+               $self->pidl("  PyLong_Type.tp_name, int_min, int_max, test_var);");
                $self->pidl($fail);
                $self->deindent;
                $self->pidl("}");
@@ -1789,8 +1795,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
                $self->deindent;
                $self->pidl("} else {");
                $self->indent;
-               $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
-               $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name);");
+               $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s\",\\");
+               $self->pidl("  PyLong_Type.tp_name);");
                $self->pidl($fail);
                $self->deindent;
                $self->pidl("}");
@@ -1850,17 +1856,17 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
        }
 
        if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
-               $self->pidl("$target = NT_STATUS(PyInt_AsLong($cvar));");
+               $self->pidl("$target = NT_STATUS(PyLong_AsLong($cvar));");
                return;
        }
 
        if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") {
-               $self->pidl("$target = W_ERROR(PyInt_AsLong($cvar));");
+               $self->pidl("$target = W_ERROR(PyLong_AsLong($cvar));");
                return;
        }
 
        if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "HRESULT") {
-               $self->pidl("$target = HRES_ERROR(PyInt_AsLong($cvar));");
+               $self->pidl("$target = HRES_ERROR(PyLong_AsLong($cvar));");
                return;
        }
 
@@ -1902,6 +1908,9 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
        $recurse = $recurse + 1;
 
        if ($l->{TYPE} eq "POINTER") {
+               my $need_deindent = 0;
+               my $need_deref = 0;
+
                if ($l->{POINTER_TYPE} ne "ref") {
                        $self->pidl("if ($py_var == Py_None) {");
                        $self->indent;
@@ -1909,10 +1918,13 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
                        $self->deindent;
                        $self->pidl("} else {");
                        $self->indent;
+                       $need_deindent = 1;
+                       if ($nl->{TYPE} eq "POINTER") {
+                               $need_deref = 1;
+                       }
                }
-               # if we want to handle more than one level of pointer in python interfaces
-               # then this is where we would need to allocate it
-               if ($l->{POINTER_TYPE} eq "ref") {
+
+               if ($l->{POINTER_TYPE} eq "ref" or $need_deref == 1) {
                        $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
                        $self->pidl("if ($var_name == NULL) {");
                        $self->indent;
@@ -1932,11 +1944,20 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
                } else {
                        $self->pidl("$var_name = NULL;");
                }
+               if ($need_deref == 1) {
+                       my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer");
+                       $self->pidl("$py_var = py_dcerpc_ndr_pointer_deref($ndr_pointer_typename, $py_var);");
+                       $self->pidl("if ($py_var == NULL) {");
+                       $self->indent;
+                        $self->pidl($fail);
+                       $self->deindent;
+                       $self->pidl("}");
+               }
                unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
                        $var_name = get_value_of($var_name);
                }
                $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail, $recurse);
-               if ($l->{POINTER_TYPE} ne "ref") {
+               if ($need_deindent == 1) {
                        $self->deindent;
                        $self->pidl("}");
                }
@@ -1967,7 +1988,11 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
                        }
                        $self->pidl("for ($counter = 0; $counter < PyList_GET_SIZE($py_var); $counter++) {");
                        $self->indent;
-                       $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, $var_name."[$counter]", $fail, 0);
+                       if (ArrayDynamicallyAllocated($e, $l)) {
+                               $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, $var_name."[$counter]", $fail, 0);
+                       } else {
+                               $self->ConvertObjectFromPythonLevel($env, $mem_ctx, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, $var_name."[$counter]", $fail, 0);
+                       }
                        $self->deindent;
                        $self->pidl("}");
                        $self->deindent;
@@ -2015,15 +2040,15 @@ sub ConvertScalarToPython($$$$)
        $ctypename = expandAlias($ctypename);
 
        if ($ctypename =~ /^(int64|dlong)$/) {
-               return "ndr_PyLong_FromLongLong($cvar)";
+               return "PyLong_FromLongLong($cvar)";
        }
 
        if ($ctypename =~ /^(uint64|hyper|NTTIME_hyper|NTTIME|NTTIME_1sec|udlong|udlongr|uid_t|gid_t)$/) {
-               return "ndr_PyLong_FromUnsignedLongLong($cvar)";
+               return "PyLong_FromUnsignedLongLong($cvar)";
        }
 
        if ($ctypename =~ /^(char|int|int8|int16|int32|time_t)$/) {
-               return "PyInt_FromLong($cvar)";
+               return "PyLong_FromLong($cvar)";
        }
 
        # Needed to ensure unsigned values in a 32 or 16 bit enum is
@@ -2031,11 +2056,11 @@ sub ConvertScalarToPython($$$$)
        # possibly 64 bit unsigned long.  (enums are signed in C,
        # unsigned in NDR)
        if ($ctypename =~ /^(uint32|uint3264)$/) {
-               return "ndr_PyLong_FromUnsignedLongLong((uint32_t)$cvar)";
+               return "PyLong_FromUnsignedLongLong((uint32_t)$cvar)";
        }
 
        if ($ctypename =~ /^(uint|uint8|uint16|uint1632)$/) {
-               return "PyInt_FromLong((uint16_t)$cvar)";
+               return "PyLong_FromLong((uint16_t)$cvar)";
        }
 
        if ($ctypename eq "DATA_BLOB") {
@@ -2138,6 +2163,10 @@ sub ConvertObjectToPythonLevel($$$$$$$)
        }
 
        if ($l->{TYPE} eq "POINTER") {
+               my $need_wrap = 0;
+               if ($l->{POINTER_TYPE} ne "ref" and $nl->{TYPE} eq "POINTER") {
+                       $need_wrap = 1;
+               }
                if ($l->{POINTER_TYPE} ne "ref") {
                        if ($recurse == 0) {
                                $self->pidl("if ($var_name == NULL) {");
@@ -2164,6 +2193,19 @@ sub ConvertObjectToPythonLevel($$$$$$$)
                        $self->deindent;
                        $self->pidl("}");
                }
+               if ($need_wrap) {
+                       my $py_var_wrap = undef;
+                       $need_wrap = 1;
+                       $self->pidl("{");
+                       $self->indent;
+                       $py_var_wrap = "py_$e->{NAME}_level_$l->{LEVEL_INDEX}";
+                       $self->pidl("PyObject *$py_var_wrap = $py_var;");
+                       my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer");
+                       $self->pidl("$py_var = py_dcerpc_ndr_pointer_wrap($ndr_pointer_typename, $py_var_wrap);");
+                       $self->pidl("Py_XDECREF($py_var_wrap);");
+                       $self->deindent;
+                       $self->pidl("}");
+               }
        } elsif ($l->{TYPE} eq "ARRAY") {
                if ($pl && $pl->{TYPE} eq "POINTER") {
                        $var_name = get_pointer_to($var_name);
@@ -2199,7 +2241,11 @@ sub ConvertObjectToPythonLevel($$$$$$$)
                        $self->indent;
                        my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}";
                        $self->pidl("PyObject *$member_var;");
-                       $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name."[$counter]", $member_var, $fail, $recurse);
+                       if (ArrayDynamicallyAllocated($e, $l)) {
+                               $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name."[$counter]", $member_var, $fail, $recurse);
+                       } else {
+                               $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, $nl, $var_name."[$counter]", $member_var, $fail, $recurse);
+                       }
                        $self->pidl("PyList_SetItem($py_var, $counter, $member_var);");
                        $self->deindent;
                        $self->pidl("}");
@@ -2240,18 +2286,36 @@ sub Parse($$$$$)
 
        $self->{BASENAME} = $basename;
 
+        my $ndr_hdr_include = "";
+       if (defined($ndr_hdr)) {
+               $ndr_hdr_include = "#include \"$ndr_hdr\"";
+       }
     $self->pidl_hdr("
 /* Python wrapper functions auto-generated by pidl */
 #define PY_SSIZE_T_CLEAN 1 /* We use Py_ssize_t for PyArg_ParseTupleAndKeywords */
 #include <Python.h>
 #include \"python/py3compat.h\"
 #include \"includes.h\"
+#include \"python/modules.h\"
 #include <pytalloc.h>
 #include \"librpc/rpc/pyrpc.h\"
 #include \"librpc/rpc/pyrpc_util.h\"
 #include \"$hdr\"
-#include \"$ndr_hdr\"
+$ndr_hdr_include
 
+/*
+ * Suppress compiler warnings if the generated code does not call these
+ * functions
+ */
+#ifndef _MAYBE_UNUSED_
+#ifdef __has_attribute
+#if __has_attribute(unused)
+#define _MAYBE_UNUSED_ __attribute__ ((unused))
+#else
+#define _MAYBE_UNUSED_
+#endif
+#endif
+#endif
 /*
  * These functions are here to ensure they can be optimized out by
  * the compiler based on the constant input values
@@ -2273,7 +2337,7 @@ static inline unsigned long long ndr_sizeof2uintmax(size_t var_size)
        return 0;
 }
 
-static inline long long ndr_sizeof2intmax(size_t var_size)
+static inline _MAYBE_UNUSED_ long long ndr_sizeof2intmax(size_t var_size)
 {
        switch (var_size) {
        case 8:
@@ -2288,25 +2352,6 @@ static inline long long ndr_sizeof2intmax(size_t var_size)
 
        return 0;
 }
-
-static inline PyObject *ndr_PyLong_FromLongLong(long long v)
-{
-       if (v > LONG_MAX || v < LONG_MIN) {
-               return PyLong_FromLongLong(v);
-       } else {
-               return PyInt_FromLong(v);
-       }
-}
-
-static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
-{
-       if (v > LONG_MAX) {
-               return PyLong_FromUnsignedLongLong(v);
-       } else {
-               return PyInt_FromLong(v);
-       }
-}
-
 ");
 
        foreach my $x (@$ndr) {
@@ -2340,9 +2385,9 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
        $self->pidl("MODULE_INIT_FUNC($basename)");
        $self->pidl("{");
        $self->indent;
-       $self->pidl("PyObject *m;");
+       $self->pidl("PyObject *m = NULL;");
        foreach my $h (@{$self->{module_imports}}) {
-               $self->pidl("PyObject *$h->{'key'};");
+               $self->pidl("PyObject *$h->{'key'} = NULL;");
        }
        $self->pidl("");
 
@@ -2351,20 +2396,20 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
                my $module_path = $h->{'val'};
                $self->pidl("$var_name = PyImport_ImportModule(\"$module_path\");");
                $self->pidl("if ($var_name == NULL)");
-               $self->pidl("\treturn NULL;");
+               $self->pidl("\tgoto out;");
                $self->pidl("");
        }
 
        foreach my $h (@{$self->{type_imports}}) {
                my $type_var = "$h->{'key'}\_Type";
                my $module_path = $h->{'val'};
-               $self->pidl_hdr("static PyTypeObject *$type_var;\n");
+               $self->pidl_hdr("static PyTypeObject *$type_var;");
                my $pretty_name = PrettifyTypeName($h->{'key'}, $module_path);
                my $module_var = "dep_$module_path";
                $module_var =~ s/\./_/g;
                $self->pidl("$type_var = (PyTypeObject *)PyObject_GetAttrString($module_var, \"$pretty_name\");");
                $self->pidl("if ($type_var == NULL)");
-               $self->pidl("\treturn NULL;");
+               $self->pidl("\tgoto out;");
                $self->pidl("");
        }
 
@@ -2372,7 +2417,7 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
 
        foreach (@{$self->{ready_types}}) {
                $self->pidl("if (PyType_Ready($_) < 0)");
-               $self->pidl("\treturn NULL;");
+               $self->pidl("\tgoto out;");
        }
 
        $self->pidl($_) foreach (@{$self->{postreadycode}});
@@ -2388,16 +2433,16 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
 
        $self->pidl("m = PyModule_Create(&moduledef);");
        $self->pidl("if (m == NULL)");
-       $self->pidl("\treturn NULL;");
+       $self->pidl("\tgoto out;");
        $self->pidl("");
        foreach my $h (@{$self->{constants}}) {
                my $pretty_name = PrettifyTypeName($h->{'key'}, $basename);
                my $py_obj;
                my ($ctype, $cvar) = @{$h->{'val'}};
                if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) {
-                       $py_obj = "ndr_PyLong_FromUnsignedLongLong($cvar)";
+                       $py_obj = "PyLong_FromUnsignedLongLong($cvar)";
                } elsif ($cvar =~ /^".*"$/) {
-                       $py_obj = "PyStr_FromString($cvar)";
+                       $py_obj = "PyUnicode_FromString($cvar)";
                } else {
                        $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar, undef);
                }
@@ -2414,7 +2459,11 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
        $self->pidl("#ifdef PY_MOD_".uc($basename)."_PATCH");
        $self->pidl("PY_MOD_".uc($basename)."_PATCH(m);");
        $self->pidl("#endif");
-
+       $self->pidl("out:");
+       foreach my $h (@{$self->{module_imports}}) {
+               my $mod_var = $h->{'key'};
+               $self->pidl("Py_XDECREF($mod_var);");
+       }
        $self->pidl("return m;");
        $self->pidl("");
        $self->deindent;
index c0749304ef32a11b96ff357c2b0fd1f00141e245..c3282879988009a5099c7af7c22d265c74f1548d 100644 (file)
@@ -9,25 +9,20 @@ use Parse::Pidl::Util qw(has_property ParseExpr is_constant);
 use Parse::Pidl::Samba4 qw(is_intree choose_header);
 use Parse::Pidl::Typelist qw(mapTypeName);
 
-use Exporter;
-@ISA = qw(Exporter);
-@EXPORT_OK = qw(ParserType $ret $ret_hdr);
+use base Parse::Pidl::Base;
 
 use vars qw($VERSION);
 $VERSION = '0.01';
 
 use strict;
+use warnings;
 
 sub new($) {
        my ($class) = shift;
-       my $self = { ret => "", ret_hdr => "", tabs => "" };
+       my $self = { res => "", res_hdr => "", tabs => "" };
        bless($self, $class);
 }
 
-sub indent($) { my $self = shift; $self->{tabs}.="\t"; }
-sub deindent($) { my $self = shift; $self->{tabs} = substr($self->{tabs}, 1); }
-sub pidl($$) { my $self = shift; $self->{ret} .= $self->{tabs}.(shift)."\n"; }
-sub pidl_hdr($$) { my $self = shift; $self->{ret_hdr} .= (shift)."\n"; }
 sub typearg($) { 
        my $t = shift; 
        return(", const char *name") if ($t eq "print");
@@ -277,7 +272,7 @@ sub Parser($$$$)
        $self->pidl_hdr("");
 
        foreach (@$idl) { $self->ParserInterface($_) if ($_->{TYPE} eq "INTERFACE"); }  
-       return ($self->{ret_hdr}, $self->{ret});
+       return ($self->{res_hdr}, $self->{res});
 }
 
 1;
index 175bb1247f7813ba8d07ca8be9fc6c45485ece3b..6a6755b8f57a1c7868d17529df4f2245bcdeb5ac 100644 (file)
@@ -11,6 +11,7 @@ $VERSION = '0.01';
 use Parse::Pidl::Util qw(genpad);
 
 use strict;
+use warnings;
 
 my($res);
 
@@ -30,7 +31,18 @@ sub Template($)
 
    Copyright (C) YOUR NAME HERE YEAR
 
-   SPDX-License-Identifier: GPL-3.0-or-later
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include \"includes.h\"
index 774554f093bdc84722b8ad8c8e374f98ac148d18..2b850ffee4bb2fa0e2510ad8a79836dc6fa76239 100644 (file)
@@ -16,6 +16,7 @@ $VERSION = '0.01';
 
 use Parse::Pidl::Util qw(has_property);
 use strict;
+use warnings;
 
 my %types = ();
 
index 83e23937a87723f89b44d4b85141fbb5acaa9dc9..7a6039ba12b37b63a93c2052776efed51a452379 100644 (file)
@@ -6,11 +6,12 @@ package Parse::Pidl::Util;
 
 require Exporter;
 @ISA = qw(Exporter);
-@EXPORT = qw(has_property property_matches ParseExpr ParseExprExt is_constant make_str unmake_str print_uuid MyDumper genpad);
+@EXPORT = qw(has_property property_matches ParseExpr ParseExprExt is_constant make_str unmake_str print_uuid MyDumper genpad parse_int parse_range);
 use vars qw($VERSION);
 $VERSION = '0.01';
 
 use strict;
+use warnings;
 
 use Parse::Pidl::Expr;
 use Parse::Pidl qw(error);
@@ -190,6 +191,41 @@ sub genpad($)
        return "\t"x($nt)." "x($ns);
 }
 
+=item B<parse_int>
+
+Try to convert hex and octal strings to numbers. If a string doesn't
+look hexish or octish it will be left as is. If the unconverted string
+is actually a decimal number, Perl is likely to handle it correctly.
+
+=cut
+
+sub parse_int {
+       my $s = shift;
+       if ($s =~ /^0[xX][0-9A-Fa-f]+$/) {
+               return hex $s;
+       }
+       if ($s =~ /^0[0-7]+$/) {
+               return oct $s;
+       }
+       return $s;
+}
+
+=item B<parse_range>
+
+Read a range specification that might contain hex or octal numbers,
+and work out what those numbers are.
+
+=cut
+
+sub parse_range {
+       my $range = shift;
+       my ($low, $high) = split(/,/, $range, 2);
+       $low = parse_int($low);
+       $high = parse_int($high);
+       return ($low, $high);
+}
+
+
 =back
 
 =cut
index 01a8c473c56e2a0ec595c66fcb702bcea872c6bb..7f7ef184c183fad637a7d722595d1a6965119b6c 100644 (file)
@@ -115,6 +115,7 @@ $VERSION = '0.01';
 @EXPORT_OK = qw(ReadConformance ReadConformanceFH valid_ft_type valid_base_type);
 
 use strict;
+use warnings;
 
 use Parse::Pidl qw(fatal warning error);
 use Parse::Pidl::Util qw(has_property);
index 8ac37f51519e2f663feae0b7ac4a530a38bcdf78..175b86c91b78d0fb3ee017747ad0c747273221b3 100644 (file)
@@ -21,6 +21,7 @@ use Exporter;
 @EXPORT_OK = qw(field2name %res PrintIdl StripPrefixes RegisterInterfaceHandoff register_hf_field CheckUsed ProcessImport ProcessInclude find_type DumpEttList DumpEttDeclaration DumpHfList DumpHfDeclaration DumpFunctionTable register_type register_ett);
 
 use strict;
+use warnings;
 use Parse::Pidl qw(error warning);
 use Parse::Pidl::Typelist qw(getType);
 use Parse::Pidl::Util qw(has_property property_matches make_str);
diff --git a/tools/pidl/lib/wscript_build b/tools/pidl/lib/wscript_build
deleted file mode 100644 (file)
index 54b3170..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-
-# install the pidl modules
-bld.INSTALL_FILES(bld.env.PERL_LIB_INSTALL_DIR,
-                  '''
-                  Parse/Pidl.pm
-                  Parse/Pidl/Samba4.pm
-                  Parse/Pidl/CUtil.pm
-                  Parse/Pidl/Expr.pm
-                  Parse/Pidl/Wireshark/Conformance.pm
-                  Parse/Pidl/Wireshark/NDR.pm
-                  Parse/Pidl/ODL.pm
-                  Parse/Pidl/Dump.pm
-                  Parse/Pidl/Util.pm
-                  Parse/Pidl/Samba4/Header.pm
-                  Parse/Pidl/Samba4/COM/Header.pm
-                  Parse/Pidl/Samba4/COM/Proxy.pm
-                  Parse/Pidl/Samba4/COM/Stub.pm
-                  Parse/Pidl/Samba4/TDR.pm
-                  Parse/Pidl/Samba4/NDR/Server.pm
-                  Parse/Pidl/Samba4/NDR/Client.pm
-                  Parse/Pidl/Samba4/NDR/Parser.pm
-                  Parse/Pidl/Samba4/Python.pm
-                  Parse/Pidl/Samba4/Template.pm
-                  Parse/Pidl/IDL.pm
-                  Parse/Pidl/Typelist.pm
-                  Parse/Pidl/Samba3/ClientNDR.pm
-                  Parse/Pidl/Samba3/ServerNDR.pm
-                  Parse/Pidl/Compat.pm
-                  Parse/Pidl/NDR.pm
-                  ''',
-                  flat=False)
-
-if not bld.CONFIG_SET('USING_SYSTEM_PARSE_YAPP_DRIVER'):
-    bld.INSTALL_FILES(bld.env.PERL_LIB_INSTALL_DIR,
-                      'Parse/Yapp/Driver.pm',
-                      flat=False)
index e8e6941fb358483d5ca6600bc3b7ab11ff5ef3c4..762824e6851e43797063e51781305167f5a67063 100755 (executable)
@@ -382,7 +382,7 @@ usesgetlasterror, vararg, vi_progid, wire_marshal.
 =head1 SEE ALSO
 
 L<https://msdn.microsoft.com/en-us/library/windows/desktop/aa373864%28v=vs.85%29.aspx>
-L<https://gitlab.com/wireshark/wireshark/-/wikis/DCE/RPC>,
+L<https://wiki.wireshark.org/DCE/RPC>,
 L<https://www.samba.org/>,
 L<yapp(1)>
 
@@ -402,6 +402,7 @@ pidl README by Andrew Tridgell.
 
 
 use strict;
+use warnings;
 use FindBin qw($RealBin $Script);
 use lib "$RealBin/lib";
 use Getopt::Long;
@@ -474,6 +475,7 @@ my($opt_template) = 0;
 my($opt_client);
 my($opt_typelib);
 my($opt_server);
+my($opt_server_compat);
 my($opt_ndr_parser);
 my($opt_tdr_parser);
 my($opt_ws_parser);
@@ -559,6 +561,7 @@ my $result = GetOptions (
                'samba3-template' => \$opt_samba3_template,
                'header:s' => \$opt_header,
                'server:s' => \$opt_server,
+               'server-compat:s' => \$opt_server_compat,
                'typelib:s' => \$opt_typelib,
                'tdr-parser:s' => \$opt_tdr_parser,
                'template' => \$opt_template,
@@ -669,6 +672,7 @@ sub process_file($)
        if (defined($opt_ws_parser) or
                defined($opt_client) or
                defined($opt_server) or
+               defined($opt_server_compat) or
                defined($opt_header) or
                defined($opt_ndr_parser) or
                defined($opt_python) or
@@ -712,8 +716,11 @@ sub process_file($)
        if (defined($opt_python)) {
                require Parse::Pidl::Samba4::Python;
                my $generator = new Parse::Pidl::Samba4::Python();
+               if (!defined($opt_client)) {
+                   $c_header = undef;
+               }
                my ($prsr) = $generator->Parse($basename, $ndr,
-                                       "$outputdir/ndr_$basename\_c.h", $h_filename);
+                                              $c_header, $h_filename);
                FileSave("$outputdir/py_$basename.c", $prsr);
        }
 
@@ -794,6 +801,19 @@ sub process_file($)
                FileSave($header, $h_code);
        }
 
+       if (defined($opt_server_compat)) {
+               require Parse::Pidl::Samba4::NDR::ServerCompat;
+
+               my $c_scompat = ($opt_server_compat or "$outputdir/ndr_$basename\_scompat.c");
+               my $h_scompat = $c_scompat;
+               $h_scompat =~ s/\.c$/.h/;
+
+               my $generator = new Parse::Pidl::Samba4::NDR::ServerCompat();
+               my ($source, $header) = $generator->Parse($ndr, $h_scompat, $h_filename);
+
+               FileSave($c_scompat, $source);
+               FileSave($h_scompat, $header);
+       }
 }
 
 if (scalar(@ARGV) == 0) {
index 86b521bf94a28b25654e4a81a2cece8856537076..a7b5a63f1fb7d42604f57f136bd57d22a76cd160 100644 (file)
@@ -9,6 +9,7 @@ require Exporter;
 @EXPORT = qw(test_samba4_ndr test_warnings test_errors);
 
 use strict;
+use warnings;
 
 use FindBin qw($RealBin);
 use lib "$RealBin/../lib";
index cc089eaa1f7aabf1f48266dd31e6613b68d352f4..80d61158e3700eee0e5350f550ec8516a5049f02 100755 (executable)
@@ -2,6 +2,7 @@
 # NDR alignment tests
 # (C) 2005 Jelmer Vernooij. Published under the GNU GPL
 use strict;
+use warnings;
 
 use Test::More tests => 5 * 8;
 use FindBin qw($RealBin);
@@ -16,7 +17,7 @@ test_samba4_ndr('align-uint8-uint16',
        } bla;
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct bla r;
        uint8_t expected[] = { 0x0D, 0x00, 0xef, 0xbe };
        DATA_BLOB expected_blob = { expected, 4 };
@@ -41,7 +42,7 @@ test_samba4_ndr('align-uint8-uint32',
        } bla;
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct bla r;
        uint8_t expected[] = { 0x0D, 0x00, 0x00, 0x00, 0xef, 0xbe, 0xef, 0xbe };
        DATA_BLOB expected_blob = { expected, 8 };
@@ -67,7 +68,7 @@ test_samba4_ndr('align-uint8-hyper',
        } bla;
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(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 +94,7 @@ test_samba4_ndr('noalignflag-uint8-uint16',
        } bla;
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct bla r;
        uint8_t expected[] = { 0x0D, 0xef, 0xbe };
        DATA_BLOB expected_blob = { expected, 3 };
@@ -121,7 +122,7 @@ test_samba4_ndr('align-blob-align2',
        } blie;
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct blie r;
        uint8_t data[] = { 0x01, 0x02 };
        uint8_t expected[] = { 0x0D, 0x00, 0x0E };
index 399fbd21d62c5a7854d7f2827348ac84988c2965..c708c3b53936ea4d2ec92a275c1e8212092447bf 100755 (executable)
@@ -2,6 +2,7 @@
 # NDR allocation tests
 # (C) 2005 Jelmer Vernooij. Published under the GNU GPL
 use strict;
+use warnings;
 
 use Test::More tests => 5 * 8;
 use FindBin qw($RealBin);
index 2a6b5bbd57dfc8491723e7c0c110e5b93f4ac09f..46ab83ec14c5bac7cc25c6266aedfae1ed1cb6a6 100755 (executable)
@@ -3,6 +3,7 @@
 # (C) 2005 Jelmer Vernooij <jelmer@samba.org>
 # Published under the GNU General Public License
 use strict;
+use warnings;
 
 use Test::More tests => 8;
 use FindBin qw($RealBin);
index 355e7f67323c2381222e8f768db1e6b24c374701..06f7efb40009c87d1f536a9d3ee50dd7b09d5fe1 100755 (executable)
@@ -2,6 +2,7 @@
 # (C) 2007 Jelmer Vernooij <jelmer@samba.org>
 # Published under the GNU General Public License
 use strict;
+use warnings;
 
 use Test::More tests => 2;
 use FindBin qw($RealBin);
index cc6fca7ab39bcd46a0752fe0dbef57cb9cbe4639..109b368ea22b37f408487b5bec5e72b2c4b2abb5 100755 (executable)
@@ -3,6 +3,7 @@
 # (C) 2006 Jelmer Vernooij <jelmer@samba.org>.
 # Published under the GNU General Public License.
 use strict;
+use warnings;
 
 use Test::More tests => 1 * 8;
 use FindBin qw($RealBin);
@@ -17,7 +18,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_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        uint32_t v = 13;
        struct echo_TestFull r;
        r.in.x = &v; 
index d5dd83957a41c3fd560627c400d1e523c867057c..94676a80524ec294572236bacef6ae3e8f9637c6 100755 (executable)
@@ -4,6 +4,7 @@
 # (C) 2005 Jelmer Vernooij <jelmer@samba.org>.
 # Published under the GNU General Public License.
 use strict;
+use warnings;
 
 use Test::More tests => 22 * 8;
 use FindBin qw($RealBin);
@@ -18,7 +19,7 @@ test_samba4_ndr("noptr-push",
        [public] uint16 echo_TestRef([in] xstruct foo);
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        uint16_t v = 13;
        struct echo_TestRef r;
        r.in.foo.x = v; 
@@ -48,7 +49,7 @@ test_samba4_ndr("ptr-embedded-push",
 ',
 '
        uint16_t v = 13;
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo.x = &v; 
 
@@ -74,7 +75,7 @@ test_samba4_ndr("ptr-embedded-push-null",
        [public] uint16 echo_TestRef([in] xstruct foo);
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo.x = NULL; 
 
@@ -99,7 +100,7 @@ test_samba4_ndr("refptr-embedded-push",
 ',
 '
        uint16_t v = 13;
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo.x = &v; 
 
@@ -126,7 +127,7 @@ test_samba4_ndr("refptr-embedded-push-null",
        [public] uint16 echo_TestRef([in] xstruct foo);
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo.x = NULL; 
 
@@ -144,7 +145,7 @@ test_samba4_ndr("ptr-top-push",
        [public] uint16 echo_TestRef([in] xstruct *foo);
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        struct xstruct s;
        s.x = 13;
@@ -169,7 +170,7 @@ test_samba4_ndr("ptr-top-push-null",
        [public] uint16 echo_TestRef([in] xstruct *foo);
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo = NULL;
 
@@ -189,7 +190,7 @@ test_samba4_ndr("refptr-top-push",
        [public] uint16 echo_TestRef([in,ref] xstruct *foo);
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        struct xstruct s;
        s.x = 13;
@@ -214,7 +215,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, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo = NULL;
 
@@ -233,7 +234,7 @@ test_samba4_ndr("uniqueptr-top-push",
        [public] uint16 echo_TestRef([in,unique] xstruct *foo);
 ',
 '
-       struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        struct xstruct s;
        s.x = 13;
@@ -261,7 +262,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, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo = NULL;
 
@@ -381,7 +382,7 @@ test_samba4_ndr("ptr-top-push-double",
 '
        [public] void echo_TestRef([in] uint16 **foo);
 ',
-'      struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
+'      struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        uint16_t v = 13;
        uint16_t *pv = &v;
@@ -408,7 +409,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, NULL);
+'      struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        uint16_t *pv = NULL;
        r.in.foo = &pv;
@@ -429,7 +430,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, NULL);
+'      struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo = NULL;
 
@@ -445,7 +446,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, NULL);
+'      struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        uint16_t v = 13;
        uint16_t *pv = &v;
@@ -473,7 +474,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, NULL);
+'      struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        uint16_t *pv = NULL;
        r.in.foo = &pv;
@@ -494,7 +495,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, NULL);
+'      struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        r.in.foo = NULL;
 
@@ -511,7 +512,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, NULL);
+'      struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct echo_TestRef r;
        uint16_t v = 10;
        r.in.foo = &v; 
index 2d65fb92b09a836bbaa5c50276ff65f866a79636..af9a92b6a238a8cfac0890c75625d210b9a81313 100755 (executable)
@@ -2,6 +2,7 @@
 # NDR represent_as() / transmit_as() tests
 # (C) 2006 Jelmer Vernooij. Published under the GNU GPL
 use strict;
+use warnings;
 
 use Test::More tests => 2 * 8;
 use FindBin qw($RealBin);
index 15e07d569347e9c39e835f06784fdc3c983606e1..c5c32445cfd0bd23d5da4306602b575908968ee6 100755 (executable)
@@ -3,6 +3,7 @@
 # (C) 2005 Jelmer Vernooij <jelmer@samba.org>
 # Published under the GNU General Public License
 use strict;
+use warnings;
 
 use Test::More tests => 8;
 use FindBin qw($RealBin);
index 8e8b8ecbad6c46f4ff428549b67381f60f1dd307..aa5fd8b5d1d6287fdd9dbed8cbbab4f54fc41c34 100755 (executable)
@@ -3,6 +3,7 @@
 # (C) 2005 Jelmer Vernooij <jelmer@samba.org>
 # Published under the GNU General Public License
 use strict;
+use warnings;
 
 use Test::More tests => 6 * 8;
 use FindBin qw($RealBin);
index 3f9b717bfef34753eee4b995eafa2c4f78a97a67..fa09cf773c14ef963992f27e246b602eb87e58b5 100755 (executable)
@@ -2,7 +2,7 @@
 # Support for tagged types
 # (C) 2005 Jelmer Vernooij. Published under the GNU GPL
 use strict;
-
+use warnings;
 use Test::More tests => 3 * 8;
 use FindBin qw($RealBin);
 use lib "$RealBin";
@@ -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, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(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, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(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, NULL);
+       struct ndr_push *ndr = ndr_push_init_ctx(NULL);
        struct myst st;
        uint8_t expected[] = { 0x0D };
        DATA_BLOB expected_blob = { expected, 1 };
index 14138a37b89bdb0667ee1a15c957c35f4edb2d3e..caf701b3b7783b9ce747d7f72391939b1fe4007f 100755 (executable)
@@ -3,7 +3,7 @@
 # (C) 2005 Jelmer Vernooij <jelmer@samba.org>
 # Published under the GNU General Public License
 use strict;
-
+use warnings;
 use Test::More tests => 65 * 2 + 7;
 use FindBin qw($RealBin);
 use lib "$RealBin";
index 7c53cbc76f0929c3a16b8d01ff46a0449017ee69..54a4e46d65f999eef898657185980601df3021e2 100755 (executable)
@@ -8,7 +8,6 @@ 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 
        NeededFunction NeededElement NeededType
index c758ef45425b0bb8456ebeff408d399442cae240..4349abb39d6e46c0936324cb67dd657d71e05c8e 100755 (executable)
@@ -9,7 +9,7 @@ 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::Samba3::ClientNDR;
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
 
 # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
index d6cd7a03d4c1804e51160dd77592939e8e7b65e8..41a560c842bd8afb3730119d0e7bc4de6d5bf1ad 100755 (executable)
@@ -13,18 +13,18 @@ use Parse::Pidl::Samba4::TDR qw(ParserType);
 my $tdr = new Parse::Pidl::Samba4::TDR();
 
 $tdr->ParserType({TYPE => "STRUCT", NAME => "foo", PROPERTIES => {public => 1}}, "pull");
-is($tdr->{ret}, "NTSTATUS tdr_pull_foo (struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, struct foo *v)
+is($tdr->{res}, "NTSTATUS tdr_pull_foo (struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, struct foo *v)
 {
        return NT_STATUS_OK;
 }
 
 ");
-is($tdr->{ret_hdr}, "NTSTATUS tdr_pull_foo (struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, struct foo *v);\n");
+is($tdr->{res_hdr}, "NTSTATUS tdr_pull_foo (struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, struct foo *v);\n");
 
 
 $tdr = new Parse::Pidl::Samba4::TDR();
 $tdr->ParserType({TYPE => "UNION", NAME => "bar", PROPERTIES => {public => 1}}, "pull");
-is($tdr->{ret}, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v)
+is($tdr->{res}, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v)
 {
        switch (level) {
        }
@@ -33,11 +33,11 @@ is($tdr->{ret}, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx
 }
 
 ");
-is($tdr->{ret_hdr}, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v);\n");
+is($tdr->{res_hdr}, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v);\n");
 
 $tdr = new Parse::Pidl::Samba4::TDR();
 $tdr->ParserType({TYPE => "UNION", NAME => "bar", PROPERTIES => {}}, "pull");
-is($tdr->{ret}, "static NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v)
+is($tdr->{res}, "static NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v)
 {
        switch (level) {
        }
@@ -46,4 +46,4 @@ is($tdr->{ret}, "static NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *
 }
 
 "); 
-is($tdr->{ret_hdr}, "");
+is($tdr->{res_hdr}, "");
index 2d59f6283bbf14bb162ff5fb6b0101ebb1cc2b03..93addceaed4cf525d110a72661039dc38d571f4f 100755 (executable)
@@ -2,6 +2,7 @@
 # (C) 2007 Jelmer Vernooij <jelmer@samba.org>
 # Published under the GNU General Public License
 use strict;
+use warnings;
 
 use Test::More tests => 6;
 use FindBin qw($RealBin);
index f4ff902812c764c2012d7edb375da31a8baedf73..50fe12c013dba020e8a50b729bcedfdc7ac5af2c 100644 (file)
@@ -1,77 +1,38 @@
 #!/usr/bin/env python
 
-import os, Logs
+import os, string
 from samba_utils import MODE_755
+from waflib import Logs, Errors
 
 # This function checks if a perl module is installed on the system.
 def check_system_perl_module(conf, module, version=None):
-    bundle_name = module.replace('::', '_')
     module_check = module
 
     # Create module string with version
     if version:
         module_check = module + ' ' + str(version)
 
-    # Check if we have to bundle it.
-    if conf.LIB_MUST_BE_BUNDLED(bundle_name.lower()):
-        return False
-
     # Check for system perl module
-    if not conf.check_perl_module(module_check):
+    if conf.check_perl_module(module_check) is None:
         return False
 
-    conf.define('USING_SYSTEM_%s' % bundle_name.upper(), 1)
-
     return True
 
-def set_options(opt):
+def options(opt):
     return
 
 def configure(conf):
     # Check if perl(Parse::Yapp::Driver) is available.
-    check_system_perl_module(conf, "Parse::Yapp::Driver", 1.05)
-
-    # we need a recent version of MakeMaker to get the right man page names
-    if conf.CHECK_PERL_MANPAGE():
-        conf.env.PERLMAN1EXT = conf.CHECK_PERL_MANPAGE(section='1')
-        conf.env.PERLMAN3EXT = conf.CHECK_PERL_MANPAGE(section='3')
-        conf.DEFINE('HAVE_PERL_MAKEMAKER', 1)
+    if not check_system_perl_module(conf,
+                                    "Parse::Yapp::Driver",
+                                    1.05):
+        raise Errors.WafError('perl module "Parse::Yapp::Driver" not found')
 
     # yapp is used for building the parser
-    conf.find_program('yapp', var='YAPP')
-    conf.find_program('pod2man', var='POD2MAN')
+    if not conf.find_program('yapp', var='YAPP'):
+        raise Errors.WafError('yapp not found')
 
 def build(bld):
-    bld.INSTALL_FILES('${BINDIR}', 'pidl', chmod=MODE_755, perl_fixup=True)
-
-    bld.RECURSE('lib')
-
-    if not bld.CONFIG_SET('HAVE_PERL_MAKEMAKER'):
-        return
-
-    pidl_manpages = {
-        'pidl': 'man1/pidl.${PERLMAN1EXT}',
-        'lib/Parse/Pidl/NDR.pm': 'man3/Parse::Pidl::NDR.${PERLMAN3EXT}',
-        'lib/Parse/Pidl/Wireshark/Conformance.pm': 'man3/Parse::Pidl::Wireshark::Conformance.${PERLMAN3EXT}',
-        'lib/Parse/Pidl/Dump.pm': 'man3/Parse::Pidl::Dump.${PERLMAN3EXT}',
-        'lib/Parse/Pidl/Util.pm': 'man3/Parse::Pidl::Util.${PERLMAN3EXT}',
-        'lib/Parse/Pidl/Wireshark/NDR.pm': 'man3/Parse::Pidl::Wireshark::NDR.${PERLMAN3EXT}'
-    }
-
-    for k, v in pidl_manpages.iteritems():
-        pidl_manpages[k] = bld.EXPAND_VARIABLES(v)
-
-    # use perl to build the manpages
-    bld.env.pidl_srcdir = os.path.join(bld.srcnode.abspath(), 'pidl')
-
-    bld.SET_BUILD_GROUP('final')
-    if 'POD2MAN' in bld.env and bld.env['POD2MAN'] != '':
-        for src, manpage in pidl_manpages.iteritems():
-            bld(rule='${POD2MAN} -c "Samba Documentation" ${SRC} ${TGT}',
-                shell=True,
-                source=src,
-                install_path=os.path.dirname(bld.EXPAND_VARIABLES('${MANDIR}/'+manpage)),
-                target=os.path.basename(manpage))
 
     # we want to prefer the git version of the parsers if we can.
     # Only if the source has changed do we want to re-run yapp