⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 python.pm

📁 samba最新软件
💻 PM
📖 第 1 页 / 共 3 页
字号:
#################################################### 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);");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -