Author: jelmer
Date: 2005-10-05 22:18:59 +0000 (Wed, 05 Oct 2005)
New Revision: 10742

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=10742

Log:
Support multi-level pointers + ref pointer fixes

Modified:
   branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/NDR.pm
   branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Client.pm
   branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Header.pm
   branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Parser.pm


Changeset:
Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/NDR.pm
===================================================================
--- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/NDR.pm        2005-10-05 
21:52:33 UTC (rev 10741)
+++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/NDR.pm        2005-10-05 
22:18:59 UTC (rev 10742)
@@ -80,6 +80,7 @@
        my @bracket_array = ();
        my @length_is = ();
        my @size_is = ();
+       my $pointer_idx = 0;
 
        if (has_property($e, "size_is")) {
                @size_is = split /,/, has_property($e, "size_is");
@@ -153,9 +154,12 @@
                        TYPE => "POINTER",
                        # for now, there can only be one pointer type per 
element
                        POINTER_TYPE => pointer_type($e),
+                       POINTER_INDEX => $pointer_idx,
                        IS_DEFERRED => "$is_deferred",
                        LEVEL => $level
                });
+
+               $pointer_idx++;
                
                # everything that follows will be deferred
                $is_deferred = 1 if ($e->{PARENT}->{TYPE} ne "FUNCTION");

Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Client.pm
===================================================================
--- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Client.pm      
2005-10-05 21:52:33 UTC (rev 10741)
+++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Client.pm      
2005-10-05 22:18:59 UTC (rev 10742)
@@ -20,7 +20,29 @@
 sub deindent() { $tabs = substr($tabs, 1); }
 sub pidl($) { $res .= $tabs.(shift)."\n"; }
 sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
+sub warning($$) { my ($e,$s) = @_; warn("$e->{FILE}:$e->{LINE}: $s\n"); }
 
+sub CopyLevel($$$$)
+{
+       sub CopyLevel($$$$);
+       my ($e,$l,$argument,$member) = @_;
+
+       if ($l->{TYPE} eq "DATA") {
+               pidl "*$argument = $member;";
+       } elsif ($l->{TYPE} eq "POINTER") {
+               pidl "if (r.ptr$l->{POINTER_INDEX}_$e->{NAME}) {";
+               indent;
+               pidl "*$argument = talloc_size(mem_ctx, sizeof(void *));";
+               CopyLevel($e,GetNextLevel($e,$l),"*$argument", $member);
+               deindent;
+               pidl "}";
+       } elsif ($l->{TYPE} eq "SWITCH") {
+               CopyLevel($e,GetNextLevel($e,$l),$argument,$member);    
+       } elsif ($l->{TYPE} eq "ARRAY") {
+               pidl "*$argument = $member;";
+       }
+}
+
 sub ParseFunction($$)
 {
        my ($if,$fn) = @_;
@@ -59,10 +81,14 @@
        pidl "\tNT_STATUS_UNSUCCESSFUL);";
        pidl "";
        pidl "/* Return variables */";
-       foreach (@{$fn->{ELEMENTS}}) {
-               next unless (grep(/out/, @{$_->{DIRECTION}}));
-
-               pidl "*$_->{NAME} = r.$_->{NAME};";
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               next unless (grep(/out/, @{$e->{DIRECTION}}));
+               
+               if ($e->{LEVELS}[0]->{TYPE} ne "POINTER") {
+                       warning($e->{ORIGINAL}, "First element not a pointer 
for [out] argument");
+                       next;
+               }
+               CopyLevel($e, $e->{LEVELS}[1], $e->{NAME}, "r.$e->{NAME}");
        }
 
        pidl"";

Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Header.pm
===================================================================
--- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Header.pm      
2005-10-05 21:52:33 UTC (rev 10741)
+++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Header.pm      
2005-10-05 22:18:59 UTC (rev 10742)
@@ -29,7 +29,7 @@
        foreach my $l (@{$e->{LEVELS}}) {
                if ($l->{TYPE} eq "POINTER") {
                        return if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} 
eq "top");
-                       pidl "\tuint32 ptr_$e->{NAME};";
+                       pidl "\tuint32 ptr$l->{POINTER_INDEX}_$e->{NAME};";
                } elsif ($l->{TYPE} eq "SWITCH") {
                        pidl "\tuint32 level_$e->{NAME};";
                } elsif ($l->{TYPE} eq "DATA") {
@@ -120,7 +120,7 @@
                                        $extra->{"length"} = $extra->{"offset"} 
= 1;
                                }
                        } elsif ($l->{TYPE} eq "POINTER") {
-                               $extra->{"ptr"} = 1;
+                               $extra->{"ptr$l->{POINTER_INDEX}"} = 1;
                        } elsif ($l->{TYPE} eq "SWITCH") {
                                $extra->{"level"} = 1;
                        }

