CHECKED... TODO:MSG pidl/Samba4::NDR::Parser: fix ...
[metze/samba/wb-ndr.git] / source / pidl / lib / Parse / Pidl / Samba4 / NDR / Parser.pm
index 73ff28eed02b592a503f9e0f33417b2aa629daac..281018d4ccb9a1214cdda183a01d0bfdb37e1da4 100644 (file)
@@ -9,13 +9,15 @@ package Parse::Pidl::Samba4::NDR::Parser;
 
 require Exporter;
 @ISA = qw(Exporter);
-@EXPORT_OK = qw(check_null_pointer GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint);
+@EXPORT_OK = qw(check_null_pointer NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint);
 
 use strict;
-use Parse::Pidl::Typelist qw(hasType getType mapTypeName);
+use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody);
 use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid);
-use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
+use Parse::Pidl::CUtil qw(get_pointer_to get_value_of);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);
 use Parse::Pidl::Samba4 qw(is_intree choose_header);
+use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
 use Parse::Pidl qw(warning);
 
 use vars qw($VERSION);
@@ -40,19 +42,21 @@ sub append_prefix($$)
 {
        my ($e, $var_name) = @_;
        my $pointers = 0;
+       my $arrays = 0;
 
        foreach my $l (@{$e->{LEVELS}}) {
                if ($l->{TYPE} eq "POINTER") {
                        $pointers++;
                } elsif ($l->{TYPE} eq "ARRAY") {
+                       $arrays++;
                        if (($pointers == 0) and 
                            (not $l->{IS_FIXED}) and
                            (not $l->{IS_INLINE})) {
-                               return get_value_of($var_name); 
+                               return get_value_of($var_name);
                        }
                } elsif ($l->{TYPE} eq "DATA") {
                        if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
-                               return get_value_of($var_name) unless ($pointers);
+                               return get_value_of($var_name) unless ($pointers or $arrays);
                        }
                }
        }
@@ -76,42 +80,6 @@ sub has_fast_array($$)
        return ($t->{NAME} eq "uint8") or ($t->{NAME} eq "string");
 }
 
-sub is_charset_array($$)
-{
-       my ($e,$l) = @_;
-
-       return 0 if ($l->{TYPE} ne "ARRAY");
-
-       my $nl = GetNextLevel($e,$l);
-
-       return 0 unless ($nl->{TYPE} eq "DATA");
-
-       return has_property($e, "charset");
-}
-
-sub get_pointer_to($)
-{
-       my $var_name = shift;
-       
-       if ($var_name =~ /^\*(.*)$/) {
-               return $1;
-       } elsif ($var_name =~ /^\&(.*)$/) {
-               return "&($var_name)";
-       } else {
-               return "&$var_name";
-       }
-}
-
-sub get_value_of($)
-{
-       my $var_name = shift;
-
-       if ($var_name =~ /^\&(.*)$/) {
-               return $1;
-       } else {
-               return "*$var_name";
-       }
-}
 
 ####################################
 # pidl() is our basic output routine
@@ -215,68 +183,6 @@ sub end_flags($$)
        }
 }
 
-sub GenerateStructEnv($$)
-{
-       my ($x, $v) = @_;
-       my %env;
-
-       foreach my $e (@{$x->{ELEMENTS}}) {
-               $env{$e->{NAME}} = "$v->$e->{NAME}";
-       }
-
-       $env{"this"} = $v;
-
-       return \%env;
-}
-
-sub EnvSubstituteValue($$)
-{
-       my ($env,$s) = @_;
-
-       # Substitute the value() values in the env
-       foreach my $e (@{$s->{ELEMENTS}}) {
-               next unless (defined(my $v = has_property($e, "value")));
-               
-               $env->{$e->{NAME}} = ParseExpr($v, $env, $e);
-       }
-
-       return $env;
-}
-
-sub GenerateFunctionInEnv($;$)
-{
-       my ($fn, $base) = @_;
-       my %env;
-
-       $base = "r->" unless defined($base);
-
-       foreach my $e (@{$fn->{ELEMENTS}}) {
-               if (grep (/in/, @{$e->{DIRECTION}})) {
-                       $env{$e->{NAME}} = $base."in.$e->{NAME}";
-               }
-       }
-
-       return \%env;
-}
-
-sub GenerateFunctionOutEnv($;$)
-{
-       my ($fn, $base) = @_;
-       my %env;
-
-       $base = "r->" unless defined($base);
-
-       foreach my $e (@{$fn->{ELEMENTS}}) {
-               if (grep (/out/, @{$e->{DIRECTION}})) {
-                       $env{$e->{NAME}} = $base."out.$e->{NAME}";
-               } elsif (grep (/in/, @{$e->{DIRECTION}})) {
-                       $env{$e->{NAME}} = $base."in.$e->{NAME}";
-               }
-       }
-
-       return \%env;
-}
-
 #####################################################################
 # parse the data of an array - push side
 sub ParseArrayPushHeader($$$$$$)
