pidl/python: Fix use of pointers.
authorJelmer Vernooij <jelmer@samba.org>
Sun, 13 Jan 2008 22:13:30 +0000 (23:13 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Mon, 14 Jan 2008 18:53:05 +0000 (19:53 +0100)
(This used to be commit 13f2b0380f310b101975d709361a29d4032c3689)

source4/pidl/lib/Parse/Pidl/Samba4/Python.pm
source4/torture/rpc/echo.py

index 93a6161ce496b7b25d790a27d1ac7de3890b9f5a..2d6ec50d391faa5e403c808d0c858bec9eabdc5b 100644 (file)
@@ -11,6 +11,7 @@ use Exporter;
 use strict;
 use Parse::Pidl::Typelist qw(hasType getType mapTypeName expandAlias);
 use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
 use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
 
 use vars qw($VERSION);
@@ -100,7 +101,7 @@ sub FromUnionToPythonFunction($$$)
                my $conv;
                
                if ($e->{NAME}) {
-                       $conv = $self->ConvertObjectToPython($e->{TYPE}, "$name->$e->{NAME}");
+                       $conv = $self->ConvertObjectToPython($e, "$name->$e->{NAME}");
                } else {
                        $conv = "Py_None";
                }
@@ -138,7 +139,7 @@ sub FromPythonToUnionFunction($$$$$)
                }
                $self->indent;
                if ($e->{NAME}) {
-                       $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;");
+                       $self->ConvertObjectFromPython($mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;");
                }
                $self->pidl("break;");
                $self->deindent;
@@ -174,7 +175,7 @@ sub PythonStruct($$$$)
                $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
                my $varname = "object->$e->{NAME}";
                $self->indent;
-               $self->pidl("return ".$self->ConvertObjectToPython($e->{TYPE}, $varname) . ";");
+               $self->pidl("return ".$self->ConvertObjectToPython($e, $varname) . ";");
                $self->deindent;
                $self->pidl("}");
        }
@@ -188,7 +189,7 @@ sub PythonStruct($$$$)
        $self->pidl("{");
        $self->indent;
        $self->pidl("$cname *object = py_talloc_get_type(py_obj, $cname);");
-       $self->pidl("TALLOC_CTX *mem_ctx = py_talloc_get_mem_ctx(py_obj);");
+       my $mem_ctx = "py_talloc_get_mem_ctx(py_obj)";
        foreach my $e (@{$d->{ELEMENTS}}) {
                $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
                my $varname = "object->$e->{NAME}";
@@ -196,7 +197,7 @@ sub PythonStruct($$$$)
                if ($e->{ORIGINAL}->{POINTERS} > 0) {
                        $self->pidl("talloc_free($varname);");
                }
-               $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname, "return -1;");
+               $self->ConvertObjectFromPython($mem_ctx, $e, "value", $varname, "return -1;");
                $self->pidl("return 0;");
                $self->deindent;
                $self->pidl("}");
@@ -270,7 +271,7 @@ sub PythonFunction($$$)
 
        foreach my $e (@{$fn->{ELEMENTS}}) {
                if (grep(/in/,@{$e->{DIRECTION}})) {
-                       $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;");
+                       $self->ConvertObjectFromPython("mem_ctx", $e, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;");
                }
        }
        $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);");
@@ -282,14 +283,14 @@ sub PythonFunction($$$)
 
        foreach my $e (@{$fn->{ELEMENTS}}) {
                if (grep(/out/,@{$e->{DIRECTION}})) {
-                       $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($e->{TYPE}, "r.out.$e->{NAME}") . ");");
+                       $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($e, "r.out.$e->{NAME}") . ");");
 
                        $i++;
                }
        }
 
        if (defined($fn->{RETURN_TYPE})) {
-               $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($fn->{RETURN_TYPE}, "r.out.result") . ");");
+               $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPythonData($fn->{RETURN_TYPE}, "r.out.result") . ");");
        }
 
        $self->pidl("talloc_free(mem_ctx);");
@@ -484,7 +485,7 @@ sub register_module_method($$$$$)
        push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc])
 }
 