Modified: branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Parser.pm
===================================================================
--- branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Parser.pm      
2005-10-05 21:52:33 UTC (rev 10741)
+++ branches/SAMBA_4_0/source/pidl/lib/Parse/Pidl/Samba3/Parser.pm      
2005-10-05 22:18:59 UTC (rev 10742)
@@ -158,14 +158,16 @@
        my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
 
        if ($what == PRIMITIVES) {
-               if ($l->{POINTER_TYPE} eq "ref" and 
-                       $l->{LEVEL} eq "TOP") {
-                       pidl "if (!" . ParseExpr("ptr_$e->{NAME}", $env) . ")";
+               if (($l->{POINTER_TYPE} eq "ref") and ($l->{LEVEL} eq 
"EMBEDDED")) {
+                       # Ref pointers always have to be non-NULL
+                       pidl "if (MARSHALLING(ps) && !" . 
ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . ")";
                        pidl "\treturn False;";
                        pidl "";
-               } else {
+               } 
+               
+               unless ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP") {
                        Align($align, 4);
-                       pidl "if (!prs_uint32(\"ptr_$e->{NAME}\", ps, depth, &" 
. ParseExpr("ptr_$e->{NAME}", $env) . "))";
+                       pidl "if 
(!prs_uint32(\"ptr$l->{POINTER_INDEX}_$e->{NAME}\", ps, depth, &" . 
ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . "))";
                        pidl "\treturn False;";
                        pidl "";
                }
@@ -177,12 +179,16 @@
        }
        
        if ($what == DEFERRED) {
-               pidl "if (" . ParseExpr("ptr_$e->{NAME}", $env) . ") {";
-               indent;
+               if ($l->{POINTER_TYPE} ne "ref") {
+                       pidl "if (" . 
ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . ") {";
+                       indent;
+               }
                ParseElementLevel($e,$nl,$env,$varname,PRIMITIVES,$align);
                ParseElementLevel($e,$nl,$env,$varname,DEFERRED,$align);
-               deindent;
-               pidl "}";
+               if ($l->{POINTER_TYPE} ne "ref") {
+                       deindent;
+                       pidl "}";
+               }
                $$align = 0;
        }
 }
@@ -221,14 +227,24 @@
        my ($e,$l,$varname,$env) = @_;
 
        if ($l->{TYPE} eq "POINTER") {
-               pidl "if ($varname) {";
-               indent;
-               pidl ParseExpr("ptr_$e->{NAME}", $env) . " = 1;";
+               if ($l->{POINTER_TYPE} eq "ref") {
+                       pidl "if (!$varname)";
+                       pidl "\treturn False;";
+                       pidl "";
+               } else {
+                       pidl "if ($varname) {";
+                       indent;
+               }
+
+               pidl ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 
1;";
                InitLevel($e, GetNextLevel($e,$l), "*$varname", $env);
-               deindent;
-               pidl "} else {";
-               pidl "\t" . ParseExpr("ptr_$e->{NAME}", $env) . " = 0;";
-               pidl "}";
+               
+               if ($l->{POINTER_TYPE} ne "ref") {
+                       deindent;
+                       pidl "} else {";
+                       pidl "\t" . 
ParseExpr("ptr$l->{POINTER_INDEX}_$e->{NAME}", $env) . " = 0;";
+                       pidl "}";
+               }
        } elsif ($l->{TYPE} eq "ARRAY") {
                pidl ParseExpr($e->{NAME}, $env) . " = $varname;";
        } elsif ($l->{TYPE} eq "DATA") {
@@ -245,7 +261,7 @@
                if ($l->{TYPE} eq "DATA") {
                        $env->{$e->{NAME}} = "v->$e->{NAME}";
                } elsif ($l->{TYPE} eq "POINTER") {
-                       $env->{"ptr_$e->{NAME}"} = "v->ptr_$e->{NAME}";
+                       $env->{"ptr$l->{POINTER_INDEX}_$e->{NAME}"} = 
"v->ptr$l->{POINTER_INDEX}_$e->{NAME}";
                } elsif ($l->{TYPE} eq "SWITCH") {
                        $env->{"level_$e->{NAME}"} = "v->level_$e->{NAME}";
                } elsif ($l->{TYPE} eq "ARRAY") {
@@ -350,7 +366,7 @@
                if ($l->{TYPE} eq "DATA") {
                        $env->{$e->{NAME}} = "v->u.$e->{NAME}";
                } elsif ($l->{TYPE} eq "POINTER") {
-                       $env->{"ptr_$e->{NAME}"} = "v->ptr";
+                       $env->{"ptr$l->{POINTER_INDEX}_$e->{NAME}"} = 
"v->ptr$l->{POINTER_INDEX}";
                } elsif ($l->{TYPE} eq "SWITCH") {
                        $env->{"level_$e->{NAME}"} = "v->level";
                } elsif ($l->{TYPE} eq "ARRAY") {
@@ -480,7 +496,7 @@
        pidl "prs_debug(ps, depth, desc, \"$fn\");";
        pidl "depth++;";
 
-       my $align = 0;
+       my $align = 8;
        foreach (@$es) {
                ParseElement($_, $env, PRIMITIVES, \$align); 
                ParseElement($_, $env, DEFERRED, \$align); 

Reply via email to