|
|
|
@ -14,7 +14,7 @@ require Exporter;
|
|
|
|
|
use strict;
|
|
|
|
|
use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody);
|
|
|
|
|
use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid);
|
|
|
|
|
use Parse::Pidl::CUtil qw(get_pointer_to get_value_of);
|
|
|
|
|
use Parse::Pidl::CUtil qw(get_pointer_to get_value_of get_array_element);
|
|
|
|
|
use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);
|
|
|
|
|
use Parse::Pidl::Samba4 qw(is_intree choose_header);
|
|
|
|
|
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
|
|
|
|
@ -42,19 +42,21 @@ sub append_prefix($$)
|
|
|
|
|
{
|
|
|
|
|
my ($e, $var_name) = @_;
|
|
|
|
|
my $pointers = 0;
|
|
|
|
|
my $arrays = 0;
|
|
|
|
|
|
|
|
|
|
foreach my $l (@{$e->{LEVELS}}) {
|
|
|
|
|
if ($l->{TYPE} eq "POINTER") {
|
|
|
|
|
$pointers++;
|
|
|
|
|
} elsif ($l->{TYPE} eq "ARRAY") {
|
|
|
|
|
$arrays++;
|
|
|
|
|
if (($pointers == 0) and
|
|
|
|
|
(not $l->{IS_FIXED}) and
|
|
|
|
|
(not $l->{IS_INLINE})) {
|
|
|
|
|
return get_value_of($var_name);
|
|
|
|
|
return get_value_of($var_name);
|
|
|
|
|
}
|
|
|
|
|
} elsif ($l->{TYPE} eq "DATA") {
|
|
|
|
|
if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
|
|
|
|
|
return get_value_of($var_name) unless ($pointers);
|
|
|
|
|
return get_value_of($var_name) unless ($pointers or $arrays);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -375,7 +377,7 @@ sub ParseArrayPullHeader($$$$$$)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (not $l->{IS_FIXED} and not is_charset_array($e, $l)) {
|
|
|
|
|
$self->AllocateArrayLevel($e,$l,$ndr,$env,$size);
|
|
|
|
|
$self->AllocateArrayLevel($e,$l,$ndr,$var_name,$size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $length;
|
|
|
|
@ -384,7 +386,7 @@ sub ParseArrayPullHeader($$$$$$)
|
|
|
|
|
sub compression_alg($$)
|
|
|
|
|
{
|
|
|
|
|
my ($e, $l) = @_;
|
|
|
|
|
my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
|
|
|
|
|
my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION});
|
|
|
|
|
|
|
|
|
|
return $alg;
|
|
|
|
|
}
|
|
|
|
@ -392,7 +394,7 @@ sub compression_alg($$)
|
|
|
|
|
sub compression_clen($$$)
|
|
|
|
|
{
|
|
|
|
|
my ($e, $l, $env) = @_;
|
|
|
|
|
my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
|
|
|
|
|
my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION});
|
|
|
|
|
|
|
|
|
|
return ParseExpr($clen, $env, $e->{ORIGINAL});
|
|
|
|
|
}
|
|
|
|
@ -400,7 +402,7 @@ sub compression_clen($$$)
|
|
|
|
|
sub compression_dlen($$$)
|
|
|
|
|
{
|
|
|
|
|
my ($e,$l,$env) = @_;
|
|
|
|
|
my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
|
|
|
|
|
my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION});
|
|
|
|
|
|
|
|
|
|
return ParseExpr($dlen, $env, $e->{ORIGINAL});
|
|
|
|
|
}
|
|
|
|
@ -582,7 +584,7 @@ sub ParseElementPushLevel
|
|
|
|
|
my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL});
|
|
|
|
|
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
|
|
|
|
|
|
|
|
|
|
$var_name = $var_name . "[$counter]";
|
|
|
|
|
$var_name = get_array_element($var_name, $counter);
|
|
|
|
|
|
|
|
|
|
if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) {
|
|
|
|
|
$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");
|
|
|
|
@ -669,23 +671,48 @@ sub ParsePtrPush($$$$)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub need_pointer_to($$$)
|
|
|
|
|
{
|
|
|
|
|
my ($e, $l, $scalar_only) = @_;
|
|
|
|
|
|
|
|
|
|
my $t;
|
|
|
|
|
if (ref($l->{DATA_TYPE})) {
|
|
|
|
|
$t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
|
|
|
|
|
} else {
|
|
|
|
|
$t = $l->{DATA_TYPE};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (not Parse::Pidl::Typelist::is_scalar($t)) {
|
|
|
|
|
return 1 if $scalar_only;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $arrays = 0;
|
|
|
|
|
|
|
|
|
|
foreach my $tl (@{$e->{LEVELS}}) {
|
|
|
|
|
last if $l == $tl;
|
|
|
|
|
if ($tl->{TYPE} eq "ARRAY") {
|
|
|
|
|
$arrays++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Parse::Pidl::Typelist::scalar_is_reference($t)) {
|
|
|
|
|
return 1 unless $arrays;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub ParseDataPrint($$$$)
|
|
|
|
|
{
|
|
|
|
|
my ($self, $e, $l, $var_name) = @_;
|
|
|
|
|
|
|
|
|
|
if (not ref($l->{DATA_TYPE}) or
|
|
|
|
|
defined($l->{DATA_TYPE}->{NAME})) {
|
|
|
|
|
my $t;
|
|
|
|
|
if (ref($l->{DATA_TYPE})) {
|
|
|
|
|
$t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
|
|
|
|
|
} else {
|
|
|
|
|
$t = $l->{DATA_TYPE};
|
|
|
|
|
}
|
|
|
|
|
if (not Parse::Pidl::Typelist::is_scalar($t) or
|
|
|
|
|
Parse::Pidl::Typelist::scalar_is_reference($t)) {
|
|
|
|
|
if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
|
|
|
|
|
|
|
|
|
|
if (need_pointer_to($e, $l, 1)) {
|
|
|
|
|
$var_name = get_pointer_to($var_name);
|
|
|
|
|
}
|
|
|
|
|
$self->pidl("ndr_print_$t(ndr, \"$e->{NAME}\", $var_name);");
|
|
|
|
|
|
|
|
|
|
$self->pidl(TypeFunctionName("ndr_print", $l->{DATA_TYPE})."(ndr, \"$e->{NAME}\", $var_name);");
|
|
|
|
|
} else {
|
|
|
|
|
$self->ParseTypePrint($l->{DATA_TYPE}, $var_name);
|
|
|
|
|
}
|
|
|
|
@ -752,7 +779,7 @@ sub ParseElementPrint($$$$)
|
|
|
|
|
$self->pidl("if (idx_$l->{LEVEL_INDEX}) {");
|
|
|
|
|
$self->indent;
|
|
|
|
|
|
|
|
|
|
$var_name = $var_name . "[$counter]";
|
|
|
|
|
$var_name = get_array_element($var_name, $counter);
|
|
|
|
|
}
|
|
|
|
|
} elsif ($l->{TYPE} eq "DATA") {
|
|
|
|
|
$self->ParseDataPrint($e, $l, $var_name);
|
|
|
|
@ -815,12 +842,11 @@ sub ParseDataPull($$$$$$$)
|
|
|
|
|
{
|
|
|
|
|
my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_;
|
|
|
|
|
|
|
|
|
|
if (not ref($l->{DATA_TYPE}) or
|
|
|
|
|
defined($l->{DATA_TYPE}->{NAME})) {
|
|
|
|
|
if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
|
|
|
|
|
|
|
|
|
|
my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
|
|
|
|
|
|
|
|
|
|
if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
|
|
|
|
|
if (need_pointer_to($e, $l, 0)) {
|
|
|
|
|
$var_name = get_pointer_to($var_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -830,7 +856,7 @@ sub ParseDataPull($$$$$$$)
|
|
|
|
|
|
|
|
|
|
if (my $range = has_property($e, "range")) {
|
|
|
|
|
$var_name = get_value_of($var_name);
|
|
|
|
|
my ($low, $high) = split(/ /, $range, 2);
|
|
|
|
|
my ($low, $high) = split(/,/, $range, 2);
|
|
|
|
|
$self->pidl("if ($var_name < $low || $var_name > $high) {");
|
|
|
|
|
$self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");");
|
|
|
|
|
$self->pidl("}");
|
|
|
|
@ -845,21 +871,15 @@ sub ParseDataPush($$$$$$$)
|
|
|
|
|
my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_;
|
|
|
|
|
|
|
|
|
|
if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) {
|
|
|
|
|
my $t;
|
|
|
|
|
if (ref($l->{DATA_TYPE}) eq "HASH") {
|
|
|
|
|
$t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
|
|
|
|
|
} else {
|
|
|
|
|
$t = $l->{DATA_TYPE};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
|
|
|
|
|
|
|
|
|
|
# strings are passed by value rather than reference
|
|
|
|
|
if (not Parse::Pidl::Typelist::is_scalar($t) or
|
|
|
|
|
Parse::Pidl::Typelist::scalar_is_reference($t)) {
|
|
|
|
|
if (need_pointer_to($e, $l, 1)) {
|
|
|
|
|
$var_name = get_pointer_to($var_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
|
|
|
|
|
$self->pidl("NDR_CHECK(ndr_push_$t($ndr, $ndr_flags, $var_name));");
|
|
|
|
|
$self->pidl("NDR_CHECK(".TypeFunctionName("ndr_push", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));");
|
|
|
|
|
} else {
|
|
|
|
|
$self->ParseTypePush($l->{DATA_TYPE}, $var_name, $primitives, $deferred);
|
|
|
|
|
}
|
|
|
|
@ -890,15 +910,17 @@ sub CalcNdrFlags($$$)
|
|
|
|
|
return undef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub ParseMemCtxPullStart($$$$)
|
|
|
|
|
sub ParseMemCtxPullFlags($$$$)
|
|
|
|
|
{
|
|
|
|
|
my ($self, $e, $l, $ptr_name) = @_;
|
|
|
|
|
my ($self, $e, $l) = @_;
|
|
|
|
|
|
|
|
|
|
my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
|
|
|
|
|
my $mem_c_ctx = $ptr_name;
|
|
|
|
|
my $mem_c_flags = "0";
|
|
|
|
|
return undef unless ($l->{TYPE} eq "POINTER" or $l->{TYPE} eq "ARRAY");
|
|
|
|
|
|
|
|
|
|
return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});
|
|
|
|
|
return undef if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});
|
|
|
|
|
return undef if has_fast_array($e, $l);
|
|
|
|
|
return undef if is_charset_array($e, $l);
|
|
|
|
|
|
|
|
|
|
my $mem_flags = "0";
|
|
|
|
|
|
|
|
|
|
if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
|
|
|
|
|
my $nl = GetNextLevel($e, $l);
|
|
|
|
@ -906,12 +928,25 @@ sub ParseMemCtxPullStart($$$$)
|
|
|
|
|
my $next_is_string = (($nl->{TYPE} eq "DATA") and
|
|
|
|
|
($nl->{DATA_TYPE} eq "string"));
|
|
|
|
|
if ($next_is_array or $next_is_string) {
|
|
|
|
|
return;
|
|
|
|
|
return undef;
|
|
|
|
|
} else {
|
|
|
|
|
$mem_c_flags = "LIBNDR_FLAG_REF_ALLOC";
|
|
|
|
|
$mem_flags = "LIBNDR_FLAG_REF_ALLOC";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $mem_flags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub ParseMemCtxPullStart($$$$)
|
|
|
|
|
{
|
|
|
|
|
my ($self, $e, $l, $ptr_name) = @_;
|
|
|
|
|
|
|
|
|
|
my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
|
|
|
|
|
my $mem_c_ctx = $ptr_name;
|
|
|
|
|
my $mem_c_flags = $self->ParseMemCtxPullFlags($e, $l);
|
|
|
|
|
|
|
|
|
|
return unless defined($mem_c_flags);
|
|
|
|
|
|
|
|
|
|
$self->pidl("$mem_r_ctx = NDR_PULL_GET_MEM_CTX(ndr);");
|
|
|
|
|
$self->pidl("NDR_PULL_SET_MEM_CTX(ndr, $mem_c_ctx, $mem_c_flags);");
|
|
|
|
|
}
|
|
|
|
@ -921,21 +956,9 @@ sub ParseMemCtxPullEnd($$$)
|
|
|
|
|
my ($self, $e, $l) = @_;
|
|
|
|
|
|
|
|
|
|
my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
|
|
|
|
|
my $mem_r_flags = "0";
|
|
|
|
|
my $mem_r_flags = $self->ParseMemCtxPullFlags($e, $l);
|
|
|
|
|
|
|
|
|
|
return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});
|
|
|
|
|
|
|
|
|
|
if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
|
|
|
|
|
my $nl = GetNextLevel($e, $l);
|
|
|
|
|
my $next_is_array = ($nl->{TYPE} eq "ARRAY");
|
|
|
|
|
my $next_is_string = (($nl->{TYPE} eq "DATA") and
|
|
|
|
|
($nl->{DATA_TYPE} eq "string"));
|
|
|
|
|
if ($next_is_array or $next_is_string) {
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
$mem_r_flags = "LIBNDR_FLAG_REF_ALLOC";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return unless defined($mem_r_flags);
|
|
|
|
|
|
|
|
|
|
$self->pidl("NDR_PULL_SET_MEM_CTX(ndr, $mem_r_ctx, $mem_r_flags);");
|
|
|
|
|
}
|
|
|
|
@ -1025,7 +1048,7 @@ sub ParseElementPullLevel
|
|
|
|
|
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
|
|
|
|
|
my $array_name = $var_name;
|
|
|
|
|
|
|
|
|
|
$var_name = $var_name . "[$counter]";
|
|
|
|
|
$var_name = get_array_element($var_name, $counter);
|
|
|
|
|
|
|
|
|
|
$self->ParseMemCtxPullStart($e, $l, $array_name);
|
|
|
|
|
|
|
|
|
@ -1441,31 +1464,12 @@ sub DeclareArrayVariables($$)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub need_decl_mem_ctx($$)
|
|
|
|
|
{
|
|
|
|
|
my ($e,$l) = @_;
|
|
|
|
|
|
|
|
|
|
return 0 if has_fast_array($e,$l);
|
|
|
|
|
return 0 if is_charset_array($e,$l);
|
|
|
|
|
return 1 if (($l->{TYPE} eq "ARRAY") and not $l->{IS_FIXED});
|
|
|
|
|
|
|
|
|
|
if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
|
|
|
|
|
my $nl = GetNextLevel($e, $l);
|
|
|
|
|
my $next_is_array = ($nl->{TYPE} eq "ARRAY");
|
|
|
|
|
my $next_is_string = (($nl->{TYPE} eq "DATA") and
|
|
|
|
|
($nl->{DATA_TYPE} eq "string"));
|
|
|
|
|
return 0 if ($next_is_array or $next_is_string);
|
|
|
|
|
}
|
|
|
|
|
return 1 if ($l->{TYPE} eq "POINTER");
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub DeclareMemCtxVariables($$)
|
|
|
|
|
{
|
|
|
|
|
my ($self,$e) = @_;
|
|
|
|
|
foreach my $l (@{$e->{LEVELS}}) {
|
|
|
|
|
if (need_decl_mem_ctx($e, $l)) {
|
|
|
|
|
my $mem_flags = $self->ParseMemCtxPullFlags($e, $l);
|
|
|
|
|
if (defined($mem_flags)) {
|
|
|
|
|
$self->pidl("TALLOC_CTX *_mem_save_$e->{NAME}_$l->{LEVEL_INDEX};");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -2058,9 +2062,7 @@ sub ParseFunctionPush($$)
|
|
|
|
|
|
|
|
|
|
sub AllocateArrayLevel($$$$$$)
|
|
|
|
|
{
|
|
|
|
|
my ($self,$e,$l,$ndr,$env,$size) = @_;
|
|
|
|
|
|
|
|
|
|
my $var = ParseExpr($e->{NAME}, $env, $e->{ORIGINAL});
|
|
|
|
|
my ($self,$e,$l,$ndr,$var,$size) = @_;
|
|
|
|
|
|
|
|
|
|
my $pl = GetPrevLevel($e, $l);
|
|
|
|
|
if (defined($pl) and
|
|
|
|
@ -2236,7 +2238,7 @@ sub FunctionTable($$)
|
|
|
|
|
$interface->{PROPERTIES}->{authservice} = "\"host\"";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my @a = split / /, $interface->{PROPERTIES}->{authservice};
|
|
|
|
|
my @a = split /,/, $interface->{PROPERTIES}->{authservice};
|
|
|
|
|
my $authservice_count = $#a + 1;
|
|
|
|
|
|
|
|
|
|
$self->pidl("static const char * const $interface->{NAME}\_authservice_strings[] = {");
|
|
|
|
@ -2311,7 +2313,7 @@ sub HeaderInterface($$$)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (defined $interface->{PROPERTIES}->{helper}) {
|
|
|
|
|
$self->HeaderInclude(split / /, $interface->{PROPERTIES}->{helper});
|
|
|
|
|
$self->HeaderInclude(split /,/, $interface->{PROPERTIES}->{helper});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (defined $interface->{PROPERTIES}->{uuid}) {
|
|
|
|
|