summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-01-13 18:05:43 +0100
committerJelmer Vernooij <jelmer@samba.org>2008-01-14 19:53:05 +0100
commitbe01d080247c70ec260763adc7711976c8ee19fc (patch)
tree6ed7f4fce3b7257d299770b2c08bc6da44920460
parent915f1589252be8cb9fb86eed479e328371e355e1 (diff)
downloadsamba-be01d080247c70ec260763adc7711976c8ee19fc.tar.gz
samba-be01d080247c70ec260763adc7711976c8ee19fc.tar.bz2
samba-be01d080247c70ec260763adc7711976c8ee19fc.zip
pidl/python: Work towards supporting more complex types (arrays, etc).
(This used to be commit 49d91a1a92e226c015db86ddc9ef772030415d76)
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba4/Python.pm191
1 files changed, 115 insertions, 76 deletions
diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 1c0cafc050..545d233d08 100644
--- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -97,7 +97,13 @@ sub FromUnionToPythonFunction($$$)
$self->indent;
foreach my $e (@{$type->{ELEMENTS}}) {
- my $conv = $self->ConvertObjectToPython($e->{TYPE}, "$name->$e->{NAME}");
+ my $conv;
+
+ if ($e->{NAME}) {
+ $conv = $self->ConvertObjectToPython($e->{TYPE}, "$name->$e->{NAME}");
+ } else {
+ $conv = "Py_None";
+ }
if (defined($e->{CASE})) {
$self->pidl("$e->{CASE}: return $conv;");
} else {
@@ -112,27 +118,46 @@ sub FromUnionToPythonFunction($$$)
$self->pidl("return NULL;");
}
-sub FromPythonToUnionFunction($$$$)
+sub FromPythonToUnionFunction($$$$$)
{
- my ($self, $type, $switch, $mem_ctx, $name) = @_;
+ my ($self, $type, $typename, $switch, $mem_ctx, $name) = @_;
+
+ my $has_default = 0;
+
+ $self->pidl("$typename *ret = talloc_zero($mem_ctx, $typename);");
$self->pidl("switch ($switch) {");
$self->indent;
foreach my $e (@{$type->{ELEMENTS}}) {
- my $conv = $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, "$name");
if (defined($e->{CASE})) {
- $self->pidl("$e->{CASE}: return $conv;");
+ $self->pidl("$e->{CASE}:");
} else {
- $self->pidl("default: return $conv;");
+ $has_default = 1;
+ $self->pidl("default:");
}
+ $self->indent;
+ if ($e->{NAME}) {
+ $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, $name, "ret->$e->{NAME}");
+ }
+ $self->pidl("break;");
+ $self->deindent;
+ $self->pidl("");
+ }
+
+ if (!$has_default) {
+ $self->pidl("default:");
+ $self->indent;
+ $self->pidl("PyErr_SetString(PyExc_TypeError, \"invalid union level value\");");
+ $self->pidl("talloc_free(ret);");
+ $self->pidl("ret = NULL;");
+ $self->deindent;
}
$self->deindent;
$self->pidl("}");
$self->pidl("");
- $self->pidl("PyErr_SetString(PyExc_TypeError, \"invalid union level value\");");
- $self->pidl("return NULL;");
+ $self->pidl("return ret;");
}
sub PythonStruct($$$$)
@@ -161,21 +186,22 @@ sub PythonStruct($$$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("static PyObject *py_$name\_setattr(PyObject *obj, char *name, PyObject *value)");
+ $self->pidl("static int py_$name\_setattr(PyObject *py_obj, char *name, PyObject *value)");
$self->pidl("{");
$self->indent;
- $self->pidl("$cname *object = py_talloc_get_type(py_object, $cname);");
+ $self->pidl("$cname *object = py_talloc_get_type(py_obj, $cname);");
foreach my $e (@{$d->{ELEMENTS}}) {
$self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {");
my $varname = "object->$e->{NAME}";
$self->indent;
$self->pidl("/* FIXME: talloc_free($varname) if necessary */");
- $self->pidl("$varname = " . $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value") . ";");
+ $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname);
+ $self->pidl("return 0;");
$self->deindent;
$self->pidl("}");
}
$self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");");
- $self->pidl("return NULL;");
+ $self->pidl("return -1;");
$self->deindent;
$self->pidl("}");
$self->pidl("");
@@ -238,7 +264,7 @@ sub PythonFunction($$$)
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/in/,@{$e->{DIRECTION}})) {
- $self->pidl("r.in.$e->{NAME} = " . $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}") . ";");
+ $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}", "r.in.$e->{NAME}");
}
}
$self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);");
@@ -303,7 +329,7 @@ sub PythonType($$$)
$fn_name =~ s/^$interface->{NAME}_//;
$fn_name =~ s/^$basename\_//;
- $self->register_module_method($fn_name, $py_fnname, "METH_VARARGS|METH_KEYWORDS", "NULL");
+ $self->register_module_method($fn_name, $py_fnname, "METH_NOARGS", "NULL");
}
if ($d->{TYPE} eq "ENUM" or $d->{TYPE} eq "BITMAP") {
@@ -315,7 +341,7 @@ sub PythonType($$$)
}
if ($actual_ctype->{TYPE} eq "UNION") {
- $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)");
+ $self->pidl("PyObject *py_import_$d->{NAME}(int level, " .mapTypeName($d) . " *in)");
$self->pidl("{");
$self->indent;
$self->FromUnionToPythonFunction($actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION");
@@ -323,10 +349,10 @@ sub PythonType($$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)");
+ $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, PyObject *in)");
$self->pidl("{");
$self->indent;
- $self->FromPythonToUnionFunction($actual_ctype, "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION");
+ $self->FromPythonToUnionFunction($actual_ctype, mapTypeName($d), "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION");
$self->deindent;
$self->pidl("}");
$self->pidl("");
@@ -452,9 +478,9 @@ sub register_module_method($$$$$)
push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc])
}
-sub ConvertObjectFromPython($$$$)
+sub ConvertObjectFromPython($$$$$)
{
- my ($self, $mem_ctx, $ctype, $cvar) = @_;
+ my ($self, $mem_ctx, $ctype, $cvar, $target) = @_;
die("undef type for $cvar") unless(defined($ctype));
@@ -463,7 +489,8 @@ sub ConvertObjectFromPython($$$$)
}
if (ref($ctype) ne "HASH") {
- return "FIXME($cvar)";
+ $self->pidl("$target = FIXME($cvar);");
+ return;
}
my $actual_ctype = $ctype;
@@ -474,64 +501,102 @@ sub ConvertObjectFromPython($$$$)
if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or
$actual_ctype->{TYPE} eq "SCALAR" and (
expandAlias($actual_ctype->{NAME}) =~ /^(u?int[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong|udlongr)$/)) {
- return "PyInt_AsLong($cvar)";
+ $self->pidl("$target = PyInt_AsLong($cvar);");
+ return;
}
if ($actual_ctype->{TYPE} eq "STRUCT") {
- return "py_talloc_get_type($cvar, " . mapTypeName($ctype) . ")";
+ $self->pidl("$target = py_talloc_get_type($cvar, " . mapTypeName($ctype) . ");");
+ return;
}
if ($actual_ctype->{TYPE} eq "UNION") {
- return "py_export_$ctype->{NAME}($cvar)";
+ $self->pidl("$target = py_export_$ctype->{NAME}($cvar);");
+ return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "DATA_BLOB") {
- return "data_blob_talloc($mem_ctx, PyString_AsString($cvar), PyString_Size($cvar))";
+ $self->pidl("$target = data_blob_talloc($mem_ctx, PyString_AsString($cvar), PyString_Size($cvar));");
+ return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and
($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) {
- return "talloc_strdup($mem_ctx, PyString_AsString($cvar))";
+ $self->pidl("$target = talloc_strdup($mem_ctx, PyString_AsString($cvar));");
+ return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") {
- return "FIXME($cvar)";
+ $self->pidl("$target = FIXME($cvar);");
+ return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
- return "PyInt_AsLong($cvar)";
+ $self->pidl("$target = PyInt_AsLong($cvar);");
+ return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") {
- return "PyInt_AsLong($cvar)";
+ $self->pidl("$target = PyInt_AsLong($cvar);");
+ return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") {
- return "FIXME($cvar)";
+ $self->pidl("$target = FIXME($cvar);");
+ return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") {
- return "PyCObject_AsVoidPtr($cvar)";
+ $self->pidl("$target = PyCObject_AsVoidPtr($cvar);");
+ return;
}
die("unknown type ".mapTypeName($ctype) . ": $cvar");
}
-sub ConvertObjectToPython($$$)
+sub ConvertScalarToPython($$$)
{
- my ($self, $ctype, $cvar) = @_;
+ my ($self, $ctypename, $cvar) = @_;
- if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) {
+ $ctypename = expandAlias($ctypename);
+
+ if ($ctypename =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) {
return "PyInt_FromLong($cvar)";
}
- die("undef type for $cvar") unless(defined($ctype));
+ if ($ctypename eq "DATA_BLOB") {
+ return "PyString_FromStringAndSize($cvar->data, $cvar->length)";
+ }
+
+ if ($ctypename eq "NTSTATUS") {
+ return "PyInt_FromLong(NT_STATUS_V($cvar))";
+ }
+
+ if ($ctypename eq "WERROR") {
+ return "PyInt_FromLong(W_ERROR_V($cvar))";
+ }
- if ($cvar =~ /^".*"$/) {
+ if (($ctypename eq "string" or $ctypename eq "nbt_string" or $ctypename eq "nbt_name" or $ctypename eq "wrepl_nbt_name")) {
return "PyString_FromString($cvar)";
}
+ if ($ctypename eq "string_array") { return "FIXME($cvar)"; }
+
+ if ($$ctypename eq "ipv4address") { return "FIXME($cvar)"; }
+ if ($ctypename eq "pointer") {
+ return "PyCObject_FromVoidPtr($cvar, talloc_free)";
+ }
+
+ die("Unknown scalar type $ctypename");
+}
+
+sub ConvertObjectToPython($$$)
+{
+ my ($self, $ctype, $cvar) = @_;
+
+ die("undef type for $cvar") unless(defined($ctype));
+
if (ref($ctype) ne "HASH") {
if (not hasType($ctype)) {
if (ref($ctype) eq "HASH") {
@@ -550,54 +615,19 @@ sub ConvertObjectToPython($$$)
}
if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or
- ($actual_ctype->{TYPE} eq "SCALAR" and
- expandAlias($actual_ctype->{NAME}) =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/)) {
- return "PyInt_FromLong($cvar)";
+ ($actual_ctype->{TYPE} eq "SCALAR") {
+ return $self->ConvertScalarToPython($actual_ctype->{NAME}, $cvar);
}
- if ($ctype->{TYPE} eq "TYPEDEF" and $actual_ctype->{TYPE} eq "UNION") {
+ if ($actual_ctype->{TYPE} eq "UNION") {
return "py_import_$ctype->{NAME}($cvar)";
}
- if ($ctype->{TYPE} eq "TYPEDEF" and $actual_ctype->{TYPE} eq "STRUCT") {
+ if ($actual_ctype->{TYPE} eq "STRUCT") {
# FIXME: if $cvar is not a pointer, do a talloc_dup()
return "py_talloc_import(&$ctype->{NAME}_ObjectType, $cvar)";
}
- if ($actual_ctype->{TYPE} eq "SCALAR" and
- expandAlias($actual_ctype->{NAME}) eq "DATA_BLOB") {
- return "PyString_FromStringAndSize($cvar->data, $cvar->length)";
- }
-
- if ($ctype->{TYPE} eq "STRUCT" or $ctype->{TYPE} eq "UNION") {
- return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)";
- }
-
- if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
- return "PyInt_FromLong(NT_STATUS_V($cvar))";
- }
-
- if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") {
- return "PyInt_FromLong(W_ERROR_V($cvar))";
- }
-
- if ($actual_ctype->{TYPE} eq "SCALAR" and
- ($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) {
- return "PyString_FromString($cvar)";
- }
-
- if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") {
- return "FIXME($cvar)";
- }
-
- if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") {
- return "FIXME($cvar)";
- }
-
- if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") {
- return "PyCObject_FromVoidPtr($cvar, talloc_free)";
- }
-
die("unknown type ".mapTypeName($ctype) . ": $cvar");
}
@@ -646,8 +676,17 @@ sub Parse($$$$$)
$self->pidl("PyObject *m;");
$self->pidl("m = Py_InitModule(\"$basename\", $basename\_methods);");
foreach (keys %{$self->{constants}}) {
- # FIXME: Handle non-string constants
- $self->pidl("PyModule_AddObject(m, \"$_\", " . $self->ConvertObjectToPython($self->{constants}->{$_}->[0], $self->{constants}->{$_}->[1]) . ");");
+ my $py_obj;
+ my ($ctype, $cvar) = @{$self->{constants}->{$_}};
+ if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) {
+ $py_obj = "PyInt_FromLong($cvar)";
+ } elsif ($cvar =~ /^".*"$/) {
+ $py_obj = "PyString_FromString($cvar)";
+ } else {
+ $py_obj = $self->ConvertScalarToPython($ctype, $cvar);
+ }
+
+ $self->pidl("PyModule_AddObject(m, \"$_\", $py_obj);");
}
$self->deindent;
$self->pidl("}");