@@ -423,8 +329,10 @@ sub ParseArrayPullHeader($$$$$$)
        } elsif ($l->{IS_ZERO_TERMINATED}) { # Noheader arrays
                $length = $size = "ndr_get_string_size($ndr, sizeof(*$var_name))";
        } else {
-               $length = $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL}, 
-                   check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
+               $length = $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
+                       check_null_pointer($e, $env, sub { $self->pidl(shift); },
+                                          "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"),
+                       check_fully_dereferenced($e, $env));
        }
 
        if ((!$l->{IS_SURROUNDING}) and $l->{IS_CONFORMANT}) {
@@ -447,7 +355,10 @@ sub ParseArrayPullHeader($$$$$$)
        if ($l->{IS_CONFORMANT} and not $l->{IS_ZERO_TERMINATED}) {
                $self->defer("if ($var_name) {");
                $self->defer_indent;
-               my $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->defer(shift); }, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
+               my $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
+                       check_null_pointer($e, $env, sub { $self->defer(shift); },
+                                          "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"),
+                       check_fully_dereferenced($e, $env));
                $self->defer("NDR_CHECK(ndr_check_array_size(ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
                $self->defer_deindent;
                $self->defer("}");
@@ -457,7 +368,8 @@ sub ParseArrayPullHeader($$$$$$)
                $self->defer("if ($var_name) {");
                $self->defer_indent;
                my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL}, 
-                       check_null_pointer($e, $env, sub { $self->defer(shift); }, "return NT_STATUS_INVALID_PARAMETER_MIX;"), 
+                       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));");
                $self->defer_deindent;
@@ -465,7 +377,7 @@ sub ParseArrayPullHeader($$$$$$)
        }
 
        if (not $l->{IS_FIXED} and not is_charset_array($e, $l)) {
-               $self->AllocateArrayLevel($e,$l,$ndr,$env,$size);
+               $self->AllocateArrayLevel($e,$l,$ndr,$var_name,$size);
        }
 
        return $length;
@@ -474,7 +386,7 @@ sub ParseArrayPullHeader($$$$$$)
 sub compression_alg($$)
 {
        my ($e, $l) = @_;
-       my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
+       my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION});
 
        return $alg;
 }
@@ -482,7 +394,7 @@ sub compression_alg($$)
 sub compression_clen($$$)
 {
        my ($e, $l, $env) = @_;
-       my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
+       my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION});
 
        return ParseExpr($clen, $env, $e->{ORIGINAL});
 }
@@ -490,7 +402,7 @@ sub compression_clen($$$)
 sub compression_dlen($$$)
 {
        my ($e,$l,$env) = @_;
-       my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
+       my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION});
 
        return ParseExpr($dlen, $env, $e->{ORIGINAL});
 }
@@ -740,7 +652,11 @@ sub ParsePtrPush($$$$)
        my ($self,$e,$l,$var_name) = @_;
 
        if ($l->{POINTER_TYPE} eq "ref") {
-               $self->pidl("if ($var_name == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;");
+               $self->pidl("if ($var_name == NULL) {");
+               $self->indent;
+               $self->pidl("return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");");
+               $self->deindent;
+               $self->pidl("}");
                if ($l->{LEVEL} eq "EMBEDDED") {
                        $self->pidl("NDR_CHECK(ndr_push_ref_ptr(ndr));");
                }
@@ -755,23 +671,48 @@ sub ParsePtrPush($$$$)
        }
 }
 
+sub need_pointer_to($$$)
+{
+       my ($e, $l, $scalar_only) = @_;
+
+       my $t;
+       if (ref($l->{DATA_TYPE})) {
+               $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
+       } else {
+               $t = $l->{DATA_TYPE};
+       }
+
+       if (not Parse::Pidl::Typelist::is_scalar($t)) {
+               return 1 if $scalar_only;
+       }
+
+       my $arrays = 0;
+
+       foreach my $tl (@{$e->{LEVELS}}) {
+               last if $l == $tl;
+               if ($tl->{TYPE} eq "ARRAY") {
+                       $arrays++;
+               }
+       }
+
+       if (Parse::Pidl::Typelist::scalar_is_reference($t)) {
+               return 1 unless $arrays;
+       }
+
+       return 0;
+}
+
 sub ParseDataPrint($$$$)
 {
        my ($self, $e, $l, $var_name) = @_;
        
-       if (not ref($l->{DATA_TYPE}) or 
-               defined($l->{DATA_TYPE}->{NAME})) {
-               my $t;
-               if (ref($l->{DATA_TYPE})) {
-                       $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
-               } else {
-                       $t = $l->{DATA_TYPE};
-               }
-               if (not Parse::Pidl::Typelist::is_scalar($t) or 
-                       Parse::Pidl::Typelist::scalar_is_reference($t)) {
+       if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
+
+               if (need_pointer_to($e, $l, 1)) {
                        $var_name = get_pointer_to($var_name);
                }
-               $self->pidl("ndr_print_$t(ndr, \"$e->{NAME}\", $var_name);");
+
+               $self->pidl(TypeFunctionName("ndr_print", $l->{DATA_TYPE})."(ndr, \"$e->{NAME}\", $var_name);");
        } else {
                $self->ParseTypePrint($l->{DATA_TYPE}, $var_name);
        }
@@ -875,7 +816,9 @@ sub ParseSwitchPull($$$$$$)
 {
        my($self,$e,$l,$ndr,$var_name,$env) = @_;
        my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, 
-               check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
+               check_null_pointer($e, $env, sub { $self->pidl(shift); },
+                                  "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"),
+               check_fully_dereferenced($e, $env));
 
        $var_name = get_pointer_to($var_name);
        $self->pidl("NDR_CHECK(ndr_pull_set_switch_value($ndr, $var_name, $switch_var));");
@@ -887,7 +830,9 @@ sub ParseSwitchPush($$$$$$)
 {
        my($self,$e,$l,$ndr,$var_name,$env) = @_;
        my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, 
-               check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
+               check_null_pointer($e, $env, sub { $self->pidl(shift); },
+                                  "return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"),
+               check_fully_dereferenced($e, $env));
 
        $var_name = get_pointer_to($var_name);
        $self->pidl("NDR_CHECK(ndr_push_set_switch_value($ndr, $var_name, $switch_var));");
@@ -897,12 +842,11 @@ sub ParseDataPull($$$$$$$)
 {
        my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_;
 
-       if (not ref($l->{DATA_TYPE}) or 
-               defined($l->{DATA_TYPE}->{NAME})) {
+       if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
 
                my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
 
-               if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
+               if (need_pointer_to($e, $l, 0)) {
                        $var_name = get_pointer_to($var_name);
                }
 
@@ -912,7 +856,7 @@ sub ParseDataPull($$$$$$$)
 
                if (my $range = has_property($e, "range")) {
                        $var_name = get_value_of($var_name);
-                       my ($low, $high) = split(/ /, $range, 2);
+                       my ($low, $high) = split(/,/, $range, 2);
                        $self->pidl("if ($var_name < $low || $var_name > $high) {");
                        $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");");
                        $self->pidl("}");
@@ -927,21 +871,15 @@ sub ParseDataPush($$$$$$$)
        my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_;
 
        if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
-               my $t;
-               if (ref($l->{DATA_TYPE}) eq "HASH") {
-                       $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
-               } else {
-                       $t = $l->{DATA_TYPE};
-               }
-                               
+
+               my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
+
                # strings are passed by value rather than reference
-               if (not Parse::Pidl::Typelist::is_scalar($t) or 
-                       Parse::Pidl::Typelist::scalar_is_reference($t)) {
+               if (need_pointer_to($e, $l, 1)) {
                        $var_name = get_pointer_to($var_name);
                }
 
-               my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
-               $self->pidl("NDR_CHECK(ndr_push_$t($ndr, $ndr_flags, $var_name));");
+               $self->pidl("NDR_CHECK(".TypeFunctionName("ndr_push", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));");
        } else {
                $self->ParseTypePush($l->{DATA_TYPE}, $var_name, $primitives, $deferred);
        }
@@ -972,15 +910,17 @@ sub CalcNdrFlags($$$)
        return undef;
 }
 
-sub ParseMemCtxPullStart($$$$)
+sub ParseMemCtxPullFlags($$$$)
 {
-       my ($self, $e, $l, $ptr_name) = @_;
+       my ($self, $e, $l) = @_;
 
-       my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
-       my $mem_c_ctx = $ptr_name;
-       my $mem_c_flags = "0";
+       return undef unless ($l->{TYPE} eq "POINTER" or $l->{TYPE} eq "ARRAY");
+
+       return undef if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});
+       return undef if has_fast_array($e, $l);
+       return undef if is_charset_array($e, $l);
 
-       return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});
+       my $mem_flags = "0";
 
        if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
                my $nl = GetNextLevel($e, $l);
