e50c9378862c1f83084c69bf1d3c4773fdafb7dd
[gd/samba-autobuild/.git] / pidl / lib / Parse / Pidl / Samba4 / Python.pm
1 ###################################################
2 # Python function wrapper generator
3 # Copyright jelmer@samba.org 2007-2008
4 # released under the GNU GPL
5
6 package Parse::Pidl::Samba4::Python;
7
8 use Exporter;
9 @ISA = qw(Exporter);
10
11 use strict;
12 use Parse::Pidl qw(warning fatal error);
13 use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias bitmap_type_fn enum_type_fn);
14 use Parse::Pidl::Util qw(has_property ParseExpr unmake_str);
15 use Parse::Pidl::NDR qw(ReturnTypeElement GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
16 use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
17 use Parse::Pidl::Samba4 qw(ArrayDynamicallyAllocated);
18 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
19
20 use vars qw($VERSION);
21 $VERSION = '0.01';
22
23 sub new($) {
24         my ($class) = @_;
25         my $self = { res => "", res_hdr => "", tabs => "",
26                                  constants => [], constants_uniq => {},
27                                  module_methods => [],
28                                  module_objects => [], module_objects_uniq => {},
29                                  ready_types => [],
30                                  module_imports => [], module_imports_uniq => {},
31                                  type_imports => [], type_imports_uniq => {},
32                                  patch_type_calls => [], prereadycode => [],
33                                  postreadycode => []};
34         bless($self, $class);
35 }
36
37 sub pidl_hdr ($$)
38 {
39         my $self = shift;
40         $self->{res_hdr} .= shift;
41 }
42
43 sub pidl($$)
44 {
45         my ($self, $d) = @_;
46         if ($d) {
47                 if ((!($d =~ /^#/))) {
48                         $self->{res} .= $self->{tabs};
49                 }
50                 $self->{res} .= $d;
51         }
52         $self->{res} .= "\n";
53 }
54
55 sub indent($)
56 {
57         my ($self) = @_;
58         $self->{tabs} .= "\t";
59 }
60
61 sub deindent($)
62 {
63         my ($self) = @_;
64         $self->{tabs} = substr($self->{tabs}, 0, -1);
65 }
66
67 sub PrettifyTypeName($$)
68 {
69         my ($name, $basename) = @_;
70
71         $basename =~ s/^.*\.([^.]+)$/\1/;
72
73         $name =~ s/^$basename\_//;
74
75
76         return $name;
77 }
78
79 sub Import
80 {
81         my $self = shift;
82         my @imports = @_;
83         foreach (@imports) {
84                 $_ = unmake_str($_);
85                 s/\.idl$//;
86                 $self->pidl_hdr("#include \"librpc/gen_ndr/$_\.h\"\n");
87                 $self->register_module_import("samba.dcerpc.$_");
88         }
89 }
90
91 sub Const($$)
92 {
93     my ($self, $const) = @_;
94         $self->register_constant($const->{NAME}, $const->{DTYPE}, $const->{VALUE});
95 }
96
97 sub register_constant($$$$)
98 {
99         my ($self, $name, $type, $value) = @_;
100
101         unless (defined $self->{constants_uniq}->{$name}) {
102                 my $h = {"key" => $name, "val" => [$type, $value]};
103                 push @{$self->{constants}}, $h;
104                 $self->{constants_uniq}->{$name} = $h;
105         }
106 }
107
108 sub EnumAndBitmapConsts($$$)
109 {
110         my ($self, $name, $d) = @_;
111
112         return unless (defined($d->{ELEMENTS}));
113
114         foreach my $e (@{$d->{ELEMENTS}}) {
115                 $e =~ /^([A-Za-z0-9_]+)/;
116                 my $cname = $1;
117
118                 $self->register_constant($cname, $d, $cname);
119         }
120 }
121
122 sub FromUnionToPythonFunction($$$$)
123 {
124         my ($self, $mem_ctx, $type, $switch, $name) = @_;
125
126         $self->pidl("PyObject *ret;");
127         $self->pidl("");
128
129         $self->pidl("switch ($switch) {");
130         $self->indent;
131
132         foreach my $e (@{$type->{ELEMENTS}}) {
133                 $self->pidl("$e->{CASE}:");
134
135                 $self->indent;
136
137                 if ($e->{NAME}) {
138                         $self->ConvertObjectToPython($mem_ctx, {}, $e, "$name->$e->{NAME}", "ret", "return NULL;");
139                 } else {
140                         $self->pidl("ret = Py_None;");
141                         $self->pidl("Py_INCREF(ret);");
142                 }
143
144                 $self->pidl("return ret;");
145                 $self->pidl("");
146
147                 $self->deindent;
148         }
149
150         $self->deindent;
151         $self->pidl("}");
152
153         $self->pidl("PyErr_SetString(PyExc_TypeError, \"unknown union level\");");
154         $self->pidl("return NULL;");
155 }
156
157 sub FromPythonToUnionFunction($$$$$)
158 {
159         my ($self, $type, $typename, $switch, $mem_ctx, $name) = @_;
160
161         my $has_default = 0;
162
163         $self->pidl("$typename *ret = talloc_zero($mem_ctx, $typename);");
164
165         $self->pidl("switch ($switch) {");
166         $self->indent;
167
168         foreach my $e (@{$type->{ELEMENTS}}) {
169                 $self->pidl("$e->{CASE}:");
170                 if ($e->{CASE} eq "default") { $has_default = 1; }
171                 $self->indent;
172                 if ($e->{NAME}) {
173                         $self->ConvertObjectFromPython({}, $mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;");
174                 }
175                 $self->pidl("break;");
176                 $self->deindent;
177                 $self->pidl("");
178         }
179
180         if (!$has_default) {
181                 $self->pidl("default:");
182                 $self->indent;
183                 $self->pidl("PyErr_SetString(PyExc_TypeError, \"invalid union level value\");");
184                 $self->pidl("talloc_free(ret);");
185                 $self->pidl("ret = NULL;");
186                 $self->deindent;
187         }
188
189         $self->deindent;
190         $self->pidl("}");
191         $self->pidl("");
192         $self->pidl("return ret;");
193 }
194
195 sub PythonElementGetSet($$$$$$) {
196         my ($self, $name, $cname, $ename, $e, $env) = @_;
197
198         my $varname = "object->$ename";
199         $self->pidl("static PyObject *py_$name\_get_$e->{NAME}(PyObject *obj, void *closure)");
200         $self->pidl("{");
201         $self->indent;
202         $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(obj);");
203         $self->pidl("PyObject *py_$e->{NAME};");
204         $self->ConvertObjectToPython("pytalloc_get_mem_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}", "return NULL;");
205         $self->pidl("return py_$e->{NAME};");
206         $self->deindent;
207         $self->pidl("}");
208         $self->pidl("");
209
210         $self->pidl("static int py_$name\_set_$e->{NAME}(PyObject *py_obj, PyObject *value, void *closure)");
211         $self->pidl("{");
212         $self->indent;
213         $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
214         my $mem_ctx = "pytalloc_get_mem_ctx(py_obj)";
215         my $l = $e->{LEVELS}[0];
216         my $nl = GetNextLevel($e, $l);
217         if ($l->{TYPE} eq "POINTER" and
218                 not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and
219                 not ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE}))) {
220                 $self->pidl("talloc_unlink($mem_ctx, discard_const($varname));");
221         }
222         $self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;");
223         $self->pidl("return 0;");
224         $self->deindent;
225         $self->pidl("}");
226         $self->pidl("");
227 }
228
229 sub PythonStruct($$$$$$)
230 {
231         my ($self, $modulename, $prettyname, $name, $cname, $d) = @_;
232
233         my $env = GenerateStructEnv($d, "object");
234
235         $self->pidl("");
236
237         my $getsetters = "NULL";
238
239         if ($#{$d->{ELEMENTS}} > -1) {
240                 foreach my $e (@{$d->{ELEMENTS}}) {
241                         $self->PythonElementGetSet($name, $cname, $e->{NAME}, $e, $env);
242                 }
243
244                 $getsetters = "py_$name\_getsetters";
245                 $self->pidl("static PyGetSetDef ".$getsetters."[] = {");
246                 $self->indent;
247                 foreach my $e (@{$d->{ELEMENTS}}) {
248                         my $etype = "";
249                         if (ref($e->{TYPE}) eq "HASH") {
250                                 $etype = $e->{TYPE}->{NAME};
251                         } else {
252                                 $etype = $e->{TYPE};
253                         }
254                         $self->pidl("{");
255                         $self->indent;
256                         $self->pidl(".name = discard_const_p(char, \"$e->{NAME}\"),");
257                         $self->pidl(".get = py_$name\_get_$e->{NAME},");
258                         $self->pidl(".set = py_$name\_set_$e->{NAME},");
259                         $self->pidl(".doc = discard_const_p(char, \"PIDL-generated element of base type $etype\")");
260                         $self->deindent;
261                         $self->pidl("},");
262                 }
263                 $self->pidl("{ .name = NULL }");
264                 $self->deindent;
265                 $self->pidl("};");
266                 $self->pidl("");
267         }
268
269         $self->pidl("static PyObject *py_$name\_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
270         $self->pidl("{");
271         $self->indent;
272         $self->pidl("return pytalloc_new($cname, type);");
273         $self->deindent;
274         $self->pidl("}");
275         $self->pidl("");
276
277         my $py_methods = "NULL";
278
279         # If the struct is not public there ndr_pull/ndr_push functions will
280         # be static so not callable from here
281         if (has_property($d, "public")) {
282                 $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj,  PyObject *Py_UNUSED(ignored))");
283                 $self->pidl("{");
284                 $self->indent;
285                 $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
286                 $self->pidl("PyObject *ret = NULL;");
287                 $self->pidl("DATA_BLOB blob;");
288                 $self->pidl("enum ndr_err_code err;");
289                 $self->pidl("TALLOC_CTX *tmp_ctx = talloc_new(pytalloc_get_mem_ctx(py_obj));");
290                 $self->pidl("if (tmp_ctx == NULL) {");
291                 $self->indent;
292                 $self->pidl("PyErr_SetNdrError(NDR_ERR_ALLOC);");
293                 $self->pidl("return NULL;");
294                 $self->deindent;
295                 $self->pidl("}");
296                 $self->pidl("err = ndr_push_struct_blob(&blob, tmp_ctx, object, (ndr_push_flags_fn_t)ndr_push_$name);");
297                 $self->pidl("if (!NDR_ERR_CODE_IS_SUCCESS(err)) {");
298                 $self->indent;
299                 $self->pidl("TALLOC_FREE(tmp_ctx);");
300                 $self->pidl("PyErr_SetNdrError(err);");
301                 $self->pidl("return NULL;");
302                 $self->deindent;
303                 $self->pidl("}");
304                 $self->pidl("");
305                 $self->pidl("ret = PyBytes_FromStringAndSize((char *)blob.data, blob.length);");
306                 $self->pidl("TALLOC_FREE(tmp_ctx);");
307                 $self->pidl("return ret;");
308                 $self->deindent;
309                 $self->pidl("}");
310                 $self->pidl("");
311
312                 $self->pidl("static PyObject *py_$name\_ndr_unpack(PyObject *py_obj, PyObject *args, PyObject *kwargs)");
313                 $self->pidl("{");
314                 $self->indent;
315                 $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
316                 $self->pidl("DATA_BLOB blob = {.data = NULL, .length = 0};");
317                 $self->pidl("Py_ssize_t blob_length = 0;");
318                 $self->pidl("enum ndr_err_code err;");
319                 $self->pidl("const char * const kwnames[] = { \"data_blob\", \"allow_remaining\", NULL };");
320                 $self->pidl("PyObject *allow_remaining_obj = NULL;");
321                 $self->pidl("bool allow_remaining = false;");
322                 $self->pidl("");
323                 $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|O:__ndr_unpack__\",");
324                 $self->indent;
325                 $self->pidl("discard_const_p(char *, kwnames),");
326                 $self->pidl("&blob.data, &blob_length,");
327                 $self->pidl("&allow_remaining_obj)) {");
328                 $self->deindent;
329                 $self->indent;
330                 $self->pidl("return NULL;");
331                 $self->deindent;
332                 $self->pidl("}");
333                 $self->pidl("blob.length = blob_length;");
334                 $self->pidl("");
335                 $self->pidl("if (allow_remaining_obj && PyObject_IsTrue(allow_remaining_obj)) {");
336                 $self->indent;
337                 $self->pidl("allow_remaining = true;");
338                 $self->deindent;
339                 $self->pidl("}");
340                 $self->pidl("");
341                 $self->pidl("if (allow_remaining) {");
342                 $self->indent;
343                 $self->pidl("err = ndr_pull_struct_blob(&blob, pytalloc_get_mem_ctx(py_obj), object, (ndr_pull_flags_fn_t)ndr_pull_$name);");
344                 $self->deindent;
345                 $self->pidl("} else {");
346                 $self->indent;
347                 $self->pidl("err = ndr_pull_struct_blob_all(&blob, pytalloc_get_mem_ctx(py_obj), object, (ndr_pull_flags_fn_t)ndr_pull_$name);");
348                 $self->deindent;
349                 $self->pidl("}");
350                 $self->pidl("if (!NDR_ERR_CODE_IS_SUCCESS(err)) {");
351                 $self->indent;
352                 $self->pidl("PyErr_SetNdrError(err);");
353                 $self->pidl("return NULL;");
354                 $self->deindent;
355                 $self->pidl("}");
356                 $self->pidl("");
357                 $self->pidl("Py_RETURN_NONE;");
358                 $self->deindent;
359                 $self->pidl("}");
360                 $self->pidl("");
361
362                 $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
363                 $self->pidl("{");
364                 $self->indent;
365                 $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
366                 $self->pidl("PyObject *ret;");
367                 $self->pidl("char *retstr;");
368                 $self->pidl("");
369                 $self->pidl("retstr = ndr_print_struct_string(pytalloc_get_mem_ctx(py_obj), (ndr_print_fn_t)ndr_print_$name, \"$name\", object);");
370                 $self->pidl("ret = PyUnicode_FromString(retstr);");
371                 $self->pidl("talloc_free(retstr);");
372                 $self->pidl("");
373                 $self->pidl("return ret;");
374                 $self->deindent;
375                 $self->pidl("}");
376                 $self->pidl("");
377
378                 $py_methods = "py_$name\_methods";
379                 $self->pidl("static PyMethodDef $py_methods\[] = {");
380                 $self->indent;
381                 $self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.ndr_pack(object) -> blob\\nNDR pack\" },");
382                 $self->pidl("{ \"__ndr_unpack__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack), METH_VARARGS|METH_KEYWORDS, \"S.ndr_unpack(class, blob, allow_remaining=False) -> None\\nNDR unpack\" },");
383                 $self->pidl("{ \"__ndr_print__\", (PyCFunction)py_$name\_ndr_print, METH_NOARGS, \"S.ndr_print(object) -> None\\nNDR print\" },");
384                 $self->pidl("{ NULL, NULL, 0, NULL }");
385                 $self->deindent;
386                 $self->pidl("};");
387                 $self->pidl("");
388         }
389
390         $self->pidl_hdr("static PyTypeObject $name\_Type;\n");
391         $self->pidl("");
392         my $docstring = $self->DocString($d, $name);
393         my $typeobject = "$name\_Type";
394         $self->pidl("static PyTypeObject $typeobject = {");
395         $self->indent;
396         $self->pidl("PyVarObject_HEAD_INIT(NULL, 0)");
397         $self->pidl(".tp_name = \"$modulename.$prettyname\",");
398         $self->pidl(".tp_getset = $getsetters,");
399         if ($docstring) {
400                 $self->pidl(".tp_doc = $docstring,");
401         }
402         $self->pidl(".tp_methods = $py_methods,");
403         $self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,");
404         $self->pidl(".tp_new = py_$name\_new,");
405         $self->deindent;
406         $self->pidl("};");
407
408         $self->pidl("");
409
410         my $talloc_typename = $self->import_type_variable("talloc", "BaseObject");
411         $self->register_module_prereadycode(["$name\_Type.tp_base = $talloc_typename;",
412                                              "$name\_Type.tp_basicsize = pytalloc_BaseObject_size();",
413                                              ""]);
414
415         return "&$typeobject";
416 }
417
418 sub PythonFunctionStruct($$$$)
419 {
420         my ($self, $modulename, $fn, $iface, $prettyname) = @_;
421
422         my $inenv = GenerateFunctionInEnv($fn, "object->");
423         my $outenv = GenerateFunctionOutEnv($fn, "object->");
424
425         my $name = "$fn->{NAME}";
426         my $cname = "struct $name";
427
428         $self->pidl("");
429
430         my $getsetters = "NULL";
431
432         foreach my $e (@{$fn->{ELEMENTS}}) {
433                 if (grep(/in/,@{$e->{DIRECTION}})) {
434                         my $inname = "$name\_in";
435                         my $ename = "in.$e->{NAME}";
436                         $self->PythonElementGetSet($inname, $cname, $ename, $e, $inenv);
437                 }
438                 if (grep(/out/,@{$e->{DIRECTION}})) {
439                         my $outname = "$name\_out";
440                         my $ename = "out.$e->{NAME}";
441                         $self->PythonElementGetSet($outname, $cname, $ename, $e, $outenv);
442                 }
443         }
444
445         if (defined($fn->{RETURN_TYPE})) {
446                 my $e = ReturnTypeElement($fn);
447                 my $ename = "out.result";
448                 $self->PythonElementGetSet($name, $cname, $ename, $e, $outenv);
449         }
450
451         $getsetters = "py_$name\_getsetters";
452         $self->pidl("static PyGetSetDef ".$getsetters."[] = {");
453         $self->indent;
454         foreach my $e (@{$fn->{ELEMENTS}}) {
455                 if (grep(/in/,@{$e->{DIRECTION}})) {
456                         $self->pidl("{");
457                         $self->indent;
458                         $self->pidl(".name = discard_const_p(char, \"in_$e->{NAME}\"),");
459                         $self->pidl(".get = py_$name\_in_get_$e->{NAME},");
460                         $self->pidl(".set = py_$name\_in_set_$e->{NAME},");
461                         $self->pidl(".doc = discard_const_p(char, \"PIDL-generated element of base type $e->{TYPE}\")");
462                         $self->deindent;
463                         $self->pidl("},");
464                 }
465                 if (grep(/out/,@{$e->{DIRECTION}})) {
466                         $self->pidl("{");
467                         $self->indent;
468                         $self->pidl(".name = discard_const_p(char, \"out_$e->{NAME}\"),");
469                         $self->pidl(".get = py_$name\_out_get_$e->{NAME},");
470                         $self->pidl(".set = py_$name\_out_set_$e->{NAME},");
471                         $self->pidl(".doc = discard_const_p(char, \"PIDL-generated element of base type $e->{TYPE}\")");
472                         $self->deindent;
473                         $self->pidl("},");
474                 }
475         }
476         if (defined($fn->{RETURN_TYPE})) {
477                 $self->pidl("{");
478                 $self->indent;
479                 $self->pidl(".name = discard_const_p(char, \"result\"),");
480                 $self->pidl(".get = py_$name\_get_result,");
481                 $self->pidl(".set = py_$name\_set_result,");
482                 $self->pidl(".doc = discard_const_p(char, \"PIDL-generated element of type $fn->{RETURN_TYPE}\")");
483                 $self->deindent;
484                 $self->pidl("},");
485         }
486         $self->pidl("{ .name = NULL }");
487         $self->deindent;
488         $self->pidl("};");
489         $self->pidl("");
490
491         $self->pidl("static PyObject *py_$name\_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
492         $self->pidl("{");
493         $self->indent;
494         $self->pidl("return pytalloc_new($cname, type);");
495         $self->deindent;
496         $self->pidl("}");
497         $self->pidl("");
498
499         my $py_methods = "NULL";
500
501         my $ndr_call = "const struct ndr_interface_call *call = NULL;";
502         my $object_ptr = "$cname *object = ($cname *)pytalloc_get_ptr(py_obj);";
503
504         $self->pidl("static PyObject *py_$name\_ndr_opnum(PyTypeObject *type, PyObject *Py_UNUSED(ignored))");
505         $self->pidl("{");
506         $self->indent;
507         $self->pidl("");
508         $self->pidl("");
509         $self->pidl("return PyInt_FromLong($fn->{OPNUM});");
510         $self->deindent;
511         $self->pidl("}");
512         $self->pidl("");
513
514         $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj, int ndr_inout_flags, uint32_t ndr_push_flags)");
515         $self->pidl("{");
516         $self->indent;
517         $self->pidl("$ndr_call");
518         $self->pidl("$object_ptr");
519         $self->pidl("PyObject *ret = NULL;");
520         $self->pidl("struct ndr_push *push = NULL;");
521         $self->pidl("DATA_BLOB blob;");
522         $self->pidl("enum ndr_err_code err;");
523         $self->pidl("");
524         $self->pidl("if (ndr_table_$iface\.num_calls < " . ($fn->{OPNUM}+1) .
525                     ") {");
526         $self->indent;
527         $self->pidl("PyErr_SetString(PyExc_TypeError, \"Internal Error, ndr_interface_call missing for py_$name\_ndr_pack\");");
528         $self->pidl("return NULL;");
529         $self->deindent;
530         $self->pidl("}");
531         $self->pidl("call = &ndr_table_$iface\.calls[$fn->{OPNUM}];");
532         $self->pidl("");
533         $self->pidl("push = ndr_push_init_ctx(pytalloc_get_mem_ctx(py_obj));");
534         $self->pidl("if (push == NULL) {");
535         $self->indent;
536         $self->pidl("PyErr_SetNdrError(NDR_ERR_ALLOC);");
537         $self->pidl("return NULL;");
538         $self->deindent;
539         $self->pidl("}");
540         $self->pidl("");
541         $self->pidl("push->flags |= ndr_push_flags;");
542         $self->pidl("");
543         $self->pidl("err = call->ndr_push(push, ndr_inout_flags, object);");
544         $self->pidl("if (!NDR_ERR_CODE_IS_SUCCESS(err)) {");
545         $self->indent;
546         $self->pidl("TALLOC_FREE(push);");
547         $self->pidl("PyErr_SetNdrError(err);");
548         $self->pidl("return NULL;");
549         $self->deindent;
550         $self->pidl("}");
551         $self->pidl("blob = ndr_push_blob(push);");
552         $self->pidl("ret = PyBytes_FromStringAndSize((char *)blob.data, blob.length);");
553         $self->pidl("TALLOC_FREE(push);");
554         $self->pidl("return ret;");
555         $self->deindent;
556         $self->pidl("}");
557         $self->pidl("");
558
559         $self->pidl("static PyObject *py_$name\_ndr_pack_in(PyObject *py_obj, PyObject *args, PyObject *kwargs)");
560         $self->pidl("{");
561         $self->indent;
562         $self->pidl("const char * const kwnames[] = { \"bigendian\", \"ndr64\", NULL };");
563         $self->pidl("PyObject *bigendian_obj = NULL;");
564         $self->pidl("PyObject *ndr64_obj = NULL;");
565         $self->pidl("uint32_t ndr_push_flags = 0;");
566         $self->pidl("");
567         $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"|OO:__ndr_pack_in__\",");
568         $self->indent;
569         $self->pidl("discard_const_p(char *, kwnames),");
570         $self->pidl("&bigendian_obj,");
571         $self->pidl("&ndr64_obj)) {");
572         $self->deindent;
573         $self->indent;
574         $self->pidl("return NULL;");
575         $self->deindent;
576         $self->pidl("}");
577         $self->pidl("");
578         $self->pidl("if (bigendian_obj && PyObject_IsTrue(bigendian_obj)) {");
579         $self->indent;
580         $self->pidl("ndr_push_flags |= LIBNDR_FLAG_BIGENDIAN;");
581         $self->deindent;
582         $self->pidl("}");
583         $self->pidl("if (ndr64_obj && PyObject_IsTrue(ndr64_obj)) {");
584         $self->indent;
585         $self->pidl("ndr_push_flags |= LIBNDR_FLAG_NDR64;");
586         $self->deindent;
587         $self->pidl("}");
588         $self->pidl("");
589         $self->pidl("return py_$name\_ndr_pack(py_obj, NDR_IN, ndr_push_flags);");
590         $self->deindent;
591         $self->pidl("}");
592         $self->pidl("");
593
594         $self->pidl("static PyObject *py_$name\_ndr_pack_out(PyObject *py_obj, PyObject *args, PyObject *kwargs)");
595         $self->pidl("{");
596         $self->indent;
597         $self->pidl("const char * const kwnames[] = { \"bigendian\", \"ndr64\", NULL };");
598         $self->pidl("PyObject *bigendian_obj = NULL;");
599         $self->pidl("PyObject *ndr64_obj = NULL;");
600         $self->pidl("uint32_t ndr_push_flags = 0;");
601         $self->pidl("");
602         $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"|OO:__ndr_pack_out__\",");
603         $self->indent;
604         $self->pidl("discard_const_p(char *, kwnames),");
605         $self->pidl("&bigendian_obj,");
606         $self->pidl("&ndr64_obj)) {");
607         $self->deindent;
608         $self->indent;
609         $self->pidl("return NULL;");
610         $self->deindent;
611         $self->pidl("}");
612         $self->pidl("");
613         $self->pidl("if (bigendian_obj && PyObject_IsTrue(bigendian_obj)) {");
614         $self->indent;
615         $self->pidl("ndr_push_flags |= LIBNDR_FLAG_BIGENDIAN;");
616         $self->deindent;
617         $self->pidl("}");
618         $self->pidl("if (ndr64_obj && PyObject_IsTrue(ndr64_obj)) {");
619         $self->indent;
620         $self->pidl("ndr_push_flags |= LIBNDR_FLAG_NDR64;");
621         $self->deindent;
622         $self->pidl("}");
623         $self->pidl("");
624         $self->pidl("return py_$name\_ndr_pack(py_obj, NDR_OUT, ndr_push_flags);");
625         $self->deindent;
626         $self->pidl("}");
627         $self->pidl("");
628
629         $self->pidl("static PyObject *py_$name\_ndr_unpack(PyObject *py_obj, const DATA_BLOB *blob, int ndr_inout_flags, uint32_t ndr_pull_flags, bool allow_remaining)");
630         $self->pidl("{");
631         $self->indent;
632         $self->pidl("$ndr_call");
633         $self->pidl("$object_ptr");
634         $self->pidl("struct ndr_pull *pull = NULL;");
635         $self->pidl("enum ndr_err_code err;");
636         $self->pidl("");
637         $self->pidl("if (ndr_table_$iface\.num_calls < " . ($fn->{OPNUM}+1) .
638                     ") {");
639         $self->indent;
640         $self->pidl("PyErr_SetString(PyExc_TypeError, \"Internal Error, ndr_interface_call missing for py_$name\_ndr_unpack\");");
641         $self->pidl("return NULL;");
642         $self->deindent;
643         $self->pidl("}");
644         $self->pidl("call = &ndr_table_$iface\.calls[$fn->{OPNUM}];");
645         $self->pidl("");
646         $self->pidl("pull = ndr_pull_init_blob(blob, object);");
647         $self->pidl("if (pull == NULL) {");
648         $self->indent;
649         $self->pidl("PyErr_SetNdrError(NDR_ERR_ALLOC);");
650         $self->pidl("return NULL;");
651         $self->deindent;
652         $self->pidl("}");
653         $self->pidl("");
654         $self->pidl("pull->flags |= ndr_pull_flags;");
655         $self->pidl("");
656         $self->pidl("err = call->ndr_pull(pull, ndr_inout_flags, object);");
657         $self->pidl("if (!NDR_ERR_CODE_IS_SUCCESS(err)) {");
658         $self->indent;
659         $self->pidl("TALLOC_FREE(pull);");
660         $self->pidl("PyErr_SetNdrError(err);");
661         $self->pidl("return NULL;");
662         $self->deindent;
663         $self->pidl("}");
664         $self->pidl("if (!allow_remaining) {");
665         $self->indent;
666         $self->pidl("uint32_t highest_ofs;");
667         $self->pidl("");
668         $self->pidl("if (pull->offset > pull->relative_highest_offset) {");
669         $self->indent;
670         $self->pidl("highest_ofs = pull->offset;");
671         $self->deindent;
672         $self->pidl("} else {");
673         $self->indent;
674         $self->pidl("highest_ofs = pull->relative_highest_offset;");
675         $self->deindent;
676         $self->pidl("}");
677         $self->pidl("if (highest_ofs < pull->data_size) {");
678         $self->indent;
679         $self->pidl("err = ndr_pull_error(pull, NDR_ERR_UNREAD_BYTES,");
680         $self->indent;
681         $self->pidl("\"not all bytes consumed ofs[%u] size[%u]\",");
682         $self->pidl("highest_ofs, pull->data_size);");
683         $self->deindent;
684         $self->pidl("TALLOC_FREE(pull);");
685         $self->pidl("PyErr_SetNdrError(err);");
686         $self->pidl("return NULL;");
687         $self->deindent;
688         $self->pidl("}");
689         $self->deindent;
690         $self->pidl("}");
691         $self->pidl("");
692         $self->pidl("TALLOC_FREE(pull);");
693         $self->pidl("Py_RETURN_NONE;");
694         $self->deindent;
695         $self->pidl("}");
696         $self->pidl("");
697
698         $self->pidl("static PyObject *py_$name\_ndr_unpack_in(PyObject *py_obj, PyObject *args, PyObject *kwargs)");
699         $self->pidl("{");
700         $self->indent;
701         $self->pidl("DATA_BLOB blob;");
702         $self->pidl("Py_ssize_t blob_length = 0;");
703         $self->pidl("const char * const kwnames[] = { \"data_blob\", \"bigendian\", \"ndr64\", \"allow_remaining\", NULL };");
704         $self->pidl("PyObject *bigendian_obj = NULL;");
705         $self->pidl("PyObject *ndr64_obj = NULL;");
706         $self->pidl("uint32_t ndr_pull_flags = LIBNDR_FLAG_REF_ALLOC;");
707         $self->pidl("PyObject *allow_remaining_obj = NULL;");
708         $self->pidl("bool allow_remaining = false;");
709         $self->pidl("");
710         $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|OOO:__ndr_unpack_in__\",");
711         $self->indent;
712         $self->pidl("discard_const_p(char *, kwnames),");
713         $self->pidl("&blob.data, &blob_length,");
714         $self->pidl("&bigendian_obj,");
715         $self->pidl("&ndr64_obj,");
716         $self->pidl("&allow_remaining_obj)) {");
717         $self->deindent;
718         $self->indent;
719         $self->pidl("return NULL;");
720         $self->deindent;
721         $self->pidl("}");
722         $self->pidl("blob.length = blob_length;");
723         $self->pidl("");
724         $self->pidl("if (bigendian_obj && PyObject_IsTrue(bigendian_obj)) {");
725         $self->indent;
726         $self->pidl("ndr_pull_flags |= LIBNDR_FLAG_BIGENDIAN;");
727         $self->deindent;
728         $self->pidl("}");
729         $self->pidl("if (ndr64_obj && PyObject_IsTrue(ndr64_obj)) {");
730         $self->indent;
731         $self->pidl("ndr_pull_flags |= LIBNDR_FLAG_NDR64;");
732         $self->deindent;
733         $self->pidl("}");
734         $self->pidl("");
735         $self->pidl("if (allow_remaining_obj && PyObject_IsTrue(allow_remaining_obj)) {");
736         $self->indent;
737         $self->pidl("allow_remaining = true;");
738         $self->deindent;
739         $self->pidl("}");
740         $self->pidl("");
741         $self->pidl("return py_$name\_ndr_unpack(py_obj, &blob, NDR_IN, ndr_pull_flags, allow_remaining);");
742         $self->deindent;
743         $self->pidl("}");
744         $self->pidl("");
745
746         $self->pidl("static PyObject *py_$name\_ndr_unpack_out(PyObject *py_obj, PyObject *args, PyObject *kwargs)");
747         $self->pidl("{");
748         $self->indent;
749         $self->pidl("DATA_BLOB blob;");
750         $self->pidl("Py_ssize_t blob_length = 0;");
751         $self->pidl("const char * const kwnames[] = { \"data_blob\", \"bigendian\", \"ndr64\", \"allow_remaining\", NULL };");
752         $self->pidl("PyObject *bigendian_obj = NULL;");
753         $self->pidl("PyObject *ndr64_obj = NULL;");
754         $self->pidl("uint32_t ndr_pull_flags = LIBNDR_FLAG_REF_ALLOC;");
755         $self->pidl("PyObject *allow_remaining_obj = NULL;");
756         $self->pidl("bool allow_remaining = false;");
757         $self->pidl("");
758         $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|OOO:__ndr_unpack_out__\",");
759         $self->indent;
760         $self->pidl("discard_const_p(char *, kwnames),");
761         $self->pidl("&blob.data, &blob_length,");
762         $self->pidl("&bigendian_obj,");
763         $self->pidl("&ndr64_obj,");
764         $self->pidl("&allow_remaining_obj)) {");
765         $self->deindent;
766         $self->indent;
767         $self->pidl("return NULL;");
768         $self->deindent;
769         $self->pidl("}");
770         $self->pidl("blob.length = blob_length;");
771         $self->pidl("");
772         $self->pidl("if (bigendian_obj && PyObject_IsTrue(bigendian_obj)) {");
773         $self->indent;
774         $self->pidl("ndr_pull_flags |= LIBNDR_FLAG_BIGENDIAN;");
775         $self->deindent;
776         $self->pidl("}");
777         $self->pidl("if (ndr64_obj && PyObject_IsTrue(ndr64_obj)) {");
778         $self->indent;
779         $self->pidl("ndr_pull_flags |= LIBNDR_FLAG_NDR64;");
780         $self->deindent;
781         $self->pidl("}");
782         $self->pidl("");
783         $self->pidl("if (allow_remaining_obj && PyObject_IsTrue(allow_remaining_obj)) {");
784         $self->indent;
785         $self->pidl("allow_remaining = true;");
786         $self->deindent;
787         $self->pidl("}");
788         $self->pidl("");
789         $self->pidl("return py_$name\_ndr_unpack(py_obj, &blob, NDR_OUT, ndr_pull_flags, allow_remaining);");
790         $self->deindent;
791         $self->pidl("}");
792         $self->pidl("");
793
794         $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj, const char *name, int ndr_inout_flags)");
795         $self->pidl("{");
796         $self->indent;
797         $self->pidl("$ndr_call");
798         $self->pidl("$object_ptr");
799         $self->pidl("PyObject *ret;");
800         $self->pidl("char *retstr;");
801         $self->pidl("");
802         $self->pidl("if (ndr_table_$iface\.num_calls < " . ($fn->{OPNUM}+1) .
803                     ") {");
804         $self->indent;
805         $self->pidl("PyErr_SetString(PyExc_TypeError, \"Internal Error, ndr_interface_call missing for py_$name\_ndr_print\");");
806         $self->pidl("return NULL;");
807         $self->deindent;
808         $self->pidl("}");
809         $self->pidl("call = &ndr_table_$iface\.calls[$fn->{OPNUM}];");
810         $self->pidl("");
811         $self->pidl("retstr = ndr_print_function_string(pytalloc_get_mem_ctx(py_obj), call->ndr_print, name, ndr_inout_flags, object);");
812         $self->pidl("ret = PyUnicode_FromString(retstr);");
813         $self->pidl("TALLOC_FREE(retstr);");
814         $self->pidl("");
815         $self->pidl("return ret;");
816         $self->deindent;
817         $self->pidl("}");
818         $self->pidl("");
819
820         $self->pidl("static PyObject *py_$name\_ndr_print_in(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
821         $self->pidl("{");
822         $self->indent;
823         $self->pidl("return py_$name\_ndr_print(py_obj, \"$name\_in\", NDR_IN);");
824         $self->deindent;
825         $self->pidl("}");
826         $self->pidl("");
827
828         $self->pidl("static PyObject *py_$name\_ndr_print_out(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
829         $self->pidl("{");
830         $self->indent;
831         $self->pidl("return py_$name\_ndr_print(py_obj, \"$name\_out\", NDR_OUT);");
832         $self->deindent;
833         $self->pidl("}");
834         $self->pidl("");
835
836         $py_methods = "py_$name\_methods";
837         $self->pidl("static PyMethodDef $py_methods\[] = {");
838         $self->indent;
839         $self->pidl("{ \"opnum\", (PyCFunction)py_$name\_ndr_opnum, METH_NOARGS|METH_CLASS,");
840         $self->indent;
841         $self->pidl("\"$modulename.$prettyname.opnum() -> ".sprintf("%d (0x%02x)", $fn->{OPNUM}, $fn->{OPNUM})." \" },");
842         $self->deindent;
843         $self->pidl("{ \"__ndr_pack_in__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_pack_in), METH_VARARGS|METH_KEYWORDS,");
844         $self->indent;
845         $self->pidl("\"S.ndr_pack_in(object, bigendian=False, ndr64=False) -> blob\\nNDR pack input\" },");
846         $self->deindent;
847         $self->pidl("{ \"__ndr_pack_out__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_pack_out), METH_VARARGS|METH_KEYWORDS,");
848         $self->indent;
849         $self->pidl("\"S.ndr_pack_out(object, bigendian=False, ndr64=False) -> blob\\nNDR pack output\" },");
850         $self->deindent;
851         $self->pidl("{ \"__ndr_unpack_in__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack_in), METH_VARARGS|METH_KEYWORDS,");
852         $self->indent;
853         $self->pidl("\"S.ndr_unpack_in(class, blob, bigendian=False, ndr64=False, allow_remaining=False) -> None\\nNDR unpack input\" },");
854         $self->deindent;
855         $self->pidl("{ \"__ndr_unpack_out__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack_out), METH_VARARGS|METH_KEYWORDS,");
856         $self->indent;
857         $self->pidl("\"S.ndr_unpack_out(class, blob, bigendian=False, ndr64=False, allow_remaining=False) -> None\\nNDR unpack output\" },");
858         $self->deindent;
859         $self->pidl("{ \"__ndr_print_in__\", (PyCFunction)py_$name\_ndr_print_in, METH_NOARGS, \"S.ndr_print_in(object) -> None\\nNDR print input\" },");
860         $self->pidl("{ \"__ndr_print_out__\", (PyCFunction)py_$name\_ndr_print_out, METH_NOARGS, \"S.ndr_print_out(object) -> None\\nNDR print output\" },");
861         $self->pidl("{ NULL, NULL, 0, NULL }");
862         $self->deindent;
863         $self->pidl("};");
864         $self->pidl("");
865
866         $self->pidl_hdr("static PyTypeObject $name\_Type;\n");
867         $self->pidl("");
868         my $docstring = $self->DocString($fn, $name);
869         my $typeobject = "$name\_Type";
870         $self->pidl("static PyTypeObject $typeobject = {");
871         $self->indent;
872         $self->pidl("PyVarObject_HEAD_INIT(NULL, 0)");
873         $self->pidl(".tp_name = \"$modulename.$prettyname\",");
874         $self->pidl(".tp_getset = $getsetters,");
875         if ($docstring) {
876                 $self->pidl(".tp_doc = $docstring,");
877         }
878         $self->pidl(".tp_methods = $py_methods,");
879         $self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,");
880         $self->pidl(".tp_new = py_$name\_new,");
881         $self->deindent;
882         $self->pidl("};");
883
884         $self->pidl("");
885
886         my $talloc_typename = $self->import_type_variable("talloc", "BaseObject");
887         $self->register_module_prereadycode(["$name\_Type.tp_base = $talloc_typename;",
888                                              "$name\_Type.tp_basicsize = pytalloc_BaseObject_size();",
889                                              ""]);
890
891         return "&$typeobject";
892 }
893
894 sub get_metadata_var($)
895 {
896         my ($e) = @_;
897         sub get_var($) { my $x = shift; $x =~ s/\*//g; return $x; }
898
899          if (has_property($e, "length_is")) {
900                 return get_var($e->{PROPERTIES}->{length_is});
901          } elsif (has_property($e, "size_is")) {
902                 return get_var($e->{PROPERTIES}->{size_is});
903          }
904
905          return undef;
906 }
907
908 sub find_metadata_args($)
909 {
910         my ($fn) = @_;
911         my $metadata_args = { in => {}, out => {} };
912
913         # Determine arguments that are metadata for other arguments (size_is/length_is)
914         foreach my $e (@{$fn->{ELEMENTS}}) {
915                 foreach my $dir (@{$e->{DIRECTION}}) {
916                          my $main = get_metadata_var($e);
917                          if ($main) {
918                                  $metadata_args->{$dir}->{$main} = $e->{NAME};
919                          }
920                  }
921         }
922
923         return $metadata_args;
924 }
925
926 sub PythonFunctionUnpackOut($$$)
927 {
928         my ($self, $fn, $fnname) = @_;
929
930         my $outfnname = "unpack_$fnname\_args_out";
931         my $signature = "";
932
933         my $metadata_args = find_metadata_args($fn);
934
935         my $env = GenerateFunctionOutEnv($fn, "r->");
936         my $result_size = 0;
937
938         $self->pidl("static PyObject *$outfnname(struct $fn->{NAME} *r)");
939         $self->pidl("{");
940         $self->indent;
941         $self->pidl("PyObject *result;");
942         foreach my $e (@{$fn->{ELEMENTS}}) {
943                 next unless (grep(/out/,@{$e->{DIRECTION}}));
944                 next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or
945                          ($metadata_args->{out}->{$e->{NAME}}) and grep(/out/, @{$e->{DIRECTION}}));
946                 $self->pidl("PyObject *py_$e->{NAME};");
947                 $result_size++;
948         }
949
950         if ($fn->{RETURN_TYPE}) {
951                 $result_size++ unless ($fn->{RETURN_TYPE} eq "WERROR" or $fn->{RETURN_TYPE} eq "NTSTATUS");
952         }
953
954         my $i = 0;
955
956         if ($result_size > 1) {
957                 $self->pidl("result = PyTuple_New($result_size);");
958                 $signature .= "(";
959         } elsif ($result_size == 0) {
960                 $self->pidl("result = Py_None;");
961                 $self->pidl("Py_INCREF(result);");
962                 $signature .= "None";
963         }
964
965         foreach my $e (@{$fn->{ELEMENTS}}) {
966                 next if ($metadata_args->{out}->{$e->{NAME}});
967                 my $py_name = "py_$e->{NAME}";
968                 if (grep(/out/,@{$e->{DIRECTION}})) {
969                         $self->ConvertObjectToPython("r", $env, $e, "r->out.$e->{NAME}", $py_name, "return NULL;");
970                         if ($result_size > 1) {
971                                 $self->pidl("PyTuple_SetItem(result, $i, $py_name);");
972                                 $i++;
973                                 $signature .= "$e->{NAME}, ";
974                         } else {
975                                 $self->pidl("result = $py_name;");
976                                 $signature .= $e->{NAME};
977                         }
978                 }
979         }
980
981         if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") {
982                 $self->handle_ntstatus("r->out.result", "NULL", undef);
983         } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") {
984                 $self->handle_werror("r->out.result", "NULL", undef);
985         } elsif (defined($fn->{RETURN_TYPE})) {
986                 my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result", $fn);
987                 if ($result_size > 1) {
988                         $self->pidl("PyTuple_SetItem(result, $i, $conv);");
989                 } else {
990                         $self->pidl("result = $conv;");
991                 }
992                 $signature .= "result";
993         }
994
995         if (substr($signature, -2) eq ", ") {
996                 $signature = substr($signature, 0, -2);
997         }
998         if ($result_size > 1) {
999                 $signature .= ")";
1000         }
1001
1002         $self->pidl("return result;");
1003         $self->deindent;
1004         $self->pidl("}");
1005         $self->pidl("");
1006
1007         return ($outfnname, $signature);
1008 }
1009
1010 sub PythonFunctionPackIn($$$)
1011 {
1012         my ($self, $fn, $fnname) = @_;
1013         my $metadata_args = find_metadata_args($fn);
1014
1015         my $infnname = "pack_$fnname\_args_in";
1016
1017         $self->pidl("static bool $infnname(PyObject *args, PyObject *kwargs, struct $fn->{NAME} *r)");
1018         $self->pidl("{");
1019         $self->indent;
1020         my $args_format = "";
1021         my $args_string = "";
1022         my $args_names = "";
1023         my $signature = "";
1024
1025         foreach my $e (@{$fn->{ELEMENTS}}) {
1026                 next unless (grep(/in/,@{$e->{DIRECTION}}));
1027                 next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or
1028                                  ($metadata_args->{out}->{$e->{NAME}}) and grep(/out/, @{$e->{DIRECTION}}));
1029                 $self->pidl("PyObject *py_$e->{NAME};");
1030                 $args_format .= "O";
1031                 $args_string .= ", &py_$e->{NAME}";
1032                 $args_names .= "\"$e->{NAME}\", ";
1033                 $signature .= "$e->{NAME}, ";
1034         }
1035         if (substr($signature, -2) eq ", ") {
1036                 $signature = substr($signature, 0, -2);
1037         }
1038         $self->pidl("const char *kwnames[] = {");
1039         $self->indent;
1040         $self->pidl($args_names . "NULL");
1041         $self->deindent;
1042         $self->pidl("};");
1043
1044         $self->pidl("");
1045         $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"$args_format:$fn->{NAME}\", discard_const_p(char *, kwnames)$args_string)) {");
1046         $self->indent;
1047         $self->pidl("return false;");
1048         $self->deindent;
1049         $self->pidl("}");
1050         $self->pidl("");
1051
1052         my $env = GenerateFunctionInEnv($fn, "r->");
1053
1054         my $fail = "return false;";
1055         foreach my $e (@{$fn->{ELEMENTS}}) {
1056                 next unless (grep(/in/,@{$e->{DIRECTION}}));
1057                 if ($metadata_args->{in}->{$e->{NAME}}) {
1058                         my $py_var = "py_".$metadata_args->{in}->{$e->{NAME}};
1059                         $self->pidl("PY_CHECK_TYPE(&PyList_Type, $py_var, $fail);");
1060                         my $val = "PyList_GET_SIZE($py_var)";
1061                         if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") {
1062                                 $self->pidl("r->in.$e->{NAME} = talloc_ptrtype(r, r->in.$e->{NAME});");
1063                                 $self->pidl("if (r->in.$e->{NAME} == NULL) {");
1064                                 $self->indent;
1065                                 $self->pidl("PyErr_NoMemory();");
1066                                 $self->pidl($fail);
1067                                 $self->deindent;
1068                                 $self->pidl("}");
1069                                 $self->pidl("*r->in.$e->{NAME} = $val;");
1070                         } else {
1071                                 $self->pidl("r->in.$e->{NAME} = $val;");
1072                         }
1073                 } else {
1074                         $self->ConvertObjectFromPython($env, "r", $e, "py_$e->{NAME}", "r->in.$e->{NAME}", $fail);
1075                 }
1076         }
1077         $self->pidl("return true;");
1078         $self->deindent;
1079         $self->pidl("}");
1080         $self->pidl("");
1081         return ($infnname, $signature);
1082 }
1083
1084 sub PythonFunction($$$)
1085 {
1086         my ($self, $fn, $iface, $prettyname) = @_;
1087
1088         my $fnname = "py_$fn->{NAME}";
1089         my $docstring = $self->DocString($fn, $fn->{NAME});
1090
1091         my ($infn, $insignature) = $self->PythonFunctionPackIn($fn, $fnname);
1092         my ($outfn, $outsignature) = $self->PythonFunctionUnpackOut($fn, $fnname);
1093         my $signature = "S.$prettyname($insignature) -> $outsignature";
1094         if ($docstring) {
1095                 $docstring = "\"$signature\\n\\n\"$docstring";
1096         } else {
1097                 $docstring = "\"$signature\"";
1098         }
1099
1100         return ($infn, $outfn, $docstring);
1101 }
1102
1103 sub handle_werror($$$$)
1104 {
1105         my ($self, $var, $retval, $mem_ctx) = @_;
1106
1107         $self->pidl("if (!W_ERROR_IS_OK($var)) {");
1108         $self->indent;
1109         $self->pidl("PyErr_SetWERROR($var);");
1110         $self->pidl("talloc_free($mem_ctx);") if ($mem_ctx);
1111         $self->pidl("return $retval;");
1112         $self->deindent;
1113         $self->pidl("}");
1114         $self->pidl("");
1115 }
1116
1117 sub handle_ntstatus($$$$)
1118 {
1119         my ($self, $var, $retval, $mem_ctx) = @_;
1120
1121         $self->pidl("if (NT_STATUS_IS_ERR($var)) {");
1122         $self->indent;
1123         $self->pidl("PyErr_SetNTSTATUS($var);");
1124         $self->pidl("talloc_free($mem_ctx);") if ($mem_ctx);
1125         $self->pidl("return $retval;");
1126         $self->deindent;
1127         $self->pidl("}");
1128         $self->pidl("");
1129 }
1130
1131 sub PythonType($$$$)
1132 {
1133         my ($self, $modulename, $d, $interface, $basename) = @_;
1134
1135         my $actual_ctype = $d;
1136         if ($actual_ctype->{TYPE} eq "TYPEDEF") {
1137                 $actual_ctype = $actual_ctype->{DATA};
1138         }
1139
1140         if ($actual_ctype->{TYPE} eq "STRUCT") {
1141                 my $typeobject;
1142                 my $fn_name = PrettifyTypeName($d->{NAME}, $basename);
1143
1144                 if ($d->{TYPE} eq "STRUCT") {
1145                         $typeobject = $self->PythonStruct($modulename, $fn_name, $d->{NAME}, mapTypeName($d), $d);
1146                 } else {
1147                         $typeobject = $self->PythonStruct($modulename, $fn_name, $d->{NAME}, mapTypeName($d), $d->{DATA});
1148                 }
1149
1150                 $self->register_module_typeobject($fn_name, $typeobject, $d->{ORIGINAL});
1151         }
1152
1153         if ($d->{TYPE} eq "ENUM" or $d->{TYPE} eq "BITMAP") {
1154                 $self->EnumAndBitmapConsts($d->{NAME}, $d);
1155         }
1156
1157         if ($d->{TYPE} eq "TYPEDEF" and ($d->{DATA}->{TYPE} eq "ENUM" or $d->{DATA}->{TYPE} eq "BITMAP")) {
1158                 $self->EnumAndBitmapConsts($d->{NAME}, $d->{DATA});
1159         }
1160
1161         if ($actual_ctype->{TYPE} eq "UNION" and defined($actual_ctype->{ELEMENTS})) {
1162                 my $prettyname = PrettifyTypeName($d->{NAME}, $basename);
1163                 my $typeobject = "$d->{NAME}\_Type";
1164                 my $docstring = $self->DocString($d, $d->{NAME});
1165                 my $cname = "union $d->{NAME}";
1166
1167                 $self->pidl("static PyObject *py_import_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, " .mapTypeName($d) . " *in)");
1168                 $self->pidl("{");
1169                 $self->indent;
1170                 $self->FromUnionToPythonFunction("mem_ctx", $actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION");
1171                 $self->deindent;
1172                 $self->pidl("}");
1173                 $self->pidl("");
1174
1175                 $self->pidl("static ".mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, PyObject *in)");
1176                 $self->pidl("{");
1177                 $self->indent;
1178                 $self->FromPythonToUnionFunction($actual_ctype, mapTypeName($d), "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION");
1179                 $self->deindent;
1180                 $self->pidl("}");
1181                 $self->pidl("");
1182
1183                 my $getsetters = "NULL";
1184                 my $py_methods = "NULL";
1185                 my $typename = mapTypeName($d);
1186
1187                 $self->pidl("static PyObject *py_$d->{NAME}\_import(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
1188                 $self->pidl("{");
1189                 $self->indent;
1190                 $self->pidl("const char * const kwnames[] = { \"mem_ctx\", \"level\", \"in\", NULL };");
1191                 $self->pidl("PyObject *mem_ctx_obj = NULL;");
1192                 $self->pidl("TALLOC_CTX *mem_ctx = NULL;");
1193                 $self->pidl("int level = 0;");
1194                 $self->pidl("PyObject *in_obj = NULL;");
1195                 $self->pidl("$typename *in = NULL;");
1196                 $self->pidl("");
1197                 $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"OiO:import\",");
1198                 $self->indent;
1199                 $self->pidl("discard_const_p(char *, kwnames),");
1200                 $self->pidl("&mem_ctx_obj,");
1201                 $self->pidl("&level,");
1202                 $self->pidl("&in_obj)) {");
1203                 $self->deindent;
1204                 $self->indent;
1205                 $self->pidl("return NULL;");
1206                 $self->deindent;
1207                 $self->pidl("}");
1208                 $self->pidl("mem_ctx = pytalloc_get_ptr(mem_ctx_obj);");
1209                 $self->pidl("if (mem_ctx == NULL) {");
1210                 $self->indent;
1211                 $self->pidl("PyErr_SetString(PyExc_TypeError, \"mem_ctx is NULL)!\");");
1212                 $self->pidl("return NULL;");
1213                 $self->deindent;
1214                 $self->pidl("}");
1215                 $self->pidl("in = ($typename *)pytalloc_get_ptr(in_obj);");
1216                 $self->pidl("if (in == NULL) {");
1217                 $self->indent;
1218                 $self->pidl("PyErr_Format(PyExc_TypeError, \"in needs to be a pointer to $typename!\");");
1219                 $self->pidl("return NULL;");
1220                 $self->deindent;
1221                 $self->pidl("}");
1222                 $self->pidl("");
1223                 $self->pidl("return py_import_$d->{NAME}(mem_ctx, level, in);");
1224                 $self->deindent;
1225                 $self->pidl("}");
1226                 $self->pidl("");
1227
1228                 $self->pidl("static PyObject *py_$d->{NAME}\_export(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
1229                 $self->pidl("{");
1230                 $self->indent;
1231                 $self->pidl("const char * const kwnames[] = { \"mem_ctx\", \"level\", \"in\", NULL };");
1232                 $self->pidl("PyObject *mem_ctx_obj = NULL;");
1233                 $self->pidl("TALLOC_CTX *mem_ctx = NULL;");
1234                 $self->pidl("int level = 0;");
1235                 $self->pidl("PyObject *in = NULL;");
1236                 $self->pidl("$typename *out = NULL;");
1237                 $self->pidl("");
1238                 $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"OiO:export\",");
1239                 $self->indent;
1240                 $self->pidl("discard_const_p(char *, kwnames),");
1241                 $self->pidl("&mem_ctx_obj,");
1242                 $self->pidl("&level,");
1243                 $self->pidl("&in)) {");
1244                 $self->deindent;
1245                 $self->indent;
1246                 $self->pidl("return NULL;");
1247                 $self->deindent;
1248                 $self->pidl("}");
1249                 $self->pidl("mem_ctx = pytalloc_get_ptr(mem_ctx_obj);");
1250                 $self->pidl("if (mem_ctx == NULL) {");
1251                 $self->indent;
1252                 $self->pidl("PyErr_SetString(PyExc_TypeError, \"mem_ctx is NULL)!\");");
1253                 $self->pidl("return NULL;");
1254                 $self->deindent;
1255                 $self->pidl("}");
1256                 $self->pidl("");
1257                 $self->pidl("out = py_export_$d->{NAME}(mem_ctx, level, in);");
1258                 $self->pidl("if (out == NULL) {");
1259                 $self->indent;
1260                 $self->pidl("return NULL;");
1261                 $self->deindent;
1262                 $self->pidl("}");
1263                 $self->pidl("");
1264                 $self->pidl("return pytalloc_GenericObject_reference(out);");
1265                 $self->deindent;
1266                 $self->pidl("}");
1267                 $self->pidl("");
1268
1269                 $py_methods = "py_$d->{NAME}_methods";
1270                 $self->pidl("static PyMethodDef $py_methods\[] = {");
1271                 $self->indent;
1272                 $self->pidl("{ \"__import__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$d->{NAME}\_import),");
1273                 $self->indent;
1274                 $self->pidl("METH_VARARGS|METH_KEYWORDS|METH_CLASS,");
1275                 $self->pidl("\"T.__import__(mem_ctx, level, in) => ret.\" },");
1276                 $self->deindent;
1277                 $self->pidl("{ \"__export__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$d->{NAME}\_export),");
1278                 $self->indent;
1279                 $self->pidl("METH_VARARGS|METH_KEYWORDS|METH_CLASS,");
1280                 $self->pidl("\"T.__export__(mem_ctx, level, in) => ret.\" },");
1281                 $self->deindent;
1282                 $self->pidl("{ NULL, NULL, 0, NULL }");
1283                 $self->deindent;
1284                 $self->pidl("};");
1285                 $self->pidl("");
1286
1287                 $self->pidl("static PyObject *py_$d->{NAME}\_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
1288                 $self->pidl("{");
1289                 $self->indent;
1290                 $self->pidl("PyErr_Format(PyExc_TypeError, \"New %s Objects are not supported\", type->tp_name);");
1291                 $self->pidl("return NULL;");
1292                 $self->deindent;
1293                 $self->pidl("}");
1294                 $self->pidl("");
1295
1296                 $self->pidl("");
1297                 $self->pidl_hdr("static PyTypeObject $typeobject;\n");
1298                 $self->pidl("static PyTypeObject $typeobject = {");
1299                 $self->indent;
1300                 $self->pidl("PyVarObject_HEAD_INIT(NULL, 0)");
1301                 $self->pidl(".tp_name = \"$modulename.$prettyname\",");
1302                 $self->pidl(".tp_getset = $getsetters,");
1303                 if ($docstring) {
1304                         $self->pidl(".tp_doc = $docstring,");
1305                 }
1306                 $self->pidl(".tp_methods = $py_methods,");
1307                 $self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,");
1308                 $self->pidl(".tp_new = py_$d->{NAME}\_new,");
1309                 $self->deindent;
1310                 $self->pidl("};");
1311
1312                 $self->pidl("");
1313
1314                 my $talloc_typename = $self->import_type_variable("talloc", "BaseObject");
1315                 $self->register_module_prereadycode(["$typeobject.tp_base = $talloc_typename;",
1316                                                      "$typeobject.tp_basicsize = pytalloc_BaseObject_size();",
1317                                                      ""]);
1318
1319                 $self->register_module_typeobject($prettyname, "&$typeobject", $d->{ORIGINAL});
1320         }
1321 }
1322
1323 sub DocString($$$)
1324 {
1325         my ($self, $d, $name) = @_;
1326         if (has_property($d, "helpstring")) {
1327                 my $docstring = uc("py_doc_$name");
1328                 $self->pidl("#define $docstring ".has_property($d, "helpstring"));
1329                 return $docstring;
1330         }
1331
1332         return undef;
1333 }
1334
1335 sub Interface($$$)
1336 {
1337         my($self,$interface,$basename) = @_;
1338
1339         if (has_property($interface, "pyhelper")) {
1340                 $self->pidl("#include \"".unmake_str($interface->{PROPERTIES}->{pyhelper})."\"\n");
1341         }
1342
1343         $self->Const($_) foreach (@{$interface->{CONSTS}});
1344
1345         foreach my $d (@{$interface->{TYPES}}) {
1346                 next if has_property($d, "nopython");
1347
1348                 $self->PythonType($basename, $d, $interface, $basename);
1349         }
1350
1351         if (defined $interface->{PROPERTIES}->{uuid}) {
1352                 $self->pidl_hdr("static PyTypeObject $interface->{NAME}_InterfaceType;\n");
1353                 $self->pidl("");
1354
1355                 my @fns = ();
1356
1357                 foreach my $d (@{$interface->{FUNCTIONS}}) {
1358                         next if has_property($d, "noopnum");
1359                         next if has_property($d, "nopython");
1360                         next if has_property($d, "todo");
1361
1362                         my $skip = 0;
1363                         foreach my $e (@{$d->{ELEMENTS}}) {
1364                                 if (ContainsPipe($e, $e->{LEVELS}[0])) {
1365                                         $skip = 1;
1366                                         last;
1367                                 }
1368                         }
1369                         next if $skip;
1370
1371                         my $prettyname = $d->{NAME};
1372
1373                         $prettyname =~ s/^$interface->{NAME}_//;
1374                         $prettyname =~ s/^$basename\_//;
1375
1376                         my $typeobject = $self->PythonFunctionStruct($basename, $d, $interface->{NAME}, $prettyname);
1377                         $self->register_module_typeobject($prettyname, $typeobject, $d->{ORIGINAL});
1378
1379                         my ($infn, $outfn, $fndocstring) = $self->PythonFunction($d, $interface->{NAME}, $prettyname);
1380
1381                         push (@fns, [$infn, $outfn, "dcerpc_$d->{NAME}_r", $prettyname, $fndocstring, $d->{OPNUM}]);
1382                 }
1383
1384                 $self->pidl("const struct PyNdrRpcMethodDef py_ndr_$interface->{NAME}\_methods[] = {");
1385                 $self->indent;
1386                 foreach my $d (@fns) {
1387                         my ($infn, $outfn, $callfn, $prettyname, $docstring, $opnum) = @$d;
1388                         $self->pidl("{ \"$prettyname\", $docstring, (py_dcerpc_call_fn)$callfn, (py_data_pack_fn)$infn, (py_data_unpack_fn)$outfn, $opnum, &ndr_table_$interface->{NAME} },");
1389                 }
1390                 $self->pidl("{ NULL }");
1391                 $self->deindent;
1392                 $self->pidl("};");
1393                 $self->pidl("");
1394
1395                 $self->pidl("static PyObject *interface_$interface->{NAME}_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
1396                 $self->pidl("{");
1397                 $self->indent;
1398                 $self->pidl("return py_dcerpc_interface_init_helper(type, args, kwargs, &ndr_table_$interface->{NAME});");
1399                 $self->deindent;
1400                 $self->pidl("}");
1401
1402                 $self->pidl("");
1403
1404                 my $signature =
1405 "\"$interface->{NAME}(binding, lp_ctx=None, credentials=None) -> connection\\n\"
1406 \"\\n\"
1407 \"binding should be a DCE/RPC binding string (for example: ncacn_ip_tcp:127.0.0.1)\\n\"
1408 \"lp_ctx should be a path to a smb.conf file or a param.LoadParm object\\n\"
1409 \"credentials should be a credentials.Credentials object.\\n\\n\"";
1410
1411                 my $docstring = $self->DocString($interface, $interface->{NAME});
1412
1413                 if ($docstring) {
1414                         $docstring = "$signature$docstring";
1415                 } else {
1416                         $docstring = $signature;
1417                 }
1418
1419                 my $if_typename = "$interface->{NAME}_InterfaceType";
1420
1421                 $self->pidl("static PyTypeObject $if_typename = {");
1422                 $self->indent;
1423                 $self->pidl("PyVarObject_HEAD_INIT(NULL, 0)");
1424                 $self->pidl(".tp_name = \"$basename.$interface->{NAME}\",");
1425                 $self->pidl(".tp_basicsize = sizeof(dcerpc_InterfaceObject),");
1426                 $self->pidl(".tp_doc = $docstring,");
1427                 $self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,");
1428                 $self->pidl(".tp_new = interface_$interface->{NAME}_new,");
1429                 $self->deindent;
1430                 $self->pidl("};");
1431
1432                 $self->pidl("");
1433
1434                 $self->register_module_typeobject($interface->{NAME}, "&$if_typename", $interface->{ORIGINAL});
1435                 my $dcerpc_typename = $self->import_type_variable("samba.dcerpc.base", "ClientConnection");
1436                 $self->register_module_prereadycode(["$if_typename.tp_base = $dcerpc_typename;", ""]);
1437                 $self->register_module_postreadycode(["if (!PyInterface_AddNdrRpcMethods(&$if_typename, py_ndr_$interface->{NAME}\_methods))", "\treturn NULL;", ""]);
1438
1439
1440                 $self->pidl("static PyObject *syntax_$interface->{NAME}_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
1441                 $self->pidl("{");
1442                 $self->indent;
1443                 $self->pidl("return py_dcerpc_syntax_init_helper(type, args, kwargs, &ndr_table_$interface->{NAME}.syntax_id);");
1444                 $self->deindent;
1445                 $self->pidl("}");
1446
1447                 $self->pidl("");
1448
1449                 my $signature = "\"$interface->{NAME}_abstract_syntax()\\n\"";
1450
1451                 my $docstring = $self->DocString($interface, $interface->{NAME}."_syntax");
1452
1453                 if ($docstring) {
1454                         $docstring = "$signature$docstring";
1455                 } else {
1456                         $docstring = $signature;
1457                 }
1458
1459                 my $syntax_typename = "$interface->{NAME}_SyntaxType";
1460
1461                 $self->pidl("static PyTypeObject $syntax_typename = {");
1462                 $self->indent;
1463                 $self->pidl("PyVarObject_HEAD_INIT(NULL, 0)");
1464                 $self->pidl(".tp_name = \"$basename.$interface->{NAME}_abstract_syntax\",");
1465                 $self->pidl(".tp_doc = $docstring,");
1466                 $self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,");
1467                 $self->pidl(".tp_new = syntax_$interface->{NAME}_new,");
1468                 $self->deindent;
1469                 $self->pidl("};");
1470
1471                 $self->pidl("");
1472
1473                 $self->register_module_typeobject("$interface->{NAME}_abstract_syntax", "&$syntax_typename", $interface->{ORIGINAL});
1474                 if (not defined($self->existing_module_object("abstract_syntax"))) {
1475                         # Only the first syntax gets registered with the legacy
1476                         # "abstract_syntax" name
1477                         $self->register_module_typeobject("abstract_syntax", "&$syntax_typename", $interface->{ORIGINAL});
1478                 }
1479                 my $ndr_typename = $self->import_type_variable("samba.dcerpc.misc", "ndr_syntax_id");
1480                 $self->register_module_prereadycode(["$syntax_typename.tp_base = $ndr_typename;",
1481                                                      "$syntax_typename.tp_basicsize = pytalloc_BaseObject_size();",
1482                                                      ""]);
1483         }
1484
1485         $self->pidl_hdr("\n");
1486 }
1487
1488 sub register_module_method($$$$$)
1489 {
1490         my ($self, $fn_name, $pyfn_name, $flags, $doc) = @_;
1491
1492         push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc])
1493 }
1494
1495 sub register_module_typeobject($$$$)
1496 {
1497         my ($self, $name, $py_name, $location) = @_;
1498
1499         $self->register_module_object($name, "(PyObject *)(void *)$py_name", $location);
1500
1501         $self->check_ready_type($py_name);
1502
1503         $self->register_patch_type_call($name, $py_name);
1504 }
1505
1506 sub check_ready_type($$)
1507 {
1508         my ($self, $py_name) = @_;
1509         push (@{$self->{ready_types}}, $py_name) unless (grep(/^$py_name$/,@{$self->{ready_types}}));
1510 }
1511
1512 sub register_module_import($$)
1513 {
1514         my ($self, $module_path) = @_;
1515
1516         my $var_name = $module_path;
1517         $var_name =~ s/\./_/g;
1518         $var_name = "dep_$var_name";
1519
1520         unless (defined $self->{module_imports_uniq}->{$var_name}) {
1521                 my $h = { "key" => $var_name, "val" => $module_path};
1522                 push @{$self->{module_imports}}, $h;
1523                 $self->{module_imports_uniq}->{$var_name} = $h;
1524         }
1525         return $var_name;
1526 }
1527
1528 sub import_type_variable($$$)
1529 {
1530         my ($self, $module, $name) = @_;
1531
1532         $self->register_module_import($module);
1533         unless (defined $self->{type_imports_uniq}->{$name}) {
1534                 my $h = { "key" => $name, "val" => $module};
1535                 push @{$self->{type_imports}}, $h;
1536                 $self->{type_imports_uniq}->{$name} = $h;
1537         }
1538         return "$name\_Type";
1539 }
1540
1541 sub use_type_variable($$)
1542 {
1543         my ($self, $orig_ctype) = @_;
1544         # FIXME: Have a global lookup table for types that look different on the
1545         # wire than they are named in C?
1546         if ($orig_ctype->{NAME} eq "dom_sid2" or
1547             $orig_ctype->{NAME} eq "dom_sid28" or
1548             $orig_ctype->{NAME} eq "dom_sid0") {
1549                 $orig_ctype->{NAME} = "dom_sid";
1550         }
1551         if ($orig_ctype->{NAME} eq "spoolss_security_descriptor") {
1552                 $orig_ctype->{NAME} = "security_descriptor";
1553         }
1554
1555         my $ctype = resolveType($orig_ctype);
1556         unless (defined($ctype->{BASEFILE})) {
1557                 return undef;
1558         }
1559         # If this is an external type, make sure we do the right imports.
1560         if (($ctype->{BASEFILE} ne $self->{BASENAME})) {
1561                 return $self->import_type_variable("samba.dcerpc.$ctype->{BASEFILE}", $ctype->{NAME});
1562         }
1563         return "&$ctype->{NAME}_Type";
1564 }
1565
1566 sub register_patch_type_call($$$)
1567 {
1568         my ($self, $typename, $cvar) = @_;
1569
1570         push(@{$self->{patch_type_calls}}, [$typename, $cvar]);
1571
1572 }
1573
1574 sub register_module_prereadycode($$)
1575 {
1576         my ($self, $code) = @_;
1577
1578         push (@{$self->{prereadycode}}, @$code);
1579 }
1580
1581 sub register_module_postreadycode($$)
1582 {
1583         my ($self, $code) = @_;
1584
1585         push (@{$self->{postreadycode}}, @$code);
1586 }
1587
1588 sub existing_module_object($$)
1589 {
1590         my ($self, $name) = @_;
1591
1592         if (defined($self->{module_object_uniq}->{$name})) {
1593                 return $self->{module_object_uniq}->{$name};
1594         }
1595
1596         return undef;
1597 }
1598
1599 sub register_module_object($$$$)
1600 {
1601         my ($self, $name, $py_name, $location) = @_;
1602
1603         my $existing = $self->existing_module_object($name);
1604         fatal($location, "module_object($name, $py_name) registered twice! $existing.") if defined($existing);
1605
1606         push (@{$self->{module_objects}}, [$name, $py_name]);
1607         $self->{module_object_uniq}->{$name} = $py_name;
1608 }
1609
1610 sub assign($$$)
1611 {
1612         my ($self, $dest, $src) = @_;
1613         if ($dest =~ /^\&/ and $src eq "NULL") {
1614                 $self->pidl("memset($dest, 0, sizeof(" . get_value_of($dest) . "));");
1615         } elsif ($dest =~ /^\&/) {
1616                 my $destvar = get_value_of($dest);
1617                 $self->pidl("$destvar = *$src;");
1618         } else {
1619                 $self->pidl("$dest = $src;");
1620         }
1621 }
1622
1623 sub ConvertStringFromPythonData($$$$$)
1624 {
1625         my ($self, $mem_ctx, $py_var, $target, $fail) = @_;
1626
1627         $self->pidl("{");
1628         $self->indent;
1629         $self->pidl("const char *test_str;");
1630         $self->pidl("const char *talloc_str;");
1631         $self->pidl("PyObject *unicode = NULL;");
1632         $self->pidl("if (PyUnicode_Check($py_var)) {");
1633         $self->indent;
1634         # FIXME: Use Unix charset setting rather than utf-8
1635         $self->pidl("unicode = PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\");");
1636         $self->pidl("if (unicode == NULL) {");
1637         $self->indent;
1638         $self->pidl("PyErr_NoMemory();");
1639         $self->pidl("$fail");
1640         $self->deindent;
1641         $self->pidl("}");
1642
1643         $self->pidl("test_str = PyBytes_AS_STRING(unicode);");
1644         $self->deindent;
1645         $self->pidl("} else if (PyBytes_Check($py_var)) {");
1646         $self->indent;
1647         $self->pidl("test_str = PyBytes_AS_STRING($py_var);");
1648         $self->deindent;
1649         $self->pidl("} else {");
1650         $self->indent;
1651         $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected string or unicode object, got %s\", Py_TYPE($py_var)->tp_name);");
1652         $self->pidl("$fail");
1653         $self->deindent;
1654         $self->pidl("}");
1655         $self->pidl("talloc_str = talloc_strdup($mem_ctx, test_str);");
1656         $self->pidl("if (unicode != NULL) {");
1657         $self->indent;
1658         $self->pidl("Py_DECREF(unicode);");
1659         $self->deindent;
1660         $self->pidl("}");
1661         $self->pidl("if (talloc_str == NULL) {");
1662         $self->indent;
1663         $self->pidl("PyErr_NoMemory();");
1664         $self->pidl("$fail");
1665         $self->deindent;
1666         $self->pidl("}");
1667         $self->pidl("$target = talloc_str;");
1668         $self->deindent;
1669         $self->pidl("}");
1670 }
1671
1672 sub ConvertObjectFromPythonData($$$$$$;$$)
1673 {
1674         my ($self, $mem_ctx, $cvar, $ctype, $target, $fail, $location, $switch) = @_;
1675
1676         fatal($location, "undef type for $cvar") unless(defined($ctype));
1677
1678         $ctype = resolveType($ctype);
1679
1680         my $actual_ctype = $ctype;
1681         if ($actual_ctype->{TYPE} eq "TYPEDEF") {
1682                 $actual_ctype = $actual_ctype->{DATA};
1683         }
1684
1685         # We need to cover ENUMs, BITMAPS and SCALAR values here, as
1686         # all could otherwise be assigned invalid integer values
1687         my $ctype_alias = "";
1688         my $uint_max = "";
1689         if ($actual_ctype->{TYPE} eq "ENUM") {
1690                 # Importantly, ENUM values are unsigned in pidl, and
1691                 # typically map to uint32
1692                 $ctype_alias = enum_type_fn($actual_ctype);
1693         } elsif ($actual_ctype->{TYPE} eq "BITMAP") {
1694                 $ctype_alias = bitmap_type_fn($actual_ctype);
1695         } elsif ($actual_ctype->{TYPE} eq "SCALAR") {
1696                 $ctype_alias = expandAlias($actual_ctype->{NAME});
1697         }
1698
1699         # This is the unsigned Python Integer -> C integer validation
1700         # case.  The signed case is below.
1701         if ($ctype_alias  =~ /^(uint[0-9]*|hyper|udlong|udlongr
1702                                 |NTTIME_hyper|NTTIME|NTTIME_1sec
1703                                 |uid_t|gid_t)$/x) {
1704                 $self->pidl("{");
1705                 $self->indent;
1706                 $self->pidl("const unsigned long long uint_max = ndr_sizeof2uintmax(sizeof($target));");
1707                 $self->pidl("if (PyLong_Check($cvar)) {");
1708                 $self->indent;
1709                 $self->pidl("unsigned long long test_var;");
1710                 $self->pidl("test_var = PyLong_AsUnsignedLongLong($cvar);");
1711                 $self->pidl("if (PyErr_Occurred() != NULL) {");
1712                 $self->indent;
1713                 $self->pidl($fail);
1714                 $self->deindent;
1715                 $self->pidl("}");
1716                 $self->pidl("if (test_var > uint_max) {");
1717                 $self->indent;
1718                 $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %llu\",\\");
1719                 $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);");
1720                 $self->pidl($fail);
1721                 $self->deindent;
1722                 $self->pidl("}");
1723                 $self->pidl("$target = test_var;");
1724                 $self->deindent;
1725                 $self->pidl("} else if (PyInt_Check($cvar)) {");
1726                 $self->indent;
1727                 $self->pidl("long test_var;");
1728                 $self->pidl("test_var = PyInt_AsLong($cvar);");
1729                 $self->pidl("if (test_var < 0 || (unsigned long long)test_var > uint_max) {");
1730                 $self->indent;
1731                 $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %ld\",\\");
1732                 $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);");
1733                 $self->pidl($fail);
1734                 $self->deindent;
1735                 $self->pidl("}");
1736                 $self->pidl("$target = test_var;");
1737                 $self->deindent;
1738                 $self->pidl("} else {");
1739                 $self->indent;
1740                 $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
1741                 $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name);");
1742                 $self->pidl($fail);
1743                 $self->deindent;
1744                 $self->pidl("}");
1745                 $self->deindent;
1746                 $self->pidl("}");
1747                 return;
1748         }
1749
1750         # Confirm the signed python integer fits in the C type
1751         # correctly.  It is subtly different from the unsigned case
1752         # above, so while it looks like a duplicate, it is not
1753         # actually a duplicate.
1754         if ($ctype_alias  =~ /^(dlong|char|int[0-9]*|time_t)$/x) {
1755                 $self->pidl("{");
1756                 $self->indent;
1757                 $self->pidl("const long long int_max = ndr_sizeof2intmax(sizeof($target));");
1758                 $self->pidl("const long long int_min = -int_max - 1;");
1759                 $self->pidl("if (PyLong_Check($cvar)) {");
1760                 $self->indent;
1761                 $self->pidl("long long test_var;");
1762                 $self->pidl("test_var = PyLong_AsLongLong($cvar);");
1763                 $self->pidl("if (PyErr_Occurred() != NULL) {");
1764                 $self->indent;
1765                 $self->pidl($fail);
1766                 $self->deindent;
1767                 $self->pidl("}");
1768                 $self->pidl("if (test_var < int_min || test_var > int_max) {");
1769                 $self->indent;
1770                 $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %lld\",\\");
1771                 $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
1772                 $self->pidl($fail);
1773                 $self->deindent;
1774                 $self->pidl("}");
1775                 $self->pidl("$target = test_var;");
1776                 $self->deindent;
1777                 $self->pidl("} else if (PyInt_Check($cvar)) {");
1778                 $self->indent;
1779                 $self->pidl("long test_var;");
1780                 $self->pidl("test_var = PyInt_AsLong($cvar);");
1781                 $self->pidl("if (test_var < int_min || test_var > int_max) {");
1782                 $self->indent;
1783                 $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %ld\",\\");
1784                 $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
1785                 $self->pidl($fail);
1786                 $self->deindent;
1787                 $self->pidl("}");
1788                 $self->pidl("$target = test_var;");
1789                 $self->deindent;
1790                 $self->pidl("} else {");
1791                 $self->indent;
1792                 $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
1793                 $self->pidl("  PyInt_Type.tp_name, PyLong_Type.tp_name);");
1794                 $self->pidl($fail);
1795                 $self->deindent;
1796                 $self->pidl("}");
1797                 $self->deindent;
1798                 $self->pidl("}");
1799                 return;
1800         }
1801
1802         if ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
1803                 my $ctype_name = $self->use_type_variable($ctype);
1804                 unless (defined ($ctype_name)) {
1805                         error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
1806                         $self->pidl("PyErr_SetString(PyExc_TypeError, \"Can not convert C Type " . mapTypeName($ctype) . " from Python\");");
1807                         return;
1808                 }
1809                 $self->pidl("PY_CHECK_TYPE($ctype_name, $cvar, $fail);");
1810                 $self->pidl("if (talloc_reference($mem_ctx, pytalloc_get_mem_ctx($cvar)) == NULL) {");
1811                 $self->indent;
1812                 $self->pidl("PyErr_NoMemory();");
1813                 $self->pidl("$fail");
1814                 $self->deindent;
1815                 $self->pidl("}");
1816                 $self->assign($target, "(".mapTypeName($ctype)." *)pytalloc_get_ptr($cvar)");
1817                 return;
1818         }
1819
1820         if ($actual_ctype->{TYPE} eq "UNION") {
1821                 my $ctype_name = $self->use_type_variable($ctype);
1822                 unless (defined ($ctype_name)) {
1823                         error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
1824                         $self->pidl("PyErr_SetString(PyExc_TypeError, \"Can not convert C Type " . mapTypeName($ctype) . " from Python\");");
1825                         return;
1826                 }
1827                 my $export = "pyrpc_export_union($ctype_name, $mem_ctx, $switch, $cvar, \"".mapTypeName($ctype)."\")";
1828                 $self->assign($target, "(".mapTypeName($ctype)." *)$export");
1829                 return;
1830         }
1831
1832         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "DATA_BLOB") {
1833                 $self->pidl("$target = data_blob_talloc($mem_ctx, PyBytes_AS_STRING($cvar), PyBytes_GET_SIZE($cvar));");
1834                 return;
1835         }
1836
1837         if ($actual_ctype->{TYPE} eq "SCALAR" and
1838                 ($actual_ctype->{NAME} eq "string"
1839                  or $actual_ctype->{NAME} eq "nbt_string"
1840                  or $actual_ctype->{NAME} eq "nbt_name"
1841                  or $actual_ctype->{NAME} eq "wrepl_nbt_name"
1842                  or $actual_ctype->{NAME} eq "dns_string"
1843                  or $actual_ctype->{NAME} eq "dnsp_string"
1844                  or $actual_ctype->{NAME} eq "dns_name"
1845                  or $actual_ctype->{NAME} eq "ipv4address"
1846                  or $actual_ctype->{NAME} eq "ipv6address"
1847                  or $actual_ctype->{NAME} eq "dnsp_name")) {
1848                 $self->ConvertStringFromPythonData($mem_ctx, $cvar, $target, $fail);
1849                 return;
1850         }
1851
1852         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
1853                 $self->pidl("$target = NT_STATUS(PyInt_AsLong($cvar));");
1854                 return;
1855         }
1856
1857         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") {
1858                 $self->pidl("$target = W_ERROR(PyInt_AsLong($cvar));");
1859                 return;
1860         }
1861
1862         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "HRESULT") {
1863                 $self->pidl("$target = HRES_ERROR(PyInt_AsLong($cvar));");
1864                 return;
1865         }
1866
1867         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") {
1868                 $self->pidl("$target = pytalloc_get_ptr($cvar);");
1869                 return;
1870         }
1871
1872         if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") {
1873                 $self->assign($target, "pytalloc_get_ptr($cvar)");
1874                 return;
1875         }
1876
1877         fatal($location, "unknown type `$actual_ctype->{TYPE}' for ".mapTypeName($ctype) . ": $cvar");
1878
1879 }
1880
1881 sub ConvertObjectFromPythonLevel($$$$$$$$$)
1882 {
1883         my ($self, $env, $mem_ctx, $py_var, $e, $l, $var_name, $fail, $recurse) = @_;
1884         my $nl = GetNextLevel($e, $l);
1885         if ($nl and $nl->{TYPE} eq "SUBCONTEXT") {
1886                 $nl = GetNextLevel($e, $nl);
1887         }
1888         my $pl = GetPrevLevel($e, $l);
1889         if ($pl and $pl->{TYPE} eq "SUBCONTEXT") {
1890                 $pl = GetPrevLevel($e, $pl);
1891         }
1892
1893         if ($recurse == 0) {
1894                 $self->pidl("if ($py_var == NULL) {");
1895                 $self->indent;
1896                 $self->pidl("PyErr_Format(PyExc_AttributeError, \"Cannot delete NDR object: " .
1897                     mapTypeName($var_name) . "\");");
1898                 $self->pidl($fail);
1899                 $self->deindent;
1900                 $self->pidl("}");
1901         }
1902         $recurse = $recurse + 1;
1903
1904         if ($l->{TYPE} eq "POINTER") {
1905                 my $need_deindent = 0;
1906                 my $need_deref = 0;
1907
1908                 if ($l->{POINTER_TYPE} ne "ref") {
1909                         $self->pidl("if ($py_var == Py_None) {");
1910                         $self->indent;
1911                         $self->pidl("$var_name = NULL;");
1912                         $self->deindent;
1913                         $self->pidl("} else {");
1914                         $self->indent;
1915                         $need_deindent = 1;
1916                         if ($nl->{TYPE} eq "POINTER") {
1917                                 $need_deref = 1;
1918                         }
1919                 }
1920
1921                 if ($l->{POINTER_TYPE} eq "ref" or $need_deref == 1) {
1922                         $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
1923                         $self->pidl("if ($var_name == NULL) {");
1924                         $self->indent;
1925                         $self->pidl("PyErr_NoMemory();");
1926                         $self->pidl($fail);
1927                         $self->deindent;
1928                         $self->pidl("}");
1929                 } elsif ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::is_scalar($nl->{DATA_TYPE})
1930                          and not Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
1931                         $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
1932                         $self->pidl("if ($var_name == NULL) {");
1933                         $self->indent;
1934                         $self->pidl("PyErr_NoMemory();");
1935                         $self->pidl($fail);
1936                         $self->deindent;
1937                         $self->pidl("}");
1938                 } else {
1939                         $self->pidl("$var_name = NULL;");
1940                 }
1941                 if ($need_deref == 1) {
1942                         my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer");
1943                         $self->pidl("$py_var = py_dcerpc_ndr_pointer_deref($ndr_pointer_typename, $py_var);");
1944                 }
1945                 unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
1946                         $var_name = get_value_of($var_name);
1947                 }
1948                 $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail, $recurse);
1949                 if ($need_deindent == 1) {
1950                         $self->deindent;
1951                         $self->pidl("}");
1952                 }
1953         } elsif ($l->{TYPE} eq "ARRAY") {
1954                 if ($pl && $pl->{TYPE} eq "POINTER") {
1955                         $var_name = get_pointer_to($var_name);
1956                 }
1957
1958                 if (is_charset_array($e, $l)) {
1959                         $self->ConvertStringFromPythonData($mem_ctx, $py_var, $var_name, $fail);
1960                 } else {
1961                         my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}";
1962                         $self->pidl("PY_CHECK_TYPE(&PyList_Type, $py_var, $fail);");
1963                         $self->pidl("{");
1964                         $self->indent;
1965                         $self->pidl("int $counter;");
1966                         if (ArrayDynamicallyAllocated($e, $l)) {
1967                                 $self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_GET_SIZE($py_var));");
1968                                 $self->pidl("if (!$var_name) { $fail; }");
1969                                 $self->pidl("talloc_set_name_const($var_name, \"ARRAY: $var_name\");");
1970                         } else {
1971                                 $self->pidl("if (ARRAY_SIZE($var_name) != PyList_GET_SIZE($py_var)) {");
1972                                 $self->indent;
1973                                 $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected list of type %s, length %zu, got %zd\", Py_TYPE($py_var)->tp_name, ARRAY_SIZE($var_name),  PyList_GET_SIZE($py_var));");
1974                                 $self->pidl("$fail");
1975                                 $self->deindent;
1976                                 $self->pidl("}");
1977                         }
1978                         $self->pidl("for ($counter = 0; $counter < PyList_GET_SIZE($py_var); $counter++) {");
1979                         $self->indent;
1980                         $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, $var_name."[$counter]", $fail, 0);
1981                         $self->deindent;
1982                         $self->pidl("}");
1983                         $self->deindent;
1984                         $self->pidl("}");
1985                 }
1986         } elsif ($l->{TYPE} eq "DATA") {
1987                 if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
1988                         $var_name = get_pointer_to($var_name);
1989                 }
1990                 $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail, $e->{ORIGINAL});
1991         } elsif ($l->{TYPE} eq "SWITCH") {
1992                 $var_name = get_pointer_to($var_name);
1993                 my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e);
1994                 my $switch_ptr = "$e->{NAME}_switch_$l->{LEVEL_INDEX}";
1995                 $self->pidl("{");
1996                 $self->indent;
1997                 my $union_type = mapTypeName($nl->{DATA_TYPE});
1998                 $self->pidl("$union_type *$switch_ptr;");
1999                 $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $nl->{DATA_TYPE}, $switch_ptr, $fail, $e->{ORIGINAL}, $switch);
2000                 $self->fail_on_null($switch_ptr, $fail);
2001                 $self->assign($var_name, "$switch_ptr");
2002                 $self->deindent;
2003                 $self->pidl("}");
2004         } elsif ($l->{TYPE} eq "SUBCONTEXT") {
2005                 $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail, $recurse);
2006         } else {
2007                 fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}");
2008         }
2009 }
2010
2011 sub ConvertObjectFromPython($$$$$$$)
2012 {
2013         my ($self, $env, $mem_ctx, $ctype, $cvar, $target, $fail) = @_;
2014         my $recurse = 0;
2015
2016         $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail, $recurse);
2017 }
2018
2019 sub ConvertScalarToPython($$$$)
2020 {
2021         my ($self, $ctypename, $cvar, $mem_ctx) = @_;
2022
2023         die("expected string for $cvar, not $ctypename") if (ref($ctypename) eq "HASH");
2024
2025         $ctypename = expandAlias($ctypename);
2026
2027         if ($ctypename =~ /^(int64|dlong)$/) {
2028                 return "PyLong_FromLongLong($cvar)";
2029         }
2030
2031         if ($ctypename =~ /^(uint64|hyper|NTTIME_hyper|NTTIME|NTTIME_1sec|udlong|udlongr|uid_t|gid_t)$/) {
2032                 return "PyLong_FromUnsignedLongLong($cvar)";
2033         }
2034
2035         if ($ctypename =~ /^(char|int|int8|int16|int32|time_t)$/) {
2036                 return "PyInt_FromLong($cvar)";
2037         }
2038
2039         # Needed to ensure unsigned values in a 32 or 16 bit enum is
2040         # cast correctly to a uint32_t, not sign extended to a a
2041         # possibly 64 bit unsigned long.  (enums are signed in C,
2042         # unsigned in NDR)
2043         if ($ctypename =~ /^(uint32|uint3264)$/) {
2044                 return "PyLong_FromUnsignedLongLong((uint32_t)$cvar)";
2045         }
2046
2047         if ($ctypename =~ /^(uint|uint8|uint16|uint1632)$/) {
2048                 return "PyInt_FromLong((uint16_t)$cvar)";
2049         }
2050
2051         if ($ctypename eq "DATA_BLOB") {
2052                 return "PyBytes_FromStringAndSize((char *)($cvar).data, ($cvar).length)";
2053         }
2054
2055         if ($ctypename eq "NTSTATUS") {
2056                 return "PyErr_FromNTSTATUS($cvar)";
2057         }
2058
2059         if ($ctypename eq "WERROR") {
2060                 return "PyErr_FromWERROR($cvar)";
2061         }
2062
2063         if ($ctypename eq "HRESULT") {
2064                 return "PyErr_FromHRESULT($cvar)";
2065         }
2066
2067         if (($ctypename eq "string" or $ctypename eq "nbt_string" or $ctypename eq "nbt_name" or $ctypename eq "wrepl_nbt_name")) {
2068                 return "PyString_FromStringOrNULL($cvar)";
2069         }
2070
2071         if (($ctypename eq "dns_string" or $ctypename eq "dns_name")) {
2072                 return "PyString_FromStringOrNULL($cvar)";
2073         }
2074
2075         # Not yet supported
2076         if ($ctypename eq "string_array") {
2077                 return "pytalloc_GenericObject_reference_ex($mem_ctx, $cvar)";
2078         }
2079         if ($ctypename eq "ipv4address") { return "PyString_FromStringOrNULL($cvar)"; }
2080         if ($ctypename eq "ipv6address") { return "PyString_FromStringOrNULL($cvar)"; }
2081         if ($ctypename eq "dnsp_name") { return "PyString_FromStringOrNULL($cvar)"; }
2082         if ($ctypename eq "dnsp_string") { return "PyString_FromStringOrNULL($cvar)"; }
2083         if ($ctypename eq "pointer") {
2084                 return "pytalloc_GenericObject_reference_ex($mem_ctx, $cvar)";
2085         }
2086
2087         die("Unknown scalar type $ctypename");
2088 }
2089
2090 sub ConvertObjectToPythonData($$$$$;$$)
2091 {
2092         my ($self, $mem_ctx, $ctype, $cvar, $location, $switch) = @_;
2093
2094         die("undef type for $cvar") unless(defined($ctype));
2095
2096         $ctype = resolveType($ctype);
2097
2098         my $actual_ctype = $ctype;
2099         if ($actual_ctype->{TYPE} eq "TYPEDEF") {
2100                 $actual_ctype = $actual_ctype->{DATA};
2101         }
2102
2103         if ($actual_ctype->{TYPE} eq "ENUM") {
2104                 return $self->ConvertScalarToPython(Parse::Pidl::Typelist::enum_type_fn($actual_ctype), $cvar, $mem_ctx);
2105         } elsif ($actual_ctype->{TYPE} eq "BITMAP") {
2106                 return $self->ConvertScalarToPython(Parse::Pidl::Typelist::bitmap_type_fn($actual_ctype), $cvar, $mem_ctx);
2107         } elsif ($actual_ctype->{TYPE} eq "SCALAR") {
2108                 return $self->ConvertScalarToPython($actual_ctype->{NAME}, $cvar, $mem_ctx);
2109         } elsif ($actual_ctype->{TYPE} eq "UNION") {
2110                 my $ctype_name = $self->use_type_variable($ctype);
2111                 unless (defined($ctype_name)) {
2112                         error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
2113                         return "NULL"; # FIXME!
2114                 }
2115                 return "pyrpc_import_union($ctype_name, $mem_ctx, $switch, $cvar, \"".mapTypeName($ctype)."\")";
2116         } elsif ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
2117                 my $ctype_name = $self->use_type_variable($ctype);
2118                 unless (defined($ctype_name)) {
2119                         error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
2120                         return "NULL"; # FIXME!
2121                 }
2122                 return "pytalloc_reference_ex($ctype_name, $mem_ctx, $cvar)";
2123         }
2124
2125         fatal($location, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
2126 }
2127
2128 sub fail_on_null($$$)
2129 {
2130         my ($self, $var, $fail) = @_;
2131         $self->pidl("if ($var == NULL) {");
2132         $self->indent;
2133         $self->pidl($fail);
2134         $self->deindent;
2135         $self->pidl("}");
2136 }
2137
2138 sub ConvertObjectToPythonLevel($$$$$$$)
2139 {
2140         my ($self, $mem_ctx, $env, $e, $l, $var_name, $py_var, $fail, $recurse) = @_;
2141         my $nl = GetNextLevel($e, $l);
2142         if ($nl and $nl->{TYPE} eq "SUBCONTEXT") {
2143                 $nl = GetNextLevel($e, $nl);
2144         }
2145         my $pl = GetPrevLevel($e, $l);
2146         if ($pl and $pl->{TYPE} eq "SUBCONTEXT") {
2147                 $pl = GetPrevLevel($e, $pl);
2148         }
2149
2150         if ($l->{TYPE} eq "POINTER") {
2151                 my $need_wrap = 0;
2152                 if ($l->{POINTER_TYPE} ne "ref" and $nl->{TYPE} eq "POINTER") {
2153                         $need_wrap = 1;
2154                 }
2155                 if ($l->{POINTER_TYPE} ne "ref") {
2156                         if ($recurse == 0) {
2157                                 $self->pidl("if ($var_name == NULL) {");
2158                                 $self->indent;
2159                                 $self->pidl("$py_var = Py_None;");
2160                                 $self->pidl("Py_INCREF($py_var);");
2161                                 $self->deindent;
2162                                 $self->pidl("} else {");
2163                                 $self->indent;
2164                         } else {
2165                                 $self->pidl("{");
2166                                 $self->indent;
2167                         }
2168                         $recurse = $recurse + 1;
2169                 }
2170                 my $var_name2 = $var_name;
2171                 my $recurse2 = $recurse;
2172                 unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
2173                         $var_name2 = get_value_of($var_name);
2174                         $recurse2 = 0;
2175                 }
2176                 $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name2, $py_var, $fail, $recurse2);
2177                 if ($l->{POINTER_TYPE} ne "ref") {
2178                         $self->deindent;
2179                         $self->pidl("}");
2180                 }
2181                 if ($need_wrap) {
2182                         my $py_var_wrap = undef;
2183                         $need_wrap = 1;
2184                         $self->pidl("{");
2185                         $self->indent;
2186                         $py_var_wrap = "py_$e->{NAME}_level_$l->{LEVEL_INDEX}";
2187                         $self->pidl("PyObject *$py_var_wrap = $py_var;");
2188                         my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer");
2189                         $self->pidl("$py_var = py_dcerpc_ndr_pointer_wrap($ndr_pointer_typename, $py_var_wrap);");
2190                         $self->pidl("Py_XDECREF($py_var_wrap);");
2191                         $self->deindent;
2192                         $self->pidl("}");
2193                 }
2194         } elsif ($l->{TYPE} eq "ARRAY") {
2195                 if ($pl && $pl->{TYPE} eq "POINTER") {
2196                         $var_name = get_pointer_to($var_name);
2197                 }
2198
2199                 if (is_charset_array($e, $l)) {
2200                         # FIXME: Use Unix charset setting rather than utf-8
2201                         $self->pidl("if ($var_name == NULL) {");
2202                         $self->indent;
2203                         $self->pidl("$py_var = Py_None;");
2204                         $self->pidl("Py_INCREF($py_var);");
2205                         $self->deindent;
2206                         $self->pidl("} else {");
2207                         $self->indent;
2208                         $self->pidl("$py_var = PyUnicode_Decode($var_name, strlen($var_name), \"utf-8\", \"ignore\");");
2209                         $self->deindent;
2210                         $self->pidl("}");
2211                 } else {
2212                         die("No SIZE_IS for array $var_name") unless (defined($l->{SIZE_IS}));
2213                         my $length = $l->{SIZE_IS};
2214                         if (defined($l->{LENGTH_IS})) {
2215                                 $length = $l->{LENGTH_IS};
2216                         }
2217
2218                         $length = ParseExpr($length, $env, $e);
2219                         $self->pidl("$py_var = PyList_New($length);");
2220                         $self->fail_on_null($py_var, $fail);
2221                         $self->pidl("{");
2222                         $self->indent;
2223                         my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}";
2224                         $self->pidl("int $counter;");
2225                         $self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
2226                         $self->indent;
2227                         my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}";
2228                         $self->pidl("PyObject *$member_var;");
2229                         $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name."[$counter]", $member_var, $fail, $recurse);
2230                         $self->pidl("PyList_SetItem($py_var, $counter, $member_var);");
2231                         $self->deindent;
2232                         $self->pidl("}");
2233                         $self->deindent;
2234                         $self->pidl("}");
2235                 }
2236         } elsif ($l->{TYPE} eq "SWITCH") {
2237                 $var_name = get_pointer_to($var_name);
2238                 my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e);
2239                 my $conv = $self->ConvertObjectToPythonData($mem_ctx, $nl->{DATA_TYPE}, $var_name, $e->{ORIGINAL}, $switch);
2240                 $self->pidl("$py_var = $conv;");
2241                 $self->fail_on_null($py_var, $fail);
2242
2243         } elsif ($l->{TYPE} eq "DATA") {
2244                 if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
2245                         $var_name = get_pointer_to($var_name);
2246                 }
2247                 my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $e->{ORIGINAL});
2248                 $self->pidl("$py_var = $conv;");
2249         } elsif ($l->{TYPE} eq "SUBCONTEXT") {
2250                 $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, $nl, $var_name, $py_var, $fail, $recurse);
2251         } else {
2252                 fatal($e->{ORIGINAL}, "Unknown level type $l->{TYPE} $var_name");
2253         }
2254 }
2255
2256 sub ConvertObjectToPython($$$$$$)
2257 {
2258         my ($self, $mem_ctx, $env, $ctype, $cvar, $py_var, $fail) = @_;
2259         my $recurse = 0;
2260
2261         $self->ConvertObjectToPythonLevel($mem_ctx, $env, $ctype, $ctype->{LEVELS}[0], $cvar, $py_var, $fail, $recurse);
2262 }
2263
2264 sub Parse($$$$$)
2265 {
2266     my($self,$basename,$ndr,$ndr_hdr,$hdr) = @_;
2267
2268         $self->{BASENAME} = $basename;
2269
2270     $self->pidl_hdr("
2271 /* Python wrapper functions auto-generated by pidl */
2272 #define PY_SSIZE_T_CLEAN 1 /* We use Py_ssize_t for PyArg_ParseTupleAndKeywords */
2273 #include <Python.h>
2274 #include \"python/py3compat.h\"
2275 #include \"includes.h\"
2276 #include \"python/modules.h\"
2277 #include <pytalloc.h>
2278 #include \"librpc/rpc/pyrpc.h\"
2279 #include \"librpc/rpc/pyrpc_util.h\"
2280 #include \"$hdr\"
2281 #include \"$ndr_hdr\"
2282
2283 /*
2284  * These functions are here to ensure they can be optimized out by
2285  * the compiler based on the constant input values
2286  */
2287
2288 static inline unsigned long long ndr_sizeof2uintmax(size_t var_size)
2289 {
2290         switch (var_size) {
2291         case 8:
2292                 return UINT64_MAX;
2293         case 4:
2294                 return UINT32_MAX;
2295         case 2:
2296                 return UINT16_MAX;
2297         case 1:
2298                 return UINT8_MAX;
2299         }
2300
2301         return 0;
2302 }
2303
2304 static inline long long ndr_sizeof2intmax(size_t var_size)
2305 {
2306         switch (var_size) {
2307         case 8:
2308                 return INT64_MAX;
2309         case 4:
2310                 return INT32_MAX;
2311         case 2:
2312                 return INT16_MAX;
2313         case 1:
2314                 return INT8_MAX;
2315         }
2316
2317         return 0;
2318 }
2319
2320 ");
2321
2322         foreach my $x (@$ndr) {
2323                 ($x->{TYPE} eq "IMPORT") && $self->Import(@{$x->{PATHS}});
2324             ($x->{TYPE} eq "INTERFACE") && $self->Interface($x, $basename);
2325         }
2326
2327         $self->pidl("static PyMethodDef $basename\_methods[] = {");
2328         $self->indent;
2329         foreach (@{$self->{module_methods}}) {
2330                 my ($fn_name, $pyfn_name, $flags, $doc) = @$_;
2331                 $self->pidl("{ \"$fn_name\", (PyCFunction)$pyfn_name, $flags, $doc },");
2332         }
2333
2334         $self->pidl("{ NULL, NULL, 0, NULL }");
2335         $self->deindent;
2336         $self->pidl("};");
2337
2338         $self->pidl("");
2339
2340         $self->pidl("static struct PyModuleDef moduledef = {");
2341         $self->indent;
2342         $self->pidl("PyModuleDef_HEAD_INIT,");
2343         $self->pidl(".m_name = \"$basename\",");
2344         $self->pidl(".m_doc = \"$basename DCE/RPC\",");
2345         $self->pidl(".m_size = -1,");
2346         $self->pidl(".m_methods = $basename\_methods,");
2347         $self->deindent;
2348         $self->pidl("};");
2349
2350         $self->pidl("MODULE_INIT_FUNC($basename)");
2351         $self->pidl("{");
2352         $self->indent;
2353         $self->pidl("PyObject *m = NULL;");
2354         foreach my $h (@{$self->{module_imports}}) {
2355                 $self->pidl("PyObject *$h->{'key'} = NULL;");
2356         }
2357         $self->pidl("");
2358
2359         foreach my $h (@{$self->{module_imports}}) {
2360                 my $var_name = $h->{'key'};
2361                 my $module_path = $h->{'val'};
2362                 $self->pidl("$var_name = PyImport_ImportModule(\"$module_path\");");
2363                 $self->pidl("if ($var_name == NULL)");
2364                 $self->pidl("\tgoto out;");
2365                 $self->pidl("");
2366         }
2367
2368         foreach my $h (@{$self->{type_imports}}) {
2369                 my $type_var = "$h->{'key'}\_Type";
2370                 my $module_path = $h->{'val'};
2371                 $self->pidl_hdr("static PyTypeObject *$type_var;\n");
2372                 my $pretty_name = PrettifyTypeName($h->{'key'}, $module_path);
2373                 my $module_var = "dep_$module_path";
2374                 $module_var =~ s/\./_/g;
2375                 $self->pidl("$type_var = (PyTypeObject *)PyObject_GetAttrString($module_var, \"$pretty_name\");");
2376                 $self->pidl("if ($type_var == NULL)");
2377                 $self->pidl("\tgoto out;");
2378                 $self->pidl("");
2379         }
2380
2381         $self->pidl($_) foreach (@{$self->{prereadycode}});
2382
2383         foreach (@{$self->{ready_types}}) {
2384                 $self->pidl("if (PyType_Ready($_) < 0)");
2385                 $self->pidl("\tgoto out;");
2386         }
2387
2388         $self->pidl($_) foreach (@{$self->{postreadycode}});
2389
2390         foreach (@{$self->{patch_type_calls}}) {
2391                 my ($typename, $cvar) = @$_;
2392                 $self->pidl("#ifdef PY_".uc($typename)."_PATCH");
2393                 $self->pidl("PY_".uc($typename)."_PATCH($cvar);");
2394                 $self->pidl("#endif");
2395         }
2396
2397         $self->pidl("");
2398
2399         $self->pidl("m = PyModule_Create(&moduledef);");
2400         $self->pidl("if (m == NULL)");
2401         $self->pidl("\tgoto out;");
2402         $self->pidl("");
2403         foreach my $h (@{$self->{constants}}) {
2404                 my $pretty_name = PrettifyTypeName($h->{'key'}, $basename);
2405                 my $py_obj;
2406                 my ($ctype, $cvar) = @{$h->{'val'}};
2407                 if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) {
2408                         $py_obj = "PyLong_FromUnsignedLongLong($cvar)";
2409                 } elsif ($cvar =~ /^".*"$/) {
2410                         $py_obj = "PyUnicode_FromString($cvar)";
2411                 } else {
2412                         $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar, undef);
2413                 }
2414
2415                 $self->pidl("PyModule_AddObject(m, \"$pretty_name\", $py_obj);");
2416         }
2417
2418         foreach (@{$self->{module_objects}}) {
2419                 my ($object_name, $c_name) = @$_;
2420                 $self->pidl("Py_INCREF($c_name);");
2421                 $self->pidl("PyModule_AddObject(m, \"$object_name\", $c_name);");
2422         }
2423
2424         $self->pidl("#ifdef PY_MOD_".uc($basename)."_PATCH");
2425         $self->pidl("PY_MOD_".uc($basename)."_PATCH(m);");
2426         $self->pidl("#endif");
2427         $self->pidl("out:");
2428         foreach my $h (@{$self->{module_imports}}) {
2429                 my $mod_var = $h->{'key'};
2430                 $self->pidl("Py_XDECREF($mod_var);");
2431         }
2432         $self->pidl("return m;");
2433         $self->pidl("");
2434         $self->deindent;
2435         $self->pidl("}");
2436     return ($self->{res_hdr} . $self->{res});
2437 }
2438
2439 1;