-sub ConvertObjectFromPython($$$$$$)
+sub convertObjectFromPythonData($$$$$$)
 {
        my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_;
 
@@ -561,6 +562,36 @@ sub ConvertObjectFromPython($$$$$$)
        }
 
        die("unknown type ".mapTypeName($ctype) . ": $cvar");
+
+}
+
+sub ConvertObjectFromPythonLevel($$$$$$$)
+{
+       my ($self, $mem_ctx, $e, $l, $var_name, $target, $fail) = @_;
+
+       if ($l->{TYPE} eq "POINTER") {
+               $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), get_value_of($var_name), $target, $fail);
+       } elsif ($l->{TYPE} eq "ARRAY") {
+               $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), $var_name."[i]", $target, $fail);
+       } elsif ($l->{TYPE} eq "DATA") {
+               if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or 
+                       Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
+                       $var_name = get_pointer_to($var_name);
+               }
+               $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $target, $fail);
+       } elsif ($l->{TYPE} eq "SWITCH") {
+               $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), get_value_of($var_name), $target, $fail);
+       } else {
+               die("unknown level type $l->{TYPE}");
+       }
+}
+
+sub ConvertObjectFromPython($$$$$$)
+{
+       my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_;
+
+       $self->ConvertObjectFromPythonLevel($mem_ctx, $ctype, $ctype->{LEVELS}[0], 
+                                              $cvar, $target, $fail);
 }
 
 sub ConvertScalarToPython($$$)
@@ -601,7 +632,7 @@ sub ConvertScalarToPython($$$)
        die("Unknown scalar type $ctypename");
 }
 
-sub ConvertObjectToPython($$$)
+sub ConvertObjectToPythonData($$$)
 {
        my ($self, $ctype, $cvar) = @_;
 
@@ -648,6 +679,34 @@ sub ConvertObjectToPython($$$)
        die("unknown type ".mapTypeName($ctype) . ": $cvar");
 }
 
+sub ConvertObjectToPythonLevel($$$$)
+{
+       my ($self, $e, $l, $var_name) = @_;
+
+       if ($l->{TYPE} eq "POINTER") {
+               $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), get_value_of($var_name));
+       } elsif ($l->{TYPE} eq "ARRAY") {
+               $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), $var_name."[i]");
+       } elsif ($l->{TYPE} eq "SWITCH") {
+               $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), $var_name);
+       } elsif ($l->{TYPE} eq "DATA") {
+               if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or 
+                       Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
+                       $var_name = get_pointer_to($var_name);
+               }
+               $self->ConvertObjectToPythonData($l->{DATA_TYPE}, $var_name);
+       } else {
+               die("Unknown level type $l->{TYPE} $var_name");
+       }
+}
+
+sub ConvertObjectToPython($$$)
+{
+       my ($self, $ctype, $cvar) = @_;
+
+       $self->ConvertObjectToPythonLevel($ctype, $ctype->{LEVELS}[0], $cvar);
+}
+
 sub Parse($$$$$)
 {
     my($self,$basename,$ndr,$ndr_hdr,$hdr) = @_;
@@ -705,7 +764,7 @@ sub Parse($$$$$)
                } elsif ($cvar =~ /^".*"$/) {
                        $py_obj = "PyString_FromString($cvar)";
                } else {
-                       $py_obj = $self->ConvertObjectToPython($ctype, $cvar);
+                       $py_obj = $self->ConvertObjectToPythonData($ctype, $cvar);
                }
 
                $self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);");
index 7a0a54a1a1d0d3c242f5345d4e052bdbe6324a96..47b71c9e15bdc475092c059b208acad5d1441688 100644 (file)
@@ -35,5 +35,5 @@ class RpcEchoTests(unittest.TestCase):
 
     def test_surrounding(self):
         somearray = [1,2,3,4]
-        conn.TestSurrounding(echo.Surrounding(4, somearray))
-        self.assertEquals(8 * [0], somearray)
+        (y) = conn.TestSurrounding(echo.Surrounding(4, somearray)))
+        self.assertEquals(8 * [0], y.surrounding)