?? python.pm
字號(hào):
#################################################### Python function wrapper generator# Copyright jelmer@samba.org 2007-2008# released under the GNU GPLpackage Parse::Pidl::Samba4::Python;use Exporter;@ISA = qw(Exporter);use strict;use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias);use Parse::Pidl::Util qw(has_property ParseExpr);use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);use vars qw($VERSION);$VERSION = '0.01';sub new($) { my ($class) = @_; my $self = { res => "", res_hdr => "", tabs => "", constants => {}, module_methods => [], module_objects => [], ready_types => [], readycode => [] }; bless($self, $class);}sub pidl_hdr ($$){ my $self = shift; $self->{res_hdr} .= shift;}sub pidl($$){ my ($self, $d) = @_; if ($d) { $self->{res} .= $self->{tabs}; $self->{res} .= $d; } $self->{res} .= "\n";}sub indent($){ my ($self) = @_; $self->{tabs} .= "\t";}sub deindent($){ my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 0, -1);}sub Import{ my $self = shift; my @imports = @_; foreach (@imports) { s/\.idl\"$//; s/^\"//; $self->pidl_hdr("#include \"librpc/gen_ndr/py_$_\.h\"\n"); }}sub Const($$){ my ($self, $const) = @_; $self->register_constant($const->{NAME}, $const->{DTYPE}, $const->{VALUE});}sub register_constant($$$$){ my ($self, $name, $type, $value) = @_; $self->{constants}->{$name} = [$type, $value];}sub EnumAndBitmapConsts($$$){ my ($self, $name, $d) = @_; return unless (defined($d->{ELEMENTS})); foreach my $e (@{$d->{ELEMENTS}}) { $e =~ /^([A-Za-z0-9_]+)/; my $cname = $1; $self->register_constant($cname, $d, $cname); }}sub FromUnionToPythonFunction($$$$){ my ($self, $mem_ctx, $type, $switch, $name) = @_; $self->pidl("PyObject *ret;"); $self->pidl(""); $self->pidl("switch ($switch) {"); $self->indent; foreach my $e (@{$type->{ELEMENTS}}) { $self->pidl("$e->{CASE}:"); $self->indent; if ($e->{NAME}) { $self->ConvertObjectToPython($mem_ctx, {}, $e, "$name->$e->{NAME}", "ret", "return NULL;"); } else { $self->pidl("ret = Py_None;"); } $self->pidl("return ret;"); $self->pidl(""); $self->deindent; } $self->deindent; $self->pidl("}"); $self->pidl("PyErr_SetString(PyExc_TypeError, \"unknown union level\");"); $self->pidl("return NULL;");}sub FromPythonToUnionFunction($$$$$){ my ($self, $type, $typename, $switch, $mem_ctx, $name) = @_; my $has_default = 0; $self->pidl("$typename *ret = talloc_zero($mem_ctx, $typename);"); $self->pidl("switch ($switch) {"); $self->indent; foreach my $e (@{$type->{ELEMENTS}}) { $self->pidl("$e->{CASE}:"); if ($e->{CASE} eq "default") { $has_default = 1; } $self->indent; if ($e->{NAME}) { $self->ConvertObjectFromPython({}, $mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;"); } $self->pidl("break;"); $self->deindent; $self->pidl(""); } if (!$has_default) { $self->pidl("default:"); $self->indent; $self->pidl("PyErr_SetString(PyExc_TypeError, \"invalid union level value\");"); $self->pidl("talloc_free(ret);"); $self->pidl("ret = NULL;"); $self->deindent; } $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("return ret;");}sub PythonStruct($$$$$$){ my ($self, $modulename, $prettyname, $name, $cname, $d) = @_; my $env = GenerateStructEnv($d, "object"); $self->pidl(""); my $getsetters = "NULL"; if ($#{$d->{ELEMENTS}} > -1) { foreach my $e (@{$d->{ELEMENTS}}) { my $varname = "object->$e->{NAME}"; $self->pidl("static PyObject *py_$name\_get_$e->{NAME}(PyObject *obj, void *closure)"); $self->pidl("{"); $self->indent; $self->pidl("$cname *object = py_talloc_get_ptr(obj);"); $self->pidl("PyObject *py_$e->{NAME};"); $self->ConvertObjectToPython("py_talloc_get_mem_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}", "return NULL;"); $self->pidl("return py_$e->{NAME};"); $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("static int py_$name\_set_$e->{NAME}(PyObject *py_obj, PyObject *value, void *closure)"); $self->pidl("{"); $self->indent; $self->pidl("$cname *object = py_talloc_get_ptr(py_obj);"); my $mem_ctx = "py_talloc_get_mem_ctx(py_obj)"; my $l = $e->{LEVELS}[0]; my $nl = GetNextLevel($e, $l); if ($l->{TYPE} eq "POINTER" and not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and not ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE}))) { $self->pidl("talloc_free($varname);"); } $self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;"); $self->pidl("return 0;"); $self->deindent; $self->pidl("}"); $self->pidl(""); } $getsetters = "py_$name\_getsetters"; $self->pidl("static PyGetSetDef ".$getsetters."[] = {"); $self->indent; foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("{ discard_const_p(char, \"$e->{NAME}\"), py_$name\_get_$e->{NAME}, py_$name\_set_$e->{NAME} },"); } $self->pidl("{ NULL }"); $self->deindent; $self->pidl("};"); $self->pidl(""); } $self->pidl("static PyObject *py_$name\_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)"); $self->pidl("{"); $self->indent; $self->pidl("$cname *ret = talloc_zero(NULL, $cname);"); $self->pidl("return py_talloc_import(&$name\_Type, ret);"); $self->deindent; $self->pidl("}"); $self->pidl(""); my $py_methods = "NULL"; # If the struct is not public there ndr_pull/ndr_push functions will # be static so not callable from here if (has_property($d, "public")) { $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj)"); $self->pidl("{"); $self->indent; $self->pidl("$cname *object = py_talloc_get_ptr(py_obj);"); $self->pidl("DATA_BLOB blob;"); $self->pidl("enum ndr_err_code err;"); $self->pidl("err = ndr_push_struct_blob(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_push_flags_fn_t)ndr_push_$name);"); $self->pidl("if (err != NDR_ERR_SUCCESS) {"); $self->indent; $self->pidl("PyErr_SetNdrError(err);"); $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("return PyString_FromStringAndSize((char *)blob.data, blob.length);"); $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("static PyObject *py_$name\_ndr_unpack(PyObject *py_obj, PyObject *args)"); $self->pidl("{"); $self->indent; $self->pidl("$cname *object = py_talloc_get_ptr(py_obj);"); $self->pidl("DATA_BLOB blob;"); $self->pidl("enum ndr_err_code err;"); $self->pidl("if (!PyArg_ParseTuple(args, \"s#:__ndr_unpack__\", &blob.data, &blob.length))"); $self->pidl("\treturn NULL;"); $self->pidl(""); $self->pidl("err = ndr_pull_struct_blob_all(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);"); $self->pidl("if (err != NDR_ERR_SUCCESS) {"); $self->indent; $self->pidl("PyErr_SetNdrError(err);"); $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("return Py_None;"); $self->deindent; $self->pidl("}"); $self->pidl(""); $py_methods = "py_$name\_methods"; $self->pidl("static PyMethodDef $py_methods\[] = {"); $self->indent; $self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.pack() -> blob\\nNDR pack\" },"); $self->pidl("{ \"__ndr_unpack__\", (PyCFunction)py_$name\_ndr_unpack, METH_VARARGS, \"S.unpack(blob) -> None\\nNDR unpack\" },"); $self->pidl("{ NULL, NULL, 0, NULL }"); $self->deindent; $self->pidl("};"); $self->pidl(""); } $self->pidl_hdr("PyAPI_DATA(PyTypeObject) $name\_Type;\n"); $self->pidl_hdr("#define $name\_Check(op) PyObject_TypeCheck(op, &$name\_Type)\n"); $self->pidl_hdr("#define $name\_CheckExact(op) ((op)->ob_type == &$name\_Type)\n"); $self->pidl_hdr("\n"); my $docstring = ($self->DocString($d, $name) or "NULL"); my $typeobject = "$name\_Type"; $self->pidl("PyTypeObject $typeobject = {"); $self->indent; $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$modulename.$prettyname\","); $self->pidl(".tp_basicsize = sizeof(py_talloc_Object),"); $self->pidl(".tp_dealloc = py_talloc_dealloc,"); $self->pidl(".tp_getset = $getsetters,"); $self->pidl(".tp_repr = py_talloc_default_repr,"); $self->pidl(".tp_doc = $docstring,"); $self->pidl(".tp_methods = $py_methods,"); $self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,"); $self->pidl(".tp_new = py_$name\_new,"); $self->deindent; $self->pidl("};"); $self->pidl(""); return "&$typeobject";}sub get_metadata_var($){ my ($e) = @_; sub get_var($) { my $x = shift; $x =~ s/\*//g; return $x; } if (has_property($e, "length_is")) { return get_var($e->{PROPERTIES}->{length_is}); } elsif (has_property($e, "size_is")) { return get_var($e->{PROPERTIES}->{size_is}); } return undef;}sub find_metadata_args($){ my ($fn) = @_; my $metadata_args = { in => {}, out => {} }; # Determine arguments that are metadata for other arguments (size_is/length_is) foreach my $e (@{$fn->{ELEMENTS}}) { foreach my $dir (@{$e->{DIRECTION}}) { my $main = get_metadata_var($e); if ($main) { $metadata_args->{$dir}->{$main} = $e->{NAME}; } } } return $metadata_args;}sub PythonFunctionUnpackOut($$$){ my ($self, $fn, $fnname) = @_; my $outfnname = "unpack_$fnname\_args_out"; my $signature = ""; my $metadata_args = find_metadata_args($fn); my $env = GenerateFunctionOutEnv($fn, "r->"); my $result_size = 0; $self->pidl("static PyObject *$outfnname(struct $fn->{NAME} *r)"); $self->pidl("{"); $self->indent; $self->pidl("PyObject *result = Py_None;"); foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/out/,@{$e->{DIRECTION}})); next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or ($metadata_args->{out}->{$e->{NAME}}) and grep(/out/, @{$e->{DIRECTION}})); $self->pidl("PyObject *py_$e->{NAME};"); $result_size++; } if ($fn->{RETURN_TYPE}) { $result_size++ unless ($fn->{RETURN_TYPE} eq "WERROR" or $fn->{RETURN_TYPE} eq "NTSTATUS"); } my $i = 0; if ($result_size > 1) { $self->pidl("result = PyTuple_New($result_size);"); $signature .= "("; } elsif ($result_size == 0) { $signature .= "None"; } foreach my $e (@{$fn->{ELEMENTS}}) { next if ($metadata_args->{out}->{$e->{NAME}}); my $py_name = "py_$e->{NAME}"; if (grep(/out/,@{$e->{DIRECTION}})) { $self->ConvertObjectToPython("r", $env, $e, "r->out.$e->{NAME}", $py_name, "return NULL;"); if ($result_size > 1) { $self->pidl("PyTuple_SetItem(result, $i, $py_name);"); $i++; $signature .= "$e->{NAME}, "; } else { $self->pidl("result = $py_name;"); $signature .= $e->{NAME}; } } } if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") { $self->handle_ntstatus("r->out.result", "NULL", undef); } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") { $self->handle_werror("r->out.result", "NULL", undef); } elsif (defined($fn->{RETURN_TYPE})) { my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result"); if ($result_size > 1) { $self->pidl("PyTuple_SetItem(result, $i, $conv);");
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -