PIDL: sync pidl with samba repo

Copy pidl from samba repo after all wireshark changes were applied.

Change-Id: I0d3fb780c3f79b3b873304bab0655d98564dfc71
Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Reviewed-on: https://code.wireshark.org/review/13967
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
This commit is contained in:
Aurelien Aptel 2016-02-11 14:05:11 +01:00 committed by Alexis La Goutte
parent 82057fbedf
commit 62a0ebf1e0
13 changed files with 365 additions and 144 deletions

View File

@ -13,7 +13,7 @@ use Exporter;
use strict;
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property ParseExpr);
use Parse::Pidl::Util qw(has_property ParseExpr genpad);
use Parse::Pidl::NDR qw(ContainsPipe);
use Parse::Pidl::Typelist qw(mapTypeName);
use Parse::Pidl::Samba4 qw(DeclLong);
@ -25,18 +25,9 @@ $VERSION = '0.01';
sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; }
sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
sub genpad($)
{
my ($s) = @_;
my $nt = int((length($s)+1)/8);
my $lt = ($nt*8)-1;
my $ns = (length($s)-$lt);
return "\t"x($nt)." "x($ns);
}
sub new($)
{
my ($class) = shift;

View File

@ -24,6 +24,8 @@ $VERSION = '0.01';
my $res;
my $res_hdr;
my $tabs = "";
sub pidl_reset() { $res=""; $res_hdr="", $tabs=""; }
sub pidl_return() { my $s = $res; my $h = $res_hdr; pidl_reset(); return ($s, $h) }
sub indent() { $tabs.="\t"; }
sub deindent() { $tabs = substr($tabs, 1); }
sub pidl($) { my ($txt) = @_; $res .= $txt?$tabs.(shift)."\n":"\n"; }
@ -48,9 +50,9 @@ sub DeclLevel($$)
return $res;
}
sub AllocOutVar($$$$$)
sub AllocOutVar($$$$$$$)
{
my ($e, $mem_ctx, $name, $env, $fail) = @_;
my ($e, $mem_ctx, $name, $env, $check, $cleanup, $return) = @_;
my $l = $e->{LEVELS}[0];
@ -83,15 +85,18 @@ sub AllocOutVar($$$$$)
pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");";
}
pidl "if ($name == NULL) {";
$fail->();
pidl "if (" . $check->($name) . ") {";
indent;
pidl $cleanup->($name) if defined($cleanup);
pidl $return->($name) if defined($return);
deindent;
pidl "}";
pidl "";
}
sub CallWithStruct($$$$)
sub CallWithStruct($$$$$$)
{
my ($pipes_struct, $mem_ctx, $fn, $fail) = @_;
my ($pipes_struct, $mem_ctx, $fn, $check, $cleanup, $return) = @_;
my $env = GenerateFunctionOutEnv($fn);
my $hasout = 0;
foreach (@{$fn->{ELEMENTS}}) {
@ -100,8 +105,6 @@ sub CallWithStruct($$$$)
pidl "ZERO_STRUCT(r->out);" if ($hasout);
my $proto = "_$fn->{NAME}(struct pipes_struct *p, struct $fn->{NAME} *r";
my $ret = "_$fn->{NAME}($pipes_struct, r";
foreach (@{$fn->{ELEMENTS}}) {
my @dir = @{$_->{DIRECTION}};
if (grep(/in/, @dir) and grep(/out/, @dir)) {
@ -116,20 +119,22 @@ sub CallWithStruct($$$$)
# noop
} elsif (grep(/out/, @dir) and not
has_property($_, "represent_as")) {
AllocOutVar($_, $mem_ctx, "r->out.$_->{NAME}", $env, $fail);
AllocOutVar($_, $mem_ctx, "r->out.$_->{NAME}", $env,
$check, $cleanup, $return);
}
}
$ret .= ")";
$proto .= ");";
my $proto = "_$fn->{NAME}(struct pipes_struct *p, struct $fn->{NAME} *r)";
my $ret = "_$fn->{NAME}($pipes_struct, r)";
if ($fn->{RETURN_TYPE}) {
$ret = "r->out.result = $ret";
$proto = "$fn->{RETURN_TYPE} $proto";
$proto = mapTypeName($fn->{RETURN_TYPE})." $proto";
} else {
$proto = "void $proto";
}
pidl_hdr "$proto";
pidl_hdr "$proto;";
pidl "$ret;";
}
@ -176,10 +181,18 @@ sub ParseFunction($$)
pidl "}";
pidl "";
CallWithStruct("p", "r", $fn,
sub {
pidl "\ttalloc_free(r);";
pidl "\treturn false;";
CallWithStruct("p", "r", $fn,
sub ($) {
my ($name) = @_;
return "${name} == NULL";
},
sub ($) {
my ($name) = @_;
return "talloc_free(r);";
},
sub ($) {
my ($name) = @_;
return "return false;";
}
);
@ -286,8 +299,7 @@ sub Parse($$$)
{
my($ndr,$header,$ndr_header) = @_;
$res = "";
$res_hdr = "";
pidl_reset();
pidl "/*";
pidl " * Unix SMB/CIFS implementation.";
@ -304,7 +316,7 @@ sub Parse($$$)
ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
}
return ($res, $res_hdr);
return pidl_return();
}
1;

View File

@ -11,7 +11,7 @@ use Exporter;
@EXPORT_OK = qw(Parse);
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property ParseExpr);
use Parse::Pidl::Util qw(has_property ParseExpr genpad);
use Parse::Pidl::NDR qw(ContainsPipe);
use Parse::Pidl::Typelist qw(mapTypeName);
use Parse::Pidl::Samba4 qw(choose_header is_intree DeclLong);
@ -29,15 +29,6 @@ sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
sub pidl_both($$) { my ($self, $txt) = @_; $self->{hdr} .= "$txt\n"; $self->{res_hdr} .= "$txt\n"; }
sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
sub genpad($)
{
my ($s) = @_;
my $nt = int((length($s)+1)/8);
my $lt = ($nt*8)-1;
my $ns = (length($s)-$lt);
return "\t"x($nt)." "x($ns);
}
sub new($)
{
my ($class) = shift;

View File

@ -670,7 +670,7 @@ sub ParseElementPushLevel
$var_name = get_array_element($var_name, $counter);
if ((($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) and not $array_pointless) {
$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");
$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
$self->indent;
$self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 1, 0);
$self->deindent;
@ -678,12 +678,12 @@ sub ParseElementPushLevel
}
if ($deferred and ContainsDeferred($e, $l) and not $array_pointless) {
$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");
$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
$self->indent;
$self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 0, 1);
$self->deindent;
$self->pidl("}");
}
}
} elsif ($l->{TYPE} eq "SWITCH") {
$self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, $primitives, $deferred);
}
@ -737,13 +737,15 @@ sub ParsePtrPush($$$$$)
my ($self,$e,$l,$ndr,$var_name) = @_;
if ($l->{POINTER_TYPE} eq "ref") {
$self->pidl("if ($var_name == NULL) {");
$self->indent;
$self->pidl("return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");");
$self->deindent;
$self->pidl("}");
if ($l->{LEVEL_INDEX} > 0) {
$self->pidl("if ($var_name == NULL) {");
$self->indent;
$self->pidl("return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");");
$self->deindent;
$self->pidl("}");
}
if ($l->{LEVEL} eq "EMBEDDED") {
$self->pidl("NDR_CHECK(ndr_push_ref_ptr(ndr));");
$self->pidl("NDR_CHECK(ndr_push_ref_ptr(ndr)); /* $var_name */");
}
} elsif ($l->{POINTER_TYPE} eq "relative") {
$self->pidl("NDR_CHECK(ndr_push_relative_ptr1($ndr, $var_name));");
@ -875,7 +877,7 @@ sub ParseElementPrint($$$$$)
$self->pidl("$ndr->print($ndr, \"\%s: ARRAY(\%d)\", \"$e->{NAME}\", (int)$length);");
$self->pidl("$ndr->depth++;");
$self->pidl("for ($counter=0;$counter<$length;$counter++) {");
$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
$self->indent;
$var_name = get_array_element($var_name, $counter);
@ -1203,7 +1205,7 @@ sub ParseElementPullLevel
$self->CheckStringTerminator($ndr,$e,$l,$length);
}
$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");
$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
$self->indent;
$self->ParseElementPullLevel($e, $nl, $ndr, $var_name, $env, 1, 0);
$self->deindent;
@ -1211,7 +1213,7 @@ sub ParseElementPullLevel
}
if ($deferred and ContainsDeferred($e, $l)) {
$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");
$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
$self->indent;
$self->ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 0, 1);
$self->deindent;
@ -1331,10 +1333,30 @@ sub ParsePtrPull($$$$$)
$self->pidl("}");
}
sub CheckRefPtrs($$$$)
{
my ($self,$e,$ndr,$env) = @_;
return if ContainsPipe($e, $e->{LEVELS}[0]);
return if ($e->{LEVELS}[0]->{TYPE} ne "POINTER");
return if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref");
my $var_name = $env->{$e->{NAME}};
$var_name = append_prefix($e, $var_name);
$self->pidl("if ($var_name == NULL) {");
$self->indent;
$self->pidl("return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");");
$self->deindent;
$self->pidl("}");
}
sub ParseStructPushPrimitives($$$$$)
{
my ($self, $struct, $ndr, $varname, $env) = @_;
$self->CheckRefPtrs($_, $ndr, $env) foreach (@{$struct->{ELEMENTS}});
# see if the structure contains a conformant array. If it
# does, then it must be the last element of the structure, and
# we need to push the conformant length early, as it fits on
@ -1666,7 +1688,7 @@ sub DeclareMemCtxVariables($$)
}
if (defined($mem_flags)) {
$self->pidl("TALLOC_CTX *_mem_save_$e->{NAME}_$l->{LEVEL_INDEX};");
$self->pidl("TALLOC_CTX *_mem_save_$e->{NAME}_$l->{LEVEL_INDEX} = NULL;");
}
}
}
@ -1834,7 +1856,9 @@ sub ParseUnionPushPrimitives($$$$)
$self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset1($ndr, $varname, $ndr->offset));");
}
$self->DeclareArrayVariables($el);
$self->ParseElementPush($el, $ndr, {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0);
my $el_env = {$el->{NAME} => "$varname->$el->{NAME}"};
$self->CheckRefPtrs($el, $ndr, $el_env);
$self->ParseElementPush($el, $ndr, $el_env, 1, 0);
$self->deindent;
}
$self->pidl("break; }");
@ -2363,6 +2387,12 @@ sub ParseFunctionPush($$)
EnvSubstituteValue($env, $fn);
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/in/,@{$e->{DIRECTION}})) {
$self->CheckRefPtrs($e, $ndr, $env);
}
}
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/in/,@{$e->{DIRECTION}})) {
$self->ParseElementPush($e, $ndr, $env, 1, 1);
@ -2376,6 +2406,14 @@ sub ParseFunctionPush($$)
$self->indent;
$env = GenerateFunctionOutEnv($fn);
EnvSubstituteValue($env, $fn);
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/out/,@{$e->{DIRECTION}})) {
$self->CheckRefPtrs($e, $ndr, $env);
}
}
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/out/,@{$e->{DIRECTION}})) {
$self->ParseElementPush($e, $ndr, $env, 1, 1);

View File

@ -322,6 +322,7 @@ sub Parse($$)
$res = "";
$res .= "/* server functions auto-generated by pidl */\n";
$res .= "#include \"$header\"\n";
$res .= "#include <util/debug.h>\n";
$res .= "\n";
foreach my $x (@{$ndr}) {

View File

@ -10,7 +10,7 @@ use Exporter;
use strict;
use Parse::Pidl qw(warning fatal error);
use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias);
use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias bitmap_type_fn enum_type_fn);
use Parse::Pidl::Util qw(has_property ParseExpr unmake_str);
use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
@ -112,7 +112,7 @@ sub EnumAndBitmapConsts($$$)
foreach my $e (@{$d->{ELEMENTS}}) {
$e =~ /^([A-Za-z0-9_]+)/;
my $cname = $1;
$self->register_constant($cname, $d, $cname);
}
}
@ -221,10 +221,10 @@ sub PythonStruct($$$$$$)
my $mem_ctx = "pytalloc_get_mem_ctx(py_obj)";
my $l = $e->{LEVELS}[0];
my $nl = GetNextLevel($e, $l);
if ($l->{TYPE} eq "POINTER" and
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_unlink(pytalloc_get_mem_ctx(py_obj), $varname);");
$self->pidl("talloc_unlink(pytalloc_get_mem_ctx(py_obj), discard_const($varname));");
}
$self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;");
$self->pidl("return 0;");
@ -237,9 +237,16 @@ sub PythonStruct($$$$$$)
$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("{");
$self->indent;
$self->pidl(".name = discard_const_p(char, \"$e->{NAME}\"),");
$self->pidl(".get = py_$name\_get_$e->{NAME},");
$self->pidl(".set = py_$name\_set_$e->{NAME},");
$self->pidl(".doc = discard_const_p(char, \"PIDL-generated element $e->{NAME}\")");
$self->deindent;
$self->pidl("},");
}
$self->pidl("{ NULL }");
$self->pidl("{ .name = NULL }");
$self->deindent;
$self->pidl("};");
$self->pidl("");
@ -255,7 +262,7 @@ sub PythonStruct($$$$$$)
my $py_methods = "NULL";
# If the struct is not public there ndr_pull/ndr_push functions will
# 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)");
@ -282,7 +289,7 @@ sub PythonStruct($$$$$$)
$self->indent;
$self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
$self->pidl("DATA_BLOB blob;");
$self->pidl("int blob_length = 0;");
$self->pidl("Py_ssize_t blob_length = 0;");
$self->pidl("enum ndr_err_code err;");
$self->pidl("const char * const kwnames[] = { \"data_blob\", \"allow_remaining\", NULL };");
$self->pidl("PyObject *allow_remaining_obj = NULL;");
@ -355,7 +362,7 @@ sub PythonStruct($$$$$$)
$self->pidl("");
}
$self->pidl_hdr("staticforward PyTypeObject $name\_Type;\n");
$self->pidl_hdr("static PyTypeObject $name\_Type;\n");
$self->pidl("");
my $docstring = $self->DocString($d, $name);
my $typeobject = "$name\_Type";
@ -405,8 +412,8 @@ sub find_metadata_args($)
foreach my $e (@{$fn->{ELEMENTS}}) {
foreach my $dir (@{$e->{DIRECTION}}) {
my $main = get_metadata_var($e);
if ($main) {
$metadata_args->{$dir}->{$main} = $e->{NAME};
if ($main) {
$metadata_args->{$dir}->{$main} = $e->{NAME};
}
}
}
@ -432,7 +439,7 @@ sub PythonFunctionUnpackOut($$$)
$self->pidl("PyObject *result;");
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless (grep(/out/,@{$e->{DIRECTION}}));
next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or
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++;
@ -515,7 +522,7 @@ sub PythonFunctionPackIn($$$)
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless (grep(/in/,@{$e->{DIRECTION}}));
next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or
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};");
$args_format .= "O";
@ -645,6 +652,7 @@ sub PythonType($$$$)
if ($actual_ctype->{TYPE} eq "UNION" and defined($actual_ctype->{ELEMENTS})) {
$self->pidl("PyObject *py_import_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, " .mapTypeName($d) . " *in)");
$self->pidl_hdr("PyObject *py_import_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, " .mapTypeName($d) . " *in);\n");
$self->pidl("{");
$self->indent;
$self->FromUnionToPythonFunction("mem_ctx", $actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION");
@ -653,6 +661,7 @@ sub PythonType($$$$)
$self->pidl("");
$self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, PyObject *in)");
$self->pidl_hdr(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, PyObject *in);\n");
$self->pidl("{");
$self->indent;
$self->FromPythonToUnionFunction($actual_ctype, mapTypeName($d), "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION");
@ -691,7 +700,7 @@ sub Interface($$$)
}
if (defined $interface->{PROPERTIES}->{uuid}) {
$self->pidl_hdr("staticforward PyTypeObject $interface->{NAME}_InterfaceType;\n");
$self->pidl_hdr("static PyTypeObject $interface->{NAME}_InterfaceType;\n");
$self->pidl("");
my @fns = ();
@ -737,10 +746,10 @@ sub Interface($$$)
$self->pidl("return py_dcerpc_interface_init_helper(type, args, kwargs, &ndr_table_$interface->{NAME});");
$self->deindent;
$self->pidl("}");
$self->pidl("");
my $signature =
my $signature =
"\"$interface->{NAME}(binding, lp_ctx=None, credentials=None) -> connection\\n\"
\"\\n\"
\"binding should be a DCE/RPC binding string (for example: ncacn_ip_tcp:127.0.0.1)\\n\"
@ -874,7 +883,7 @@ sub import_type_variable($$$)
sub use_type_variable($$)
{
my ($self, $orig_ctype) = @_;
# FIXME: Have a global lookup table for types that look different on the
# FIXME: Have a global lookup table for types that look different on the
# wire than they are named in C?
if ($orig_ctype->{NAME} eq "dom_sid2" or
$orig_ctype->{NAME} eq "dom_sid28" or
@ -951,14 +960,58 @@ sub ConvertObjectFromPythonData($$$$$$;$)
$actual_ctype = $actual_ctype->{DATA};
}
if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP") {
# We need to cover ENUMs, BITMAPS and SCALAR values here, as
# all could otherwise be assigned invalid integer values
my $ctype_alias = "";
my $uint_max = "";
if ($actual_ctype->{TYPE} eq "ENUM") {
# Importantly, ENUM values are unsigned in pidl, and
# typically map to uint32
$ctype_alias = enum_type_fn($actual_ctype);
} elsif ($actual_ctype->{TYPE} eq "BITMAP") {
$ctype_alias = bitmap_type_fn($actual_ctype);
} elsif ($actual_ctype->{TYPE} eq "SCALAR") {
$ctype_alias = expandAlias($actual_ctype->{NAME});
}
# This is the unsigned Python Integer -> C integer validation
# case. The signed case is below.
if ($ctype_alias =~ /^(uint[0-9]*|hyper|udlong|udlongr
|NTTIME_hyper|NTTIME|NTTIME_1sec
|uid_t|gid_t)$/x) {
$self->pidl("{");
$self->indent;
$self->pidl("const unsigned long long uint_max = ndr_sizeof2uintmax(sizeof($target));");
$self->pidl("if (PyLong_Check($cvar)) {");
$self->indent;
$self->pidl("$target = PyLong_AsLongLong($cvar);");
$self->pidl("unsigned long long test_var;");
$self->pidl("test_var = PyLong_AsUnsignedLongLong($cvar);");
$self->pidl("if (PyErr_Occurred() != NULL) {");
$self->indent;
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
$self->pidl("if (test_var > uint_max) {");
$self->indent;
$self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %llu\",\\");
$self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
$self->pidl("$target = test_var;");
$self->deindent;
$self->pidl("} else if (PyInt_Check($cvar)) {");
$self->indent;
$self->pidl("$target = PyInt_AsLong($cvar);");
$self->pidl("long test_var;");
$self->pidl("test_var = PyInt_AsLong($cvar);");
$self->pidl("if (test_var < 0 || test_var > uint_max) {");
$self->indent;
$self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %ld\",\\");
$self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
$self->pidl("$target = test_var;");
$self->deindent;
$self->pidl("} else {");
$self->indent;
@ -967,32 +1020,61 @@ sub ConvertObjectFromPythonData($$$$$$;$)
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
$self->deindent;
$self->pidl("}");
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" ) {
if (expandAlias($actual_ctype->{NAME}) =~ /^(u?int64|hyper|dlong|udlong|udlongr|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) {
$self->pidl("if (PyLong_Check($cvar)) {");
$self->indent;
$self->pidl("$target = PyLong_AsLongLong($cvar);");
$self->deindent;
$self->pidl("} else if (PyInt_Check($cvar)) {");
$self->indent;
$self->pidl("$target = PyInt_AsLong($cvar);");
$self->deindent;
$self->pidl("} else {");
$self->indent;
$self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
$self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
return;
}
if (expandAlias($actual_ctype->{NAME}) =~ /^(char|u?int[0-9]*|time_t|uid_t|gid_t)$/) {
$self->pidl("PY_CHECK_TYPE(&PyInt_Type, $cvar, $fail);");
$self->pidl("$target = PyInt_AsLong($cvar);");
return;
}
# Confirm the signed python integer fits in the C type
# correctly. It is subtly different from the unsigned case
# above, so while it looks like a duplicate, it is not
# actually a duplicate.
if ($ctype_alias =~ /^(dlong|char|int[0-9]*|time_t)$/x) {
$self->pidl("{");
$self->indent;
$self->pidl("const long long int_max = ndr_sizeof2intmax(sizeof($target));");
$self->pidl("const long long int_min = -int_max - 1;");
$self->pidl("if (PyLong_Check($cvar)) {");
$self->indent;
$self->pidl("long long test_var;");
$self->pidl("test_var = PyLong_AsLongLong($cvar);");
$self->pidl("if (PyErr_Occurred() != NULL) {");
$self->indent;
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
$self->pidl("if (test_var < int_min || test_var > int_max) {");
$self->indent;
$self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %lld\",\\");
$self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
$self->pidl("$target = test_var;");
$self->deindent;
$self->pidl("} else if (PyInt_Check($cvar)) {");
$self->indent;
$self->pidl("long test_var;");
$self->pidl("test_var = PyInt_AsLong($cvar);");
$self->pidl("if (test_var < int_min || test_var > int_max) {");
$self->indent;
$self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %ld\",\\");
$self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
$self->pidl("$target = test_var;");
$self->deindent;
$self->pidl("} else {");
$self->indent;
$self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
$self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
$self->deindent;
$self->pidl("}");
return;
}
if ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
@ -1018,7 +1100,7 @@ sub ConvertObjectFromPythonData($$$$$$;$)
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and
if ($actual_ctype->{TYPE} eq "SCALAR" and
($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) {
$self->pidl("$target = talloc_strdup($mem_ctx, PyString_AS_STRING($cvar));");
return;
@ -1059,6 +1141,11 @@ sub ConvertObjectFromPythonData($$$$$$;$)
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "HRESULT") {
$self->pidl("$target = HRES_ERROR(PyInt_AsLong($cvar));");
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") {
$self->pidl("$target = PyCObject_AsVoidPtr($cvar);");
return;
@ -1143,6 +1230,13 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
$self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_GET_SIZE($py_var));");
$self->pidl("if (!$var_name) { $fail; }");
$self->pidl("talloc_set_name_const($var_name, \"ARRAY: $var_name\");");
} else {
$self->pidl("if (ARRAY_SIZE($var_name) != PyList_GET_SIZE($py_var)) {");
$self->indent;
$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));");
$self->pidl("$fail");
$self->deindent;
$self->pidl("}");
}
$self->pidl("for ($counter = 0; $counter < PyList_GET_SIZE($py_var); $counter++) {");
$self->indent;
@ -1192,14 +1286,30 @@ sub ConvertScalarToPython($$$)
$ctypename = expandAlias($ctypename);
if ($ctypename =~ /^(u?int64|hyper|dlong|udlong|udlongr|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) {
return "PyLong_FromLongLong($cvar)";
if ($ctypename =~ /^(int64|dlong)$/) {
return "ndr_PyLong_FromLongLong($cvar)";
}
if ($ctypename =~ /^(char|u?int[0-9]*|time_t|uid_t|gid_t)$/) {
if ($ctypename =~ /^(uint64|hyper|NTTIME_hyper|NTTIME|NTTIME_1sec|udlong|udlongr|uid_t|gid_t)$/) {
return "ndr_PyLong_FromUnsignedLongLong($cvar)";
}
if ($ctypename =~ /^(char|int|int8|int16|int32|time_t)$/) {
return "PyInt_FromLong($cvar)";
}
# Needed to ensure unsigned values in a 32 or 16 bit enum is
# cast correctly to a uint32_t, not sign extended to a a
# possibly 64 bit unsigned long. (enums are signed in C,
# unsigned in NDR)
if ($ctypename =~ /^(uint32|uint3264)$/) {
return "ndr_PyLong_FromUnsignedLongLong((uint32_t)$cvar)";
}
if ($ctypename =~ /^(uint|uint8|uint16|uint1632)$/) {
return "PyInt_FromLong((uint16_t)$cvar)";
}
if ($ctypename eq "DATA_BLOB") {
return "PyString_FromStringAndSize((char *)($cvar).data, ($cvar).length)";
}
@ -1212,6 +1322,10 @@ sub ConvertScalarToPython($$$)
return "PyErr_FromWERROR($cvar)";
}
if ($ctypename eq "HRESULT") {
return "PyErr_FromHRESULT($cvar)";
}
if (($ctypename eq "string" or $ctypename eq "nbt_string" or $ctypename eq "nbt_name" or $ctypename eq "wrepl_nbt_name")) {
return "PyString_FromStringOrNULL($cvar)";
}
@ -1244,8 +1358,8 @@ sub ConvertObjectToPythonData($$$$$;$)
my $actual_ctype = $ctype;
if ($actual_ctype->{TYPE} eq "TYPEDEF") {
$actual_ctype = $actual_ctype->{DATA};
}
}
if ($actual_ctype->{TYPE} eq "ENUM") {
return $self->ConvertScalarToPython(Parse::Pidl::Typelist::enum_type_fn($actual_ctype), $cvar);
} elsif ($actual_ctype->{TYPE} eq "BITMAP") {
@ -1338,7 +1452,7 @@ sub ConvertObjectToPythonLevel($$$$$$)
$self->indent;
my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}";
$self->pidl("int $counter;");
$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");
$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
$self->indent;
my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}";
$self->pidl("PyObject *$member_var;");
@ -1383,6 +1497,7 @@ sub Parse($$$$$)
$self->pidl_hdr("
/* Python wrapper functions auto-generated by pidl */
#define PY_SSIZE_T_CLEAN 1 /* We use Py_ssize_t for PyArg_ParseTupleAndKeywords */
#include <Python.h>
#include \"includes.h\"
#include <pytalloc.h>
@ -1391,13 +1506,68 @@ sub Parse($$$$$)
#include \"$hdr\"
#include \"$ndr_hdr\"
/*
* These functions are here to ensure they can be optimized out by
* the compiler based on the constant input values
*/
static inline unsigned long long ndr_sizeof2uintmax(size_t var_size)
{
switch (var_size) {
case 8:
return UINT64_MAX;
case 4:
return UINT32_MAX;
case 2:
return UINT16_MAX;
case 1:
return UINT8_MAX;
}
return 0;
}
static inline long long ndr_sizeof2intmax(size_t var_size)
{
switch (var_size) {
case 8:
return INT64_MAX;
case 4:
return INT32_MAX;
case 2:
return INT16_MAX;
case 1:
return INT8_MAX;
}
return 0;
}
static inline PyObject *ndr_PyLong_FromLongLong(long long v)
{
if (v > LONG_MAX || v < LONG_MIN) {
return PyLong_FromLongLong(v);
} else {
return PyInt_FromLong(v);
}
}
static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
{
if (v > LONG_MAX) {
return PyLong_FromUnsignedLongLong(v);
} else {
return PyInt_FromLong(v);
}
}
");
foreach my $x (@$ndr) {
($x->{TYPE} eq "IMPORT") && $self->Import(@{$x->{PATHS}});
($x->{TYPE} eq "INTERFACE") && $self->Interface($x, $basename);
}
$self->pidl("static PyMethodDef $basename\_methods[] = {");
$self->indent;
foreach (@{$self->{module_methods}}) {
@ -1470,7 +1640,7 @@ sub Parse($$$$$)
my $py_obj;
my ($ctype, $cvar) = @{$h->{'val'}};
if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) {
$py_obj = "PyInt_FromLong($cvar)";
$py_obj = "ndr_PyLong_FromUnsignedLongLong($cvar)";
} elsif ($cvar =~ /^".*"$/) {
$py_obj = "PyString_FromString($cvar)";
} else {

View File

@ -8,6 +8,8 @@ package Parse::Pidl::Samba4::Template;
use vars qw($VERSION);
$VERSION = '0.01';
use Parse::Pidl::Util qw(genpad);
use strict;
my($res);
@ -20,24 +22,24 @@ sub Template($)
my($data) = $interface->{DATA};
my $name = $interface->{NAME};
$res .=
"/*
$res .=
"/*
Unix SMB/CIFS implementation.
endpoint server for the $name pipe
Copyright (C) YOUR NAME HERE YEAR
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@ -52,13 +54,16 @@ sub Template($)
foreach my $d (@{$data}) {
if ($d->{TYPE} eq "FUNCTION") {
my $fname = $d->{NAME};
my $pad = genpad("static $d->{RETURN_TYPE} dcesrv_$fname");
$res .=
"
/*
$fname
/*
$fname
*/
static $d->{RETURN_TYPE} dcesrv_$fname(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct $fname *r)
static $d->{RETURN_TYPE} dcesrv_$fname(struct dcesrv_call_state *dce_call,
$pad"."TALLOC_CTX *mem_ctx,
$pad"."struct $fname *r)
{
";
@ -74,7 +79,7 @@ static $d->{RETURN_TYPE} dcesrv_$fname(struct dcesrv_call_state *dce_call, TALLO
}
}
$res .=
$res .=
"
/* include the generated boilerplate */
#include \"librpc/gen_ndr/ndr_$name\_s.c\"
@ -89,7 +94,7 @@ sub Parse($)
my($idl) = shift;
$res = "";
foreach my $x (@{$idl}) {
($x->{TYPE} eq "INTERFACE") &&
($x->{TYPE} eq "INTERFACE") &&
Template($x);
}
return $res;

View File

@ -60,6 +60,7 @@ my %scalars = (
"NTTIME_1sec" => "NTTIME",
"NTTIME_hyper" => "NTTIME",
"WERROR" => "WERROR",
"HRESULT" => "HRESULT",
"NTSTATUS" => "NTSTATUS",
"COMRESULT" => "COMRESULT",
"dns_string" => "const char *",
@ -83,7 +84,6 @@ my %aliases = (
"long" => "int32",
"short" => "int16",
"HYPER_T" => "hyper",
"HRESULT" => "COMRESULT",
"mode_t" => "uint32",
);

View File

@ -6,7 +6,7 @@ package Parse::Pidl::Util;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(has_property property_matches ParseExpr ParseExprExt is_constant make_str unmake_str print_uuid MyDumper);
@EXPORT = qw(has_property property_matches ParseExpr ParseExprExt is_constant make_str unmake_str print_uuid MyDumper genpad);
use vars qw($VERSION);
$VERSION = '0.01';
@ -176,6 +176,20 @@ sub ParseExprExt($$$$$)
$deref, $use);
}
=item B<genpad>
return an empty string consisting of tabs and spaces suitable for proper indent
of C-functions.
=cut
sub genpad($)
{
my ($s) = @_;
my $nt = int((length($s)+1)/8);
my $lt = ($nt*8)-1;
my $ns = (length($s)-$lt);
return "\t"x($nt)." "x($ns);
}
=back
=cut

View File

@ -718,11 +718,6 @@ sub Struct($$$$)
$self->pidl_code("int old_offset;");
$self->pidl_code("");
if ($e->{ALIGN} > 1 and not property_matches($e, "flag", ".*LIBNDR_FLAG_NOALIGN.*")) {
$self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
}
$self->pidl_code("");
if (defined($doalign)) {
if ($doalign == 1) {
$self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");

0
tools/pidl/lib/wscript_build Executable file → Normal file
View File

View File

@ -191,7 +191,7 @@ the wire representation. It does not make the array a fixed array.
midl.exe would write the above array as the following C header:
typedef struct {
typedef struct {
long abc;
long count;
long foo;
@ -381,8 +381,7 @@ usesgetlasterror, vararg, vi_progid, wire_marshal.
=head1 SEE ALSO
# Dead link
# L<http://msdn.microsoft.com/library/en-us/rpc/rpc/field_attributes.asp>,
L<https://msdn.microsoft.com/en-us/library/windows/desktop/aa373864%28v=vs.85%29.aspx>
L<https://wiki.wireshark.org/DCE/RPC>,
L<https://www.samba.org/>,
L<yapp(1)>
@ -470,6 +469,7 @@ my($opt_samba3_parser);
my($opt_samba3_server);
my($opt_samba3_ndr_client);
my($opt_samba3_ndr_server);
my($opt_samba3_template) = 0;
my($opt_template) = 0;
my($opt_client);
my($opt_typelib);
@ -530,6 +530,7 @@ Samba 3 output:
using Samba4's NDR code [cli_BASENAME.c]
--samba3-ndr-server[=OUTF] create server call wrapper for Samba3
using Samba4's NDR code [srv_BASENAME.c]
--samba3-template print a template for a pipe
Wireshark parsers:
--ws-parser[=OUTFILE] create Wireshark parser and header
@ -555,6 +556,7 @@ my $result = GetOptions (
'dump-ndr-tree:s' => \$opt_dump_ndr_tree,
'samba3-ndr-client:s' => \$opt_samba3_ndr_client,
'samba3-ndr-server:s' => \$opt_samba3_ndr_server,
'samba3-template' => \$opt_samba3_template,
'header:s' => \$opt_header,
'server:s' => \$opt_server,
'typelib:s' => \$opt_typelib,
@ -665,17 +667,17 @@ sub process_file($)
if (defined($opt_ws_parser) or
defined($opt_client) or
defined($opt_server) or
defined($opt_header) or
defined($opt_ndr_parser) or
defined($opt_python) or
defined($opt_dump_ndr_tree) or
defined($opt_samba3_header) or
defined($opt_samba3_parser) or
defined($opt_samba3_server) or
defined($opt_samba3_ndr_client) or
defined($opt_samba3_ndr_server)) {
defined($opt_client) or
defined($opt_server) or
defined($opt_header) or
defined($opt_ndr_parser) or
defined($opt_python) or
defined($opt_dump_ndr_tree) or
defined($opt_samba3_header) or
defined($opt_samba3_parser) or
defined($opt_samba3_server) or
defined($opt_samba3_ndr_client) or
defined($opt_samba3_ndr_server)) {
require Parse::Pidl::NDR;
$ndr = Parse::Pidl::NDR::Parse($pidl);
}
@ -768,6 +770,11 @@ sub process_file($)
print Parse::Pidl::Samba4::Template::Parse($pidl);
}
if ($opt_samba3_template) {
require Parse::Pidl::Samba3::Template;
print Parse::Pidl::Samba3::Template::Parse($pidl);
}
if (defined($opt_samba3_ndr_client)) {
my $client = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c");
my $header = $client; $header =~ s/\.c$/\.h/;

5
tools/pidl/wscript Executable file → Normal file
View File

@ -1,13 +1,12 @@
#!/usr/bin/env python
import os, sys, Logs
import os, Logs
from samba_utils import MODE_755
# This function checks if a perl module is installed on the system.
def check_system_perl_module(conf, module, version=None):
bundle_name = module.replace('::', '_')
module_check = module
found = False
# Create module string with version
if version:
@ -65,8 +64,6 @@ def build(bld):
# use perl to build the manpages
bld.env.pidl_srcdir = os.path.join(bld.srcnode.abspath(), 'pidl')
blib_bld = os.path.join(bld.srcnode.abspath(bld.env), 'pidl/blib')
bld.SET_BUILD_GROUP('final')
if 'POD2MAN' in bld.env and bld.env['POD2MAN'] != '':
for src, manpage in pidl_manpages.iteritems():