$self->pidl("PyObject *allow_remaining_obj = NULL;");
$self->pidl("bool allow_remaining = false;");
$self->pidl("");
- $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s#|O:__ndr_unpack__\",");
+ $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|O:__ndr_unpack__\",");
$self->indent;
$self->pidl("discard_const_p(char *, kwnames),");
$self->pidl("&blob.data, &blob_length,");
$self->pidl("DATA_BLOB blob;");
$self->pidl("enum ndr_err_code err;");
$self->pidl("");
- $self->pidl("if (ndr_table_$iface\.num_calls < $fn->{OPNUM}) {");
+ $self->pidl("if (ndr_table_$iface\.num_calls < " . ($fn->{OPNUM}+1) .
+ ") {");
$self->indent;
$self->pidl("PyErr_SetString(PyExc_TypeError, \"Internal Error, ndr_interface_call missing for py_$name\_ndr_pack\");");
$self->pidl("return NULL;");
$self->pidl("struct ndr_pull *pull = NULL;");
$self->pidl("enum ndr_err_code err;");
$self->pidl("");
- $self->pidl("if (ndr_table_$iface\.num_calls < $fn->{OPNUM}) {");
+ $self->pidl("if (ndr_table_$iface\.num_calls < " . ($fn->{OPNUM}+1) .
+ ") {");
$self->indent;
$self->pidl("PyErr_SetString(PyExc_TypeError, \"Internal Error, ndr_interface_call missing for py_$name\_ndr_unpack\");");
$self->pidl("return NULL;");
$self->pidl("PyObject *allow_remaining_obj = NULL;");
$self->pidl("bool allow_remaining = false;");
$self->pidl("");
- $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s#|OOO:__ndr_unpack_in__\",");
+ $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|OOO:__ndr_unpack_in__\",");
$self->indent;
$self->pidl("discard_const_p(char *, kwnames),");
$self->pidl("&blob.data, &blob_length,");
$self->pidl("PyObject *allow_remaining_obj = NULL;");
$self->pidl("bool allow_remaining = false;");
$self->pidl("");
- $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s#|OOO:__ndr_unpack_out__\",");
+ $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|OOO:__ndr_unpack_out__\",");
$self->indent;
$self->pidl("discard_const_p(char *, kwnames),");
$self->pidl("&blob.data, &blob_length,");
$self->pidl("PyObject *ret;");
$self->pidl("char *retstr;");
$self->pidl("");
- $self->pidl("if (ndr_table_$iface\.num_calls < $fn->{OPNUM}) {");
+ $self->pidl("if (ndr_table_$iface\.num_calls < " . ($fn->{OPNUM}+1) .
+ ") {");
$self->indent;
$self->pidl("PyErr_SetString(PyExc_TypeError, \"Internal Error, ndr_interface_call missing for py_$name\_ndr_print\");");
$self->pidl("return NULL;");
$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_obj2)");
$self->pidl("{");
$self->indent;
$self->pidl("return py_$name\_ndr_print(py_obj, \"$name\_in\", NDR_IN);");
$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_obj2)");
$self->pidl("{");
$self->indent;
$self->pidl("return py_$name\_ndr_print(py_obj, \"$name\_out\", NDR_OUT);");
$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->pidl("if (test_var < 0 || (unsigned long long)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);");
$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;
$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;
} 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);");
+ }
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("}");
}
}
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) {");
$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);
$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("");
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("");
}
$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("");
}
foreach (@{$self->{ready_types}}) {
$self->pidl("if (PyType_Ready($_) < 0)");
- $self->pidl("\treturn NULL;");
+ $self->pidl("\tgoto out;");
}
$self->pidl($_) foreach (@{$self->{postreadycode}});
$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);
$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;