@@ -988,12 +928,25 @@ sub ParseMemCtxPullStart($$$$)
                my $next_is_string = (($nl->{TYPE} eq "DATA") and 
                                        ($nl->{DATA_TYPE} eq "string"));
                if ($next_is_array or $next_is_string) {
-                       return;
+                       return undef;
                } else {
-                       $mem_c_flags = "LIBNDR_FLAG_REF_ALLOC";
+                       $mem_flags = "LIBNDR_FLAG_REF_ALLOC";
                }
        }
 
+       return $mem_flags;
+}
+
+sub ParseMemCtxPullStart($$$$)
+{
+       my ($self, $e, $l, $ptr_name) = @_;
+
+       my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
+       my $mem_c_ctx = $ptr_name;
+       my $mem_c_flags = $self->ParseMemCtxPullFlags($e, $l);
+
+       return unless defined($mem_c_flags);
+
        $self->pidl("$mem_r_ctx = NDR_PULL_GET_MEM_CTX(ndr);");
        $self->pidl("NDR_PULL_SET_MEM_CTX(ndr, $mem_c_ctx, $mem_c_flags);");
 }
@@ -1003,21 +956,9 @@ sub ParseMemCtxPullEnd($$$)
        my ($self, $e, $l) = @_;
 
        my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
-       my $mem_r_flags = "0";
+       my $mem_r_flags = $self->ParseMemCtxPullFlags($e, $l);
 
-       return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});
-
-       if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
-               my $nl = GetNextLevel($e, $l);
-               my $next_is_array = ($nl->{TYPE} eq "ARRAY");
-               my $next_is_string = (($nl->{TYPE} eq "DATA") and 
-                                       ($nl->{DATA_TYPE} eq "string"));
-               if ($next_is_array or $next_is_string) {
-                       return;
-               } else {
-                       $mem_r_flags = "LIBNDR_FLAG_REF_ALLOC";
-               }
-       }
+       return unless defined($mem_r_flags);
 
        $self->pidl("NDR_PULL_SET_MEM_CTX(ndr, $mem_r_ctx, $mem_r_flags);");
 }
@@ -1081,8 +1022,8 @@ sub ParseElementPullLevel
                        $self->indent;
 
                        if ($l->{POINTER_TYPE} eq "relative") {
-                               $self->pidl("struct ndr_pull_save _relative_save;");
-                               $self->pidl("ndr_pull_save(ndr, &_relative_save);");
+                               $self->pidl("uint32_t _relative_save_offset;");
+                               $self->pidl("_relative_save_offset = ndr->offset;");
                                $self->pidl("NDR_CHECK(ndr_pull_relative_ptr2(ndr, $var_name));");
                        }
                }
@@ -1096,7 +1037,7 @@ sub ParseElementPullLevel
 
                if ($l->{POINTER_TYPE} ne "ref") {
                        if ($l->{POINTER_TYPE} eq "relative") {
-                               $self->pidl("ndr_pull_restore(ndr, &_relative_save);");
+                               $self->pidl("ndr->offset = _relative_save_offset;");
                        }
                        $self->deindent;
                        $self->pidl("}");
@@ -1523,31 +1464,12 @@ sub DeclareArrayVariables($$)
        }
 }
 
-sub need_decl_mem_ctx($$)
-{
-       my ($e,$l) = @_;
-
-       return 0 if has_fast_array($e,$l);
-       return 0 if is_charset_array($e,$l);
-       return 1 if (($l->{TYPE} eq "ARRAY") and not $l->{IS_FIXED});
-
-       if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
-               my $nl = GetNextLevel($e, $l);
-               my $next_is_array = ($nl->{TYPE} eq "ARRAY");
-               my $next_is_string = (($nl->{TYPE} eq "DATA") and 
-                                       ($nl->{DATA_TYPE} eq "string"));
-               return 0 if ($next_is_array or $next_is_string);
-       }
-       return 1 if ($l->{TYPE} eq "POINTER");
-
-       return 0;
-}
-
 sub DeclareMemCtxVariables($$)
 {
        my ($self,$e) = @_;
        foreach my $l (@{$e->{LEVELS}}) {
-               if (need_decl_mem_ctx($e, $l)) {
+               my $mem_flags = $self->ParseMemCtxPullFlags($e, $l);
+               if (defined($mem_flags)) {
                        $self->pidl("TALLOC_CTX *_mem_save_$e->{NAME}_$l->{LEVEL_INDEX};");
                }
        }
@@ -2089,7 +2011,7 @@ sub ParseFunctionPush($$)
 { 
        my($self, $fn) = @_;
 
-       $self->fn_declare("push", $fn, "NTSTATUS ndr_push_$fn->{NAME}(struct ndr_push *ndr, int flags, const struct $fn->{NAME} *r)") or return;
+       $self->fn_declare("push", $fn, "enum ndr_err_code ndr_push_$fn->{NAME}(struct ndr_push *ndr, int flags, const struct $fn->{NAME} *r)") or return;
 
        return if has_property($fn, "nopush");
 
@@ -2132,7 +2054,7 @@ sub ParseFunctionPush($$)
     
        $self->deindent;
        $self->pidl("}");
-       $self->pidl("return NT_STATUS_OK;");
+       $self->pidl("return NDR_ERR_SUCCESS;");
        $self->deindent;
        $self->pidl("}");
        $self->pidl("");
@@ -2140,9 +2062,7 @@ sub ParseFunctionPush($$)
 
 sub AllocateArrayLevel($$$$$$)
 {
-       my ($self,$e,$l,$ndr,$env,$size) = @_;
-
-       my $var = ParseExpr($e->{NAME}, $env, $e->{ORIGINAL});
+       my ($self,$e,$l,$ndr,$var,$size) = @_;
 
        my $pl = GetPrevLevel($e, $l);
        if (defined($pl) and 
@@ -2169,7 +2089,7 @@ sub ParseFunctionPull($$)
        my($self,$fn) = @_;
 
        # pull function args
-       $self->fn_declare("pull", $fn, "NTSTATUS ndr_pull_$fn->{NAME}(struct ndr_pull *ndr, int flags, struct $fn->{NAME} *r)") or return;
+       $self->fn_declare("pull", $fn, "enum ndr_err_code ndr_pull_$fn->{NAME}(struct ndr_pull *ndr, int flags, struct $fn->{NAME} *r)") or return;
 
        $self->pidl("{");
        $self->indent;
@@ -2222,9 +2142,10 @@ sub ParseFunctionPull($$)
                        and   $e->{LEVELS}[1]->{IS_ZERO_TERMINATED});
 
                if ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") {
-                       my $size = ParseExprExt($e->{LEVELS}[1]->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return NT_STATUS_INVALID_PARAMETER_MIX;"), 
+                       my $size = ParseExprExt($e->{LEVELS}[1]->{SIZE_IS}, $env, $e->{ORIGINAL},
+                               check_null_pointer($e, $env, sub { $self->pidl(shift); },
+                                                  "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"),
                                check_fully_dereferenced($e, $env));
-                       
                        $self->pidl("NDR_PULL_ALLOC_N(ndr, r->out.$e->{NAME}, $size);");
 
                        if (grep(/in/, @{$e->{DIRECTION}})) {
@@ -2264,7 +2185,7 @@ sub ParseFunctionPull($$)
        $self->deindent;
        $self->pidl("}");
 
-       $self->pidl("return NT_STATUS_OK;");
+       $self->pidl("return NDR_ERR_SUCCESS;");
        $self->deindent;
        $self->pidl("}");
        $self->pidl("");
@@ -2281,7 +2202,7 @@ sub FunctionTable($$)
        return if ($#{$interface->{FUNCTIONS}}+1 == 0);
        return unless defined ($interface->{PROPERTIES}->{uuid});
 
-       $self->pidl("static const struct dcerpc_interface_call $interface->{NAME}\_calls[] = {");
+       $self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {");
        foreach my $d (@{$interface->{FUNCTIONS}}) {
                next if not defined($d->{OPNUM});
                $self->pidl("\t{");
@@ -2290,11 +2211,11 @@ sub FunctionTable($$)
                $self->pidl("\t\t(ndr_push_flags_fn_t) ndr_push_$d->{NAME},");
                $self->pidl("\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},");
                $self->pidl("\t\t(ndr_print_function_t) ndr_print_$d->{NAME},");
-               $self->pidl("\t\t".($d->{ASYNC}?"True":"False").",");
+               $self->pidl("\t\t".($d->{ASYNC}?"true":"false").",");
                $self->pidl("\t},");
                $count++;
        }
-       $self->pidl("\t{ NULL, 0, NULL, NULL, NULL, False }");
+       $self->pidl("\t{ NULL, 0, NULL, NULL, NULL, false }");
        $self->pidl("};");
        $self->pidl("");
 
@@ -2307,7 +2228,7 @@ sub FunctionTable($$)
        $self->pidl("};");
        $self->pidl("");
 
-       $self->pidl("static const struct dcerpc_endpoint_list $interface->{NAME}\_endpoints = {");
+       $self->pidl("static const struct ndr_interface_string_array $interface->{NAME}\_endpoints = {");
        $self->pidl("\t.count\t= $endpoint_count,");
        $self->pidl("\t.names\t= $interface->{NAME}\_endpoint_strings");
        $self->pidl("};");
@@ -2317,7 +2238,7 @@ sub FunctionTable($$)
                $interface->{PROPERTIES}->{authservice} = "\"host\"";
        }
 
-       my @a = split / /, $interface->{PROPERTIES}->{authservice};
+       my @a = split /,/, $interface->{PROPERTIES}->{authservice};
        my $authservice_count = $#a + 1;
 
        $self->pidl("static const char * const $interface->{NAME}\_authservice_strings[] = {");
@@ -2327,19 +2248,19 @@ sub FunctionTable($$)
        $self->pidl("};");
        $self->pidl("");
 
-       $self->pidl("static const struct dcerpc_authservice_list $interface->{NAME}\_authservices = {");
+       $self->pidl("static const struct ndr_interface_string_array $interface->{NAME}\_authservices = {");
        $self->pidl("\t.count\t= $endpoint_count,");
        $self->pidl("\t.names\t= $interface->{NAME}\_authservice_strings");
        $self->pidl("};");
        $self->pidl("");
 
-       $self->pidl("\nconst struct dcerpc_interface_table dcerpc_table_$interface->{NAME} = {");
+       $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\tDCERPC_$uname\_VERSION");
+       $self->pidl("\t\tNDR_$uname\_VERSION");
        $self->pidl("\t},");
-       $self->pidl("\t.helpstring\t= DCERPC_$uname\_HELPSTRING,");
+       $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.endpoints\t= &$interface->{NAME}\_endpoints,");
@@ -2377,37 +2298,38 @@ sub HeaderInclude
 # generate prototypes and defines for the interface definitions
 # FIXME: these prototypes are for the DCE/RPC client functions, not the 
 # NDR parser and so do not belong here, technically speaking
-sub HeaderInterface($$)
+sub HeaderInterface($$$)
 {
-       my($self,$interface) = @_;
+       my($self,$interface,$needed) = @_;
 
        my $count = 0;
 
-       $self->pidl_hdr(choose_header("librpc/ndr/libndr.h", "ndr.h"));
+       if ($needed->{"compression"}) {
+               $self->pidl(choose_header("librpc/ndr/ndr_compression.h", "ndr/compression.h"));
+       }
 
        if (has_property($interface, "object")) {
                $self->pidl(choose_header("librpc/gen_ndr/ndr_orpc.h", "ndr/orpc.h"));
        }
 
        if (defined $interface->{PROPERTIES}->{helper}) {
-               $self->HeaderInclude(split / /, $interface->{PROPERTIES}->{helper});
+               $self->HeaderInclude(split /,/, $interface->{PROPERTIES}->{helper});
        }
 
        if (defined $interface->{PROPERTIES}->{uuid}) {
                my $name = uc $interface->{NAME};
-               $self->pidl_hdr("#define DCERPC_$name\_UUID " . 
+               $self->pidl_hdr("#define NDR_$name\_UUID " . 
                Parse::Pidl::Util::make_str(lc($interface->{PROPERTIES}->{uuid})));
 
                if(!defined $interface->{PROPERTIES}->{version}) { $interface->{PROPERTIES}->{version} = "0.0"; }
-               $self->pidl_hdr("#define DCERPC_$name\_VERSION $interface->{PROPERTIES}->{version}");
+               $self->pidl_hdr("#define NDR_$name\_VERSION $interface->{PROPERTIES}->{version}");
 
-               $self->pidl_hdr("#define DCERPC_$name\_NAME \"$interface->{NAME}\"");
+               $self->pidl_hdr("#define NDR_$name\_NAME \"$interface->{NAME}\"");
 
                if(!defined $interface->{PROPERTIES}->{helpstring}) { $interface->{PROPERTIES}->{helpstring} = "NULL"; }
-               $self->pidl_hdr("#define DCERPC_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}");
+               $self->pidl_hdr("#define NDR_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}");
 
-               $self->pidl_hdr("extern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};");
-               $self->pidl_hdr("NTSTATUS dcerpc_server_$interface->{NAME}_init(void);");
+               $self->pidl_hdr("extern const struct ndr_interface_table ndr_table_$interface->{NAME};");
        }
 
        foreach (@{$interface->{FUNCTIONS}}) {
@@ -2417,10 +2339,10 @@ sub HeaderInterface($$)
        
                my $val = sprintf("0x%02x", $count);
                if (defined($interface->{BASE})) {
-                       $val .= " + DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT";
+                       $val .= " + NDR_" . uc $interface->{BASE} . "_CALL_COUNT";
                }
                
-               $self->pidl_hdr("#define DCERPC_$u_name ($val)");
+               $self->pidl_hdr("#define NDR_$u_name ($val)");
 
                $self->pidl_hdr("");
                $count++;
@@ -2429,10 +2351,10 @@ sub HeaderInterface($$)
        my $val = $count;
 
        if (defined($interface->{BASE})) {
-               $val .= " + DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT";
+               $val .= " + NDR_" . uc $interface->{BASE} . "_CALL_COUNT";
        }
 
-       $self->pidl_hdr("#define DCERPC_" . uc $interface->{NAME} . "_CALL_COUNT ($val)");
+       $self->pidl_hdr("#define NDR_" . uc $interface->{NAME} . "_CALL_COUNT ($val)");
 
 }
 
@@ -2452,12 +2374,12 @@ sub ParseTypePushFunction($$$)
        my ($self, $e, $varname) = @_;
 
        my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "push", $e->{NAME}, $varname);
-       $self->fn_declare("push", $e, "NTSTATUS ".TypeFunctionName("ndr_push", $e)."(struct ndr_push *ndr, int ndr_flags, $args)") or return;
+       $self->fn_declare("push", $e, "enum ndr_err_code ".TypeFunctionName("ndr_push", $e)."(struct ndr_push *ndr, int ndr_flags, $args)") or return;
 
        $self->pidl("{");
        $self->indent;
        $self->ParseTypePush($e, $varname, 1, 1);
-       $self->pidl("return NT_STATUS_OK;");
+       $self->pidl("return NDR_ERR_SUCCESS;");
        $self->deindent;
        $self->pidl("}");
        $self->pidl("");;
@@ -2480,12 +2402,12 @@ sub ParseTypePullFunction($$)
 
        my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "pull", $e->{NAME}, $varname);
 
-       $self->fn_declare("pull", $e, "NTSTATUS ".TypeFunctionName("ndr_pull", $e)."(struct ndr_pull *ndr, int ndr_flags, $args)") or return;
+       $self->fn_declare("pull", $e, "enum ndr_err_code ".TypeFunctionName("ndr_pull", $e)."(struct ndr_pull *ndr, int ndr_flags, $args)") or return;
 
        $self->pidl("{");
        $self->indent;
        $self->ParseTypePull($e, $varname, 1, 1);
-       $self->pidl("return NT_STATUS_OK;");
+       $self->pidl("return NDR_ERR_SUCCESS;");
        $self->deindent;
        $self->pidl("}");
        $self->pidl("");
@@ -2545,14 +2467,12 @@ sub ParseInterface($$$)
 
        $self->pidl_hdr("");
 
-       if ($needed->{"compression"}) {
-               $self->pidl(choose_header("librpc/ndr/ndr_compression.h", "ndr/compression.h"));
-       }
-
-       $self->HeaderInterface($interface);
+       $self->HeaderInterface($interface, $needed);
 
        # Typedefs
        foreach my $d (@{$interface->{TYPES}}) {
+               next unless(typeHasBody($d));
+
                ($needed->{TypeFunctionName("ndr_push", $d)}) && $self->ParseTypePushFunction($d, "r");
                ($needed->{TypeFunctionName("ndr_pull", $d)}) && $self->ParseTypePullFunction($d, "r");
                ($needed->{TypeFunctionName("ndr_print", $d)}) && $self->ParseTypePrintFunction($d, "r");
@@ -2595,14 +2515,6 @@ sub GenerateIncludes($)
                $self->pidl("#include <stdarg.h>");
                $self->pidl("#include <string.h>");
        }
-
-       # Samba3 has everything in include/includes.h
-       if (is_intree() != 3) {
-               $self->pidl(choose_header("libcli/util/nterr.h", "core/nterr.h"));
-               $self->pidl(choose_header("librpc/gen_ndr/ndr_misc.h", "gen_ndr/ndr_misc.h"));
-               $self->pidl(choose_header("librpc/gen_ndr/ndr_dcerpc.h", "gen_ndr/ndr_dcerpc.h"));
-               $self->pidl(choose_header("librpc/rpc/dcerpc.h", "dcerpc.h")); #FIXME: This shouldn't be here!
-       }
 }
 
 #####################################################################
@@ -2613,6 +2525,7 @@ sub Parse($$$$)
 
        $self->pidl_hdr("/* header auto-generated by pidl */");
        $self->pidl_hdr("");
+       $self->pidl_hdr(choose_header("librpc/ndr/libndr.h", "ndr.h"));
        $self->pidl_hdr("#include \"$gen_header\"") if ($gen_header);
        $self->pidl_hdr("");
 
@@ -2703,6 +2616,7 @@ sub NeededType($$$)
        NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "TYPEDEF");
 
        if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "UNION") {
+               return unless defined($t->{ELEMENTS});
                for my $e (@{$t->{ELEMENTS}}) {
                        $e->{PARENT} = $t;
                        if (has_property($e, "compression")) { 
@@ -2740,7 +2654,7 @@ sub TypeFunctionName($$)
        my ($prefix, $t) = @_;
 
        return "$prefix\_$t->{NAME}" if (ref($t) eq "HASH" and 
-                       ($t->{TYPE} eq "TYPEDEF" or $t->{TYPE} eq "DECLARE"));
+                       $t->{TYPE} eq "TYPEDEF");
        return "$prefix\_$t->{TYPE}_$t->{NAME}" if (ref($t) eq "HASH");
        return "$prefix\_$t";
 }