require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(is_charset_array);
+@EXPORT_OK = qw(check_null_pointer GenerateFunctionInEnv
+ GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv NeededFunction
+ NeededElement NeededType $res NeededInterface);
use strict;
-use Parse::Pidl::Typelist qw(hasType getType mapType);
-use Parse::Pidl::Util qw(has_property ParseExpr print_uuid);
+use Parse::Pidl::Typelist qw(hasType getType mapTypeName);
+use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid);
use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
use Parse::Pidl::Samba4 qw(is_intree choose_header);
+use Parse::Pidl qw(warning);
use vars qw($VERSION);
$VERSION = '0.01';
}
}
-my $res;
+our $res;
my $deferred = [];
my $tabs = "";
$tabs = substr($tabs, 0, -1);
}
-#####################################################################
-# check that a variable we get from ParseExpr isn't a null pointer
-sub check_null_pointer($)
-{
- my $size = shift;
- if ($size =~ /^\*/) {
- my $size2 = substr($size, 1);
- pidl "if ($size2 == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;";
- }
-}
-
-#####################################################################
-# check that a variable we get from ParseExpr isn't a null pointer,
-# putting the check at the end of the structure/function
-sub check_null_pointer_deferred($)
-{
- my $size = shift;
- if ($size =~ /^\*/) {
- my $size2 = substr($size, 1);
- defer "if ($size2 == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;";
- }
-}
-
#####################################################################
# declare a function public or static, depending on its attributes
sub fn_declare($$$)
}
}
-sub GenerateStructEnv($)
+sub GenerateStructEnv($$)
{
- my $x = shift;
+ my ($x, $v) = @_;
my %env;
foreach my $e (@{$x->{ELEMENTS}}) {
- $env{$e->{NAME}} = "r->$e->{NAME}";
+ $env{$e->{NAME}} = "$v->$e->{NAME}";
}
- $env{"this"} = "r";
+ $env{"this"} = $v;
return \%env;
}
# Substitute the value() values in the env
foreach my $e (@{$s->{ELEMENTS}}) {
- next unless (my $v = has_property($e, "value"));
+ next unless (defined(my $v = has_property($e, "value")));
- $env->{$e->{NAME}} = ParseExpr($v, $env);
+ $env->{$e->{NAME}} = ParseExpr($v, $env, $e);
}
return $env;
$size = $length = "ndr_string_length($var_name, sizeof(*$var_name))";
}
} else {
- $size = ParseExpr($l->{SIZE_IS}, $env);
- $length = ParseExpr($l->{LENGTH_IS}, $env);
+ $size = ParseExpr($l->{SIZE_IS}, $env, $e);
+ $length = ParseExpr($l->{LENGTH_IS}, $env, $e);
}
if ((!$l->{IS_SURROUNDING}) and $l->{IS_CONFORMANT}) {
return $length;
}
+sub check_fully_dereferenced($$)
+{
+ my ($element, $env) = @_;
+
+ return sub ($) {
+ my $origvar = shift;
+ my $check = 0;
+
+ # Figure out the number of pointers in $ptr
+ my $expandedvar = $origvar;
+ $expandedvar =~ s/^(\**)//;
+ my $ptr = $1;
+
+ my $var = undef;
+ foreach (keys %$env) {
+ if ($env->{$_} eq $expandedvar) {
+ $var = $_;
+ last;
+ }
+ }
+
+ return($origvar) unless (defined($var));
+ my $e;
+ foreach (@{$element->{PARENT}->{ELEMENTS}}) {
+ if ($_->{NAME} eq $var) {
+ $e = $_;
+ last;
+ }
+ }
+
+ $e or die("Environment doesn't match siblings");
+
+ # See if pointer at pointer level $level
+ # needs to be checked.
+ my $nump = 0;
+ foreach (@{$e->{LEVELS}}) {
+ if ($_->{TYPE} eq "POINTER") {
+ $nump = $_->{POINTER_INDEX}+1;
+ }
+ }
+ warning($element->{ORIGINAL}, "Got pointer for `$e->{NAME}', expected fully derefenced variable") if ($nump > length($ptr));
+ return ($origvar);
+ }
+}
+
+sub check_null_pointer($$$$)
+{
+ my ($element, $env, $print_fn, $return) = @_;
+
+ return sub ($) {
+ my $expandedvar = shift;
+ my $check = 0;
+
+ # Figure out the number of pointers in $ptr
+ $expandedvar =~ s/^(\**)//;
+ my $ptr = $1;
+
+ my $var = undef;
+ foreach (keys %$env) {
+ if ($env->{$_} eq $expandedvar) {
+ $var = $_;
+ last;
+ }
+ }
+
+ if (defined($var)) {
+ my $e;
+ # lookup ptr in $e
+ foreach (@{$element->{PARENT}->{ELEMENTS}}) {
+ if ($_->{NAME} eq $var) {
+ $e = $_;
+ last;
+ }
+ }
+
+ $e or die("Environment doesn't match siblings");
+
+ # See if pointer at pointer level $level
+ # needs to be checked.
+ foreach my $l (@{$e->{LEVELS}}) {
+ if ($l->{TYPE} eq "POINTER" and
+ $l->{POINTER_INDEX} == length($ptr)) {
+ # No need to check ref pointers
+ $check = ($l->{POINTER_TYPE} ne "ref");
+ last;
+ }
+
+ if ($l->{TYPE} eq "DATA") {
+ warning($element, "too much dereferences for `$var'");
+ }
+ }
+ } else {
+ warning($element, "unknown dereferenced expression `$expandedvar'");
+ $check = 1;
+ }
+
+ $print_fn->("if ($ptr$expandedvar == NULL) $return") if $check;
+ }
+}
+
#####################################################################
# parse an array - pull side
sub ParseArrayPullHeader($$$$$)
} elsif ($l->{IS_ZERO_TERMINATED}) { # Noheader arrays
$length = $size = "ndr_get_string_size($ndr, sizeof(*$var_name))";
} else {
- $length = $size = ParseExpr($l->{SIZE_IS}, $env);
+ $length = $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
}
if ((!$l->{IS_SURROUNDING}) and $l->{IS_CONFORMANT}) {
pidl "NDR_CHECK(ndr_pull_array_size(ndr, " . get_pointer_to($var_name) . "));";
}
-
if ($l->{IS_VARYING}) {
pidl "NDR_CHECK(ndr_pull_array_length($ndr, " . get_pointer_to($var_name) . "));";
$length = "ndr_get_array_length($ndr, " . get_pointer_to($var_name) .")";
}
- check_null_pointer($length);
-
if ($length ne $size) {
pidl "if ($length > $size) {";
indent;
}
if ($l->{IS_CONFORMANT} and not $l->{IS_ZERO_TERMINATED}) {
- my $size = ParseExpr($l->{SIZE_IS}, $env);
defer "if ($var_name) {";
defer_indent;
- check_null_pointer_deferred($size);
+ my $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
defer "NDR_CHECK(ndr_check_array_size(ndr, (void*)" . get_pointer_to($var_name) . ", $size));";
defer_deindent;
defer "}";
}
if ($l->{IS_VARYING} and not $l->{IS_ZERO_TERMINATED}) {
- my $length = ParseExpr($l->{LENGTH_IS}, $env);
defer "if ($var_name) {";
defer_indent;
- check_null_pointer_deferred($length);
+ my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"),
+ check_fully_dereferenced($e, $env));
defer "NDR_CHECK(ndr_check_array_length(ndr, (void*)" . get_pointer_to($var_name) . ", $length));";
defer_deindent;
defer "}"
sub compression_alg($$)
{
- my ($e,$l) = @_;
- my $compression = $l->{COMPRESSION};
- my ($alg, $clen, $dlen) = split(/ /, $compression);
+ my ($e, $l) = @_;
+ my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
return $alg;
}
sub compression_clen($$$)
{
- my ($e,$l,$env) = @_;
- my $compression = $l->{COMPRESSION};
- my ($alg, $clen, $dlen) = split(/ /, $compression);
+ my ($e, $l, $env) = @_;
+ my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
- return ParseExpr($clen, $env);
+ return ParseExpr($clen, $env, $e->{ORIGINAL});
}
sub compression_dlen($$$)
{
my ($e,$l,$env) = @_;
- my $compression = $l->{COMPRESSION};
- my ($alg, $clen, $dlen) = split(/ /, $compression);
+ my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
- return ParseExpr($dlen, $env);
+ return ParseExpr($dlen, $env, $e->{ORIGINAL});
}
sub ParseCompressionPushStart($$$$)
{
my ($e,$l,$ndr,$env) = @_;
my $subndr = "_ndr_$e->{NAME}";
- my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE},$env);
+ my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL});
pidl "{";
indent;
{
my ($e,$l,$ndr,$env) = @_;
my $subndr = "_ndr_$e->{NAME}";
- my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE},$env);
+ my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL});
if (defined $l->{COMPRESSION}) {
ParseCompressionPushEnd($e, $l, $subndr, $env);
{
my ($e,$l,$ndr,$env) = @_;
my $subndr = "_ndr_$e->{NAME}";
- my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE},$env);
+ my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL});
pidl "{";
indent;
{
my ($e,$l,$ndr,$env) = @_;
my $subndr = "_ndr_$e->{NAME}";
- my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE},$env);
+ my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL});
if (defined $l->{COMPRESSION}) {
ParseCompressionPullEnd($e, $l, $subndr, $env);
# Allow speedups for arrays of scalar types
if (is_charset_array($e,$l)) {
- pidl "NDR_CHECK(ndr_push_charset($ndr, $ndr_flags, $var_name, $length, sizeof(" . mapType($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));";
+ pidl "NDR_CHECK(ndr_push_charset($ndr, $ndr_flags, $var_name, $length, sizeof(" . mapTypeName($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));";
return;
} elsif (has_fast_array($e,$l)) {
pidl "NDR_CHECK(ndr_push_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));";
return;
}
} elsif ($l->{TYPE} eq "SWITCH") {
- ParseSwitchPush($e, $l, $ndr, $var_name, $ndr_flags, $env);
+ ParseSwitchPush($e, $l, $ndr, $var_name, $env);
} elsif ($l->{TYPE} eq "DATA") {
- ParseDataPush($e, $l, $ndr, $var_name, $ndr_flags);
+ ParseDataPush($e, $l, $ndr, $var_name, $primitives, $deferred);
}
}
}
} elsif ($l->{TYPE} eq "ARRAY" and not has_fast_array($e,$l) and
not is_charset_array($e, $l)) {
- my $length = ParseExpr($l->{LENGTH_IS}, $env);
+ my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL});
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
$var_name = $var_name . "[$counter]";
#####################################################################
# parse scalars in a structure element
-sub ParseElementPush($$$$$$)
+sub ParseElementPush($$$$$)
{
- my ($e,$ndr,$var_prefix,$env,$primitives,$deferred) = @_;
+ my ($e,$ndr,$env,$primitives,$deferred) = @_;
my $subndr = undef;
- my $var_name = $var_prefix.$e->{NAME};
+ my $var_name = $env->{$e->{NAME}};
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
# Representation type is different from transmit_as
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
pidl "{";
indent;
my $transmit_name = "_transmit_$e->{NAME}";
- pidl mapType($e->{TYPE}) ." $transmit_name;";
+ pidl mapTypeName($e->{TYPE}) ." $transmit_name;";
pidl "NDR_CHECK(ndr_$e->{REPRESENTATION_TYPE}_to_$e->{TYPE}($var_name, " . get_pointer_to($transmit_name) . "));";
$var_name = $transmit_name;
}
start_flags($e);
- if (my $value = has_property($e, "value")) {
- $var_name = ParseExpr($value, $env);
+ if (defined(my $value = has_property($e, "value"))) {
+ $var_name = ParseExpr($value, $env, $e->{ORIGINAL});
}
ParseElementPushLevel($e, $e->{LEVELS}[0], $ndr, $var_name, $env, $primitives, $deferred);
end_flags($e);
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
deindent;
pidl "}";
}
my ($e,$l,$var_name) = @_;
if ($l->{POINTER_TYPE} eq "ref") {
- check_null_pointer(get_value_of($var_name));
+ pidl "if ($var_name == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;";
if ($l->{LEVEL} eq "EMBEDDED") {
pidl "NDR_CHECK(ndr_push_ref_ptr(ndr));";
}
pidl "NDR_CHECK(ndr_push_relative_ptr1(ndr, $var_name));";
} elsif ($l->{POINTER_TYPE} eq "unique") {
pidl "NDR_CHECK(ndr_push_unique_ptr(ndr, $var_name));";
- } elsif ($l->{POINTER_TYPE} eq "sptr") {
- pidl "NDR_CHECK(ndr_push_sptr_ptr(ndr, $var_name));";
+ } elsif ($l->{POINTER_TYPE} eq "full") {
+ pidl "NDR_CHECK(ndr_push_full_ptr(ndr, $var_name));";
} else {
die("Unhandled pointer type $l->{POINTER_TYPE}");
}
}
+sub ParseDataPrint($$$)
+{
+ my ($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)) {
+ $var_name = get_pointer_to($var_name);
+ }
+ pidl "ndr_print_$t(ndr, \"$e->{NAME}\", $var_name);";
+ } else {
+ ParseTypePrint($l->{DATA_TYPE}, $var_name);
+ }
+}
+
#####################################################################
# print scalars in a structure element
sub ParseElementPrint($$$)
{
- my($e,$var_name,$env) = @_;
+ my($e, $var_name, $env) = @_;
return if (has_property($e, "noprint"));
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
pidl "ndr_print_$e->{REPRESENTATION_TYPE}(ndr, \"$e->{NAME}\", $var_name);";
return;
}
$var_name = append_prefix($e, $var_name);
- if (my $value = has_property($e, "value")) {
- $var_name = "(ndr->flags & LIBNDR_PRINT_SET_VALUES)?" . ParseExpr($value,$env) . ":$var_name";
+ if (defined(my $value = has_property($e, "value"))) {
+ $var_name = "(ndr->flags & LIBNDR_PRINT_SET_VALUES)?" . ParseExpr($value,$env, $e->{ORIGINAL}) . ":$var_name";
}
foreach my $l (@{$e->{LEVELS}}) {
if ($l->{IS_ZERO_TERMINATED}) {
$length = "ndr_string_length($var_name, sizeof(*$var_name))";
} else {
- $length = ParseExpr($l->{LENGTH_IS}, $env);
+ $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return;"), check_fully_dereferenced($e, $env));
}
if (is_charset_array($e,$l)) {
$var_name = $var_name . "[$counter]";
}
} elsif ($l->{TYPE} eq "DATA") {
- if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
- $var_name = get_pointer_to($var_name);
- }
- pidl "ndr_print_$l->{DATA_TYPE}(ndr, \"$e->{NAME}\", $var_name);";
+ ParseDataPrint($e, $l, $var_name);
} elsif ($l->{TYPE} eq "SWITCH") {
- my $switch_var = ParseExpr($l->{SWITCH_IS}, $env);
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return;"), check_fully_dereferenced($e, $env));
pidl "ndr_print_set_switch_value(ndr, " . get_pointer_to($var_name) . ", $switch_var);";
}
}
#####################################################################
# parse scalars in a structure element - pull size
-sub ParseSwitchPull($$$$$$)
+sub ParseSwitchPull($$$$$)
{
- my($e,$l,$ndr,$var_name,$ndr_flags,$env) = @_;
- my $switch_var = ParseExpr($l->{SWITCH_IS}, $env);
-
- check_null_pointer($switch_var);
+ my($e,$l,$ndr,$var_name,$env) = @_;
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
$var_name = get_pointer_to($var_name);
pidl "NDR_CHECK(ndr_pull_set_switch_value($ndr, $var_name, $switch_var));";
#####################################################################
# push switch element
-sub ParseSwitchPush($$$$$$)
+sub ParseSwitchPush($$$$$)
{
- my($e,$l,$ndr,$var_name,$ndr_flags,$env) = @_;
- my $switch_var = ParseExpr($l->{SWITCH_IS}, $env);
+ my($e,$l,$ndr,$var_name,$env) = @_;
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
- check_null_pointer($switch_var);
$var_name = get_pointer_to($var_name);
pidl "NDR_CHECK(ndr_push_set_switch_value($ndr, $var_name, $switch_var));";
}
-sub ParseDataPull($$$$$)
+sub ParseDataPull($$$$$$)
{
- my ($e,$l,$ndr,$var_name,$ndr_flags) = @_;
+ my ($e,$l,$ndr,$var_name,$primitives,$deferred) = @_;
- if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
- $var_name = get_pointer_to($var_name);
- }
+ if (not ref($l->{DATA_TYPE}) or
+ defined($l->{DATA_TYPE}->{NAME})) {
- $var_name = get_pointer_to($var_name);
+ my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
+ my $t;
+ if (ref($l->{DATA_TYPE}) eq "HASH") {
+ $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";
+ } else {
+ $t = $l->{DATA_TYPE};
+ }
- pidl "NDR_CHECK(ndr_pull_$l->{DATA_TYPE}($ndr, $ndr_flags, $var_name));";
+ if (Parse::Pidl::Typelist::scalar_is_reference($t)) {
+ $var_name = get_pointer_to($var_name);
+ }
- if (my $range = has_property($e, "range")) {
- $var_name = get_value_of($var_name);
- my ($low, $high) = split(/ /, $range, 2);
- pidl "if ($var_name < $low || $var_name > $high) {";
- pidl "\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");";
- pidl "}";
+ $var_name = get_pointer_to($var_name);
+
+ pidl "NDR_CHECK(ndr_pull_$t($ndr, $ndr_flags, $var_name));";
+
+ if (my $range = has_property($e, "range")) {
+ $var_name = get_value_of($var_name);
+ my ($low, $high) = split(/ /, $range, 2);
+ pidl "if ($var_name < $low || $var_name > $high) {";
+ pidl "\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");";
+ pidl "}";
+ }
+ } else {
+ ParseTypePull($l->{DATA_TYPE}, $var_name, $primitives, $deferred);
}
}
-sub ParseDataPush($$$$$)
+sub ParseDataPush($$$$$$)
{
- my ($e,$l,$ndr,$var_name,$ndr_flags) = @_;
+ my ($e,$l,$ndr,$var_name,$primitives,$deferred) = @_;
- # strings are passed by value rather than reference
- if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) {
- $var_name = get_pointer_to($var_name);
- }
+ 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};
+ }
+
+ # strings are passed by value rather than reference
+ if (not Parse::Pidl::Typelist::is_scalar($t) or
+ Parse::Pidl::Typelist::scalar_is_reference($t)) {
+ $var_name = get_pointer_to($var_name);
+ }
- pidl "NDR_CHECK(ndr_push_$l->{DATA_TYPE}($ndr, $ndr_flags, $var_name));";
+ my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);
+ pidl "NDR_CHECK(ndr_push_$t($ndr, $ndr_flags, $var_name));";
+ } else {
+ ParseTypePush($l->{DATA_TYPE}, $var_name, $primitives, $deferred);
+ }
}
sub CalcNdrFlags($$$)
sub ParseMemCtxPullStart($$$)
{
- my $e = shift;
- my $l = shift;
- my $ptr_name = shift;
+ my ($e, $l, $ptr_name) = @_;
my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
my $mem_c_ctx = $ptr_name;
if ($l->{IS_ZERO_TERMINATED}) {
CheckStringTerminator($ndr, $e, $l, $length);
}
- pidl "NDR_CHECK(ndr_pull_charset($ndr, $ndr_flags, ".get_pointer_to($var_name).", $length, sizeof(" . mapType($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));";
+ pidl "NDR_CHECK(ndr_pull_charset($ndr, $ndr_flags, ".get_pointer_to($var_name).", $length, sizeof(" . mapTypeName($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));";
return;
} elsif (has_fast_array($e, $l)) {
if ($l->{IS_ZERO_TERMINATED}) {
} elsif ($l->{TYPE} eq "POINTER") {
ParsePtrPull($e, $l, $ndr, $var_name);
} elsif ($l->{TYPE} eq "SWITCH") {
- ParseSwitchPull($e, $l, $ndr, $var_name, $ndr_flags, $env);
+ ParseSwitchPull($e, $l, $ndr, $var_name, $env);
} elsif ($l->{TYPE} eq "DATA") {
- ParseDataPull($e, $l, $ndr, $var_name, $ndr_flags);
+ ParseDataPull($e, $l, $ndr, $var_name, $primitives, $deferred);
}
}
}
}
- ParseMemCtxPullStart($e,$l, $var_name);
+ ParseMemCtxPullStart($e, $l, $var_name);
$var_name = get_value_of($var_name);
- ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 1, 1);
+ ParseElementPullLevel($e, GetNextLevel($e,$l), $ndr, $var_name, $env, 1, 1);
ParseMemCtxPullEnd($e,$l);
}
} elsif ($l->{TYPE} eq "ARRAY" and
not has_fast_array($e,$l) and not is_charset_array($e, $l)) {
- my $length = ParseExpr($l->{LENGTH_IS}, $env);
+ my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL});
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
my $array_name = $var_name;
$var_name = $var_name . "[$counter]";
- ParseMemCtxPullStart($e,$l, $array_name);
+ ParseMemCtxPullStart($e, $l, $array_name);
if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) {
my $nl = GetNextLevel($e,$l);
pidl "}";
}
- ParseMemCtxPullEnd($e,$l);
+ ParseMemCtxPullEnd($e, $l);
} elsif ($l->{TYPE} eq "SWITCH") {
- ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
+ ParseElementPullLevel($e, GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
}
}
#####################################################################
# parse scalars in a structure element - pull size
-sub ParseElementPull($$$$$$)
+sub ParseElementPull($$$$$)
{
- my($e,$ndr,$var_prefix,$env,$primitives,$deferred) = @_;
+ my($e,$ndr,$env,$primitives,$deferred) = @_;
- my $var_name = $var_prefix.$e->{NAME};
+ my $var_name = $env->{$e->{NAME}};
my $represent_name;
my $transmit_name;
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
pidl "{";
indent;
$represent_name = $var_name;
$transmit_name = "_transmit_$e->{NAME}";
$var_name = $transmit_name;
- pidl mapType($e->{TYPE})." $var_name;";
+ pidl mapTypeName($e->{TYPE})." $var_name;";
}
$var_name = append_prefix($e, $var_name);
end_flags($e);
# Representation type is different from transmit_as
- if ($e->{REPRESENTATION_TYPE}) {
+ if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
pidl "NDR_CHECK(ndr_$e->{TYPE}_to_$e->{REPRESENTATION_TYPE}($transmit_name, ".get_pointer_to($represent_name)."));";
deindent;
pidl "}";
return;
} elsif (($l->{POINTER_TYPE} eq "unique") or
($l->{POINTER_TYPE} eq "relative") or
- ($l->{POINTER_TYPE} eq "sptr")) {
+ ($l->{POINTER_TYPE} eq "full")) {
pidl "NDR_CHECK(ndr_pull_generic_ptr($ndr, &_ptr_$e->{NAME}));";
pidl "if (_ptr_$e->{NAME}) {";
indent;
pidl "}";
}
-#####################################################################
-# parse a struct
-sub ParseStructPush($$)
+sub ParseStructPushPrimitives($$$)
{
- my($struct,$name) = @_;
-
- return unless defined($struct->{ELEMENTS});
-
- my $env = GenerateStructEnv($struct);
-
- EnvSubstituteValue($env, $struct);
-
- # save the old relative_base_offset
- pidl "uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);" if defined($struct->{PROPERTIES}{relative_base});
-
- foreach my $e (@{$struct->{ELEMENTS}}) {
- DeclareArrayVariables($e);
- }
-
- start_flags($struct);
+ my ($struct, $varname, $env) = @_;
# see if the structure contains a conformant array. If it
# does, then it must be the last element of the structure, and
if ($e->{LEVELS}[0]->{IS_ZERO_TERMINATED}) {
if (has_property($e, "charset")) {
- $size = "ndr_charset_length(r->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})";
+ $size = "ndr_charset_length($varname->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})";
} else {
- $size = "ndr_string_length(r->$e->{NAME}, sizeof(*r->$e->{NAME}))";
+ $size = "ndr_string_length($varname->$e->{NAME}, sizeof(*$varname->$e->{NAME}))";
}
} else {
- $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env);
+ $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL});
}
pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));";
} else {
- pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, r->$e->{NAME})));";
+ pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, $varname->$e->{NAME})));";
}
}
- pidl "if (ndr_flags & NDR_SCALARS) {";
- indent;
-
pidl "NDR_CHECK(ndr_push_align(ndr, $struct->{ALIGN}));";
if (defined($struct->{PROPERTIES}{relative_base})) {
# set the current offset as base for relative pointers
# and store it based on the toplevel struct/union
- pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));";
+ pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, $varname, ndr->offset));";
}
- foreach my $e (@{$struct->{ELEMENTS}}) {
- ParseElementPush($e, "ndr", "r->", $env, 1, 0);
- }
-
- deindent;
- pidl "}";
+ ParseElementPush($_, "ndr", $env, 1, 0) foreach (@{$struct->{ELEMENTS}});
+}
- pidl "if (ndr_flags & NDR_BUFFERS) {";
- indent;
+sub ParseStructPushDeferred($$$)
+{
+ my ($struct, $varname, $env) = @_;
if (defined($struct->{PROPERTIES}{relative_base})) {
# retrieve the current offset as base for relative pointers
# based on the toplevel struct/union
- pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));";
- }
- foreach my $e (@{$struct->{ELEMENTS}}) {
- ParseElementPush($e, "ndr", "r->", $env, 0, 1);
+ pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, $varname));";
}
+ ParseElementPush($_, "ndr", $env, 0, 1) foreach (@{$struct->{ELEMENTS}});
+}
+
+#####################################################################
+# parse a struct
+sub ParseStructPush($$)
+{
+ my ($struct, $varname) = @_;
+
+ return unless defined($struct->{ELEMENTS});
+
+ my $env = GenerateStructEnv($struct, $varname);
+
+ EnvSubstituteValue($env, $struct);
+
+ DeclareArrayVariables($_) foreach (@{$struct->{ELEMENTS}});
+ start_flags($struct);
+
+ pidl "if (ndr_flags & NDR_SCALARS) {";
+ indent;
+ ParseStructPushPrimitives($struct, $varname, $env);
+ deindent;
+ pidl "}";
+
+ pidl "if (ndr_flags & NDR_BUFFERS) {";
+ indent;
+ ParseStructPushDeferred($struct, $varname, $env);
deindent;
pidl "}";
end_flags($struct);
- # restore the old relative_base_offset
- pidl "ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($struct->{PROPERTIES}{relative_base});
}
#####################################################################
# generate a push function for an enum
sub ParseEnumPush($$)
{
- my($enum,$name) = @_;
+ my($enum,$varname) = @_;
my($type_fn) = $enum->{BASE_TYPE};
start_flags($enum);
- pidl "NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, r));";
+ pidl "NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, $varname));";
end_flags($enum);
}
# generate a pull function for an enum
sub ParseEnumPull($$)
{
- my($enum,$name) = @_;
+ my($enum,$varname) = @_;
my($type_fn) = $enum->{BASE_TYPE};
- my($type_v_decl) = mapType($type_fn);
+ my($type_v_decl) = mapTypeName($type_fn);
pidl "$type_v_decl v;";
start_flags($enum);
pidl "NDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));";
- pidl "*r = v;";
+ pidl "*$varname = v;";
end_flags($enum);
}
#####################################################################
# generate a print function for an enum
-sub ParseEnumPrint($$)
+sub ParseEnumPrint($$$)
{
- my($enum,$name) = @_;
+ my($enum,$name,$varname) = @_;
pidl "const char *val = NULL;";
pidl "";
start_flags($enum);
- pidl "switch (r) {";
+ pidl "switch ($varname) {";
indent;
my $els = \@{$enum->{ELEMENTS}};
foreach my $i (0 .. $#{$els}) {
deindent;
pidl "}";
- pidl "ndr_print_enum(ndr, name, \"$enum->{TYPE}\", val, r);";
+ pidl "ndr_print_enum(ndr, name, \"$enum->{TYPE}\", val, $varname);";
end_flags($enum);
}
-sub DeclEnum($)
+sub DeclEnum($$$$)
{
- my ($e,$t) = @_;
- return "enum $e->{NAME} " .
- ($t eq "pull"?"*":"") . "r";
+ my ($e,$t,$name,$varname) = @_;
+ return "enum $name " .
+ ($t eq "pull"?"*":"") . $varname;
}
$typefamily{ENUM} = {
# generate a push function for a bitmap
sub ParseBitmapPush($$)
{
- my($bitmap,$name) = @_;
+ my($bitmap,$varname) = @_;
my($type_fn) = $bitmap->{BASE_TYPE};
start_flags($bitmap);
- pidl "NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, r));";
+ pidl "NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, $varname));";
end_flags($bitmap);
}
# generate a pull function for an bitmap
sub ParseBitmapPull($$)
{
- my($bitmap,$name) = @_;
+ my($bitmap,$varname) = @_;
my $type_fn = $bitmap->{BASE_TYPE};
- my($type_decl) = mapType($bitmap->{BASE_TYPE});
+ my($type_decl) = mapTypeName($bitmap->{BASE_TYPE});
pidl "$type_decl v;";
start_flags($bitmap);
pidl "NDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));";
- pidl "*r = v;";
+ pidl "*$varname = v;";
end_flags($bitmap);
}
#####################################################################
# generate a print function for an bitmap
-sub ParseBitmapPrintElement($$$)
+sub ParseBitmapPrintElement($$$$)
{
- my($e,$bitmap,$name) = @_;
- my($type_decl) = mapType($bitmap->{BASE_TYPE});
+ my($e,$bitmap,$name,$varname) = @_;
+ my($type_decl) = mapTypeName($bitmap->{BASE_TYPE});
my($type_fn) = $bitmap->{BASE_TYPE};
my($flag);
die "Bitmap: \"$name\" invalid Flag: \"$e\"";
}
- pidl "ndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, r);";
+ pidl "ndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, $varname);";
}
#####################################################################
# generate a print function for an bitmap
-sub ParseBitmapPrint($$)
+sub ParseBitmapPrint($$$)
{
- my($bitmap,$name) = @_;
- my($type_decl) = mapType($bitmap->{TYPE});
+ my($bitmap,$name,$varname) = @_;
+ my($type_decl) = mapTypeName($bitmap->{TYPE});
my($type_fn) = $bitmap->{BASE_TYPE};
start_flags($bitmap);
- pidl "ndr_print_$type_fn(ndr, name, r);";
+ pidl "ndr_print_$type_fn(ndr, name, $varname);";
pidl "ndr->depth++;";
foreach my $e (@{$bitmap->{ELEMENTS}}) {
- ParseBitmapPrintElement($e, $bitmap, $name);
+ ParseBitmapPrintElement($e, $bitmap, $name, $varname);
}
pidl "ndr->depth--;";
end_flags($bitmap);
}
-sub DeclBitmap($$)
+sub DeclBitmap($$$$)
{
- my ($e,$t) = @_;
- return mapType(Parse::Pidl::Typelist::bitmap_type_fn($e->{DATA})) .
- ($t eq "pull"?" *":" ") . "r";
+ my ($e,$t,$name,$varname) = @_;
+ return mapTypeName(Parse::Pidl::Typelist::bitmap_type_fn($e)) .
+ ($t eq "pull"?" *":" ") . $varname;
}
$typefamily{BITMAP} = {
#####################################################################
# generate a struct print function
-sub ParseStructPrint($$)
+sub ParseStructPrint($$$)
{
- my($struct,$name) = @_;
+ my($struct,$name,$varname) = @_;
return unless defined $struct->{ELEMENTS};
- my $env = GenerateStructEnv($struct);
+ my $env = GenerateStructEnv($struct, $varname);
EnvSubstituteValue($env, $struct);
pidl "ndr->depth++;";
- ParseElementPrint($_, "r->$_->{NAME}", $env) foreach (@{$struct->{ELEMENTS}});
+ ParseElementPrint($_, $env->{$_->{NAME}}, $env)
+ foreach (@{$struct->{ELEMENTS}});
pidl "ndr->depth--;";
end_flags($struct);
}
}
-#####################################################################
-# parse a struct - pull side
-sub ParseStructPull($$)
+sub ParseStructPullPrimitives($$$)
{
- my($struct,$name) = @_;
-
- return unless defined $struct->{ELEMENTS};
-
- my $env = GenerateStructEnv($struct);
-
- # declare any internal pointers we need
- foreach my $e (@{$struct->{ELEMENTS}}) {
- DeclarePtrVariables($e);
- DeclareArrayVariables($e);
- DeclareMemCtxVariables($e);
- }
-
- # save the old relative_base_offset
- pidl "uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);" if defined($struct->{PROPERTIES}{relative_base});
-
- start_flags($struct);
-
- pidl "if (ndr_flags & NDR_SCALARS) {";
- indent;
+ my($struct,$varname,$env) = @_;
if (defined $struct->{SURROUNDING_ELEMENT}) {
- pidl "NDR_CHECK(ndr_pull_array_size(ndr, &r->$struct->{SURROUNDING_ELEMENT}->{NAME}));";
+ pidl "NDR_CHECK(ndr_pull_array_size(ndr, &$varname->$struct->{SURROUNDING_ELEMENT}->{NAME}));";
}
pidl "NDR_CHECK(ndr_pull_align(ndr, $struct->{ALIGN}));";
if (defined($struct->{PROPERTIES}{relative_base})) {
# set the current offset as base for relative pointers
# and store it based on the toplevel struct/union
- pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));";
+ pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, $varname, ndr->offset));";
}
- foreach my $e (@{$struct->{ELEMENTS}}) {
- ParseElementPull($e, "ndr", "r->", $env, 1, 0);
- }
+ ParseElementPull($_, "ndr", $env, 1, 0) foreach (@{$struct->{ELEMENTS}});
add_deferred();
+}
+
+sub ParseStructPullDeferred($$$)
+{
+ my ($struct,$varname,$env) = @_;
- deindent;
- pidl "}";
- pidl "if (ndr_flags & NDR_BUFFERS) {";
- indent;
if (defined($struct->{PROPERTIES}{relative_base})) {
# retrieve the current offset as base for relative pointers
# based on the toplevel struct/union
- pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));";
+ pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, $varname));";
}
foreach my $e (@{$struct->{ELEMENTS}}) {
- ParseElementPull($e, "ndr", "r->", $env, 0, 1);
+ ParseElementPull($e, "ndr", $env, 0, 1);
}
add_deferred();
+}
+
+#####################################################################
+# parse a struct - pull side
+sub ParseStructPull($$)
+{
+ my($struct,$varname) = @_;
+
+ return unless defined $struct->{ELEMENTS};
+ # declare any internal pointers we need
+ foreach my $e (@{$struct->{ELEMENTS}}) {
+ DeclarePtrVariables($e);
+ DeclareArrayVariables($e);
+ DeclareMemCtxVariables($e);
+ }
+
+ start_flags($struct);
+
+ my $env = GenerateStructEnv($struct, $varname);
+
+ pidl "if (ndr_flags & NDR_SCALARS) {";
+ indent;
+ ParseStructPullPrimitives($struct,$varname,$env);
+ deindent;
+ pidl "}";
+ pidl "if (ndr_flags & NDR_BUFFERS) {";
+ indent;
+ ParseStructPullDeferred($struct,$varname,$env);
deindent;
pidl "}";
end_flags($struct);
- # restore the old relative_base_offset
- pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($struct->{PROPERTIES}{relative_base});
}
#####################################################################
# calculate size of ndr struct
-sub ParseStructNdrSize($)
+sub ParseStructNdrSize($$$)
{
- my $t = shift;
+ my ($t, $name, $varname) = @_;
my $sizevar;
if (my $flags = has_property($t, "flag")) {
pidl "flags |= $flags;";
}
- pidl "return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_$t->{NAME});";
+ pidl "return ndr_size_struct($varname, flags, (ndr_push_flags_fn_t)ndr_push_$name);";
}
-sub DeclStruct($)
+sub DeclStruct($$$$)
{
- my ($e,$t) = @_;
- return ($t ne "pull"?"const ":"") . "struct $e->{NAME} *r";
+ my ($e,$t,$name,$varname) = @_;
+ return ($t ne "pull"?"const ":"") . "struct $name *$varname";
}
-sub ArgsStructNdrSize($)
+sub ArgsStructNdrSize($$$)
{
- my $d = shift;
- return "const struct $d->{NAME} *r, int flags";
+ my ($d, $name, $varname) = @_;
+ return "const struct $name *$varname, int flags";
}
$typefamily{STRUCT} = {
#####################################################################
# calculate size of ndr struct
-sub ParseUnionNdrSize($)
+sub ParseUnionNdrSize($$$)
{
- my $t = shift;
+ my ($t, $name, $varname) = @_;
my $sizevar;
if (my $flags = has_property($t, "flag")) {
pidl "flags |= $flags;";
}
- pidl "return ndr_size_union(r, flags, level, (ndr_push_flags_fn_t)ndr_push_$t->{NAME});";
+ pidl "return ndr_size_union($varname, flags, level, (ndr_push_flags_fn_t)ndr_push_$name);";
}
-#####################################################################
-# parse a union - push side
-sub ParseUnionPush($$)
+sub ParseUnionPushPrimitives($$)
{
- my ($e,$name) = @_;
- my $have_default = 0;
-
- # save the old relative_base_offset
- pidl "uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);" if defined($e->{PROPERTIES}{relative_base});
- pidl "int level;";
+ my ($e, $varname) = @_;
- start_flags($e);
+ my $have_default = 0;
- pidl "level = ndr_push_get_switch_value(ndr, r);";
-
- pidl "if (ndr_flags & NDR_SCALARS) {";
- indent;
+ pidl "int level = ndr_push_get_switch_value(ndr, $varname);";
if (defined($e->{SWITCH_TYPE})) {
pidl "NDR_CHECK(ndr_push_$e->{SWITCH_TYPE}(ndr, NDR_SCALARS, level));";
pidl "NDR_CHECK(ndr_push_align(ndr, $el->{ALIGN}));";
# set the current offset as base for relative pointers
# and store it based on the toplevel struct/union
- pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));";
+ pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, $varname, ndr->offset));";
}
DeclareArrayVariables($el);
- ParseElementPush($el, "ndr", "r->", {}, 1, 0);
+ ParseElementPush($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0);
deindent;
}
pidl "break;";
}
deindent;
pidl "}";
- deindent;
- pidl "}";
- pidl "if (ndr_flags & NDR_BUFFERS) {";
- indent;
+}
+
+sub ParseUnionPushDeferred($$)
+{
+ my ($e, $varname) = @_;
+
+ my $have_default = 0;
+
+ pidl "int level = ndr_push_get_switch_value(ndr, $varname);";
if (defined($e->{PROPERTIES}{relative_base})) {
# retrieve the current offset as base for relative pointers
# based on the toplevel struct/union
- pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));";
+ pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, $varname));";
}
pidl "switch (level) {";
indent;
foreach my $el (@{$e->{ELEMENTS}}) {
+ if ($el->{CASE} eq "default") {
+ $have_default = 1;
+ }
+
pidl "$el->{CASE}:";
if ($el->{TYPE} ne "EMPTY") {
indent;
- ParseElementPush($el, "ndr", "r->", {}, 0, 1);
+ ParseElementPush($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1);
deindent;
}
pidl "break;";
}
deindent;
pidl "}";
+}
+
+#####################################################################
+# parse a union - push side
+sub ParseUnionPush($$)
+{
+ my ($e,$varname) = @_;
+ my $have_default = 0;
+
+ start_flags($e);
+ pidl "if (ndr_flags & NDR_SCALARS) {";
+ indent;
+ ParseUnionPushPrimitives($e, $varname);
+ deindent;
+ pidl "}";
+ pidl "if (ndr_flags & NDR_BUFFERS) {";
+ indent;
+ ParseUnionPushDeferred($e, $varname);
deindent;
pidl "}";
end_flags($e);
- # restore the old relative_base_offset
- pidl "ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($e->{PROPERTIES}{relative_base});
}
#####################################################################
# print a union
-sub ParseUnionPrint($$)
+sub ParseUnionPrint($$$)
{
- my ($e,$name) = @_;
+ my ($e,$name,$varname) = @_;
my $have_default = 0;
pidl "int level;";
start_flags($e);
- pidl "level = ndr_print_get_switch_value(ndr, r);";
+ pidl "level = ndr_print_get_switch_value(ndr, $varname);";
pidl "ndr_print_union(ndr, name, level, \"$name\");";
pidl "$el->{CASE}:";
if ($el->{TYPE} ne "EMPTY") {
indent;
- ParseElementPrint($el, "r->$el->{NAME}", {});
+ ParseElementPrint($el, "$varname->$el->{NAME}", {});
deindent;
}
pidl "break;";
end_flags($e);
}
-#####################################################################
-# parse a union - pull side
-sub ParseUnionPull($$)
+sub ParseUnionPullPrimitives($$$)
{
- my ($e,$name) = @_;
+ my ($e,$varname,$switch_type) = @_;
my $have_default = 0;
- my $switch_type = $e->{SWITCH_TYPE};
-
- # save the old relative_base_offset
- pidl "uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);" if defined($e->{PROPERTIES}{relative_base});
- pidl "int level;";
- if (defined($switch_type)) {
- if (Parse::Pidl::Typelist::typeIs($switch_type, "ENUM")) {
- $switch_type = Parse::Pidl::Typelist::enum_type_fn(getType($switch_type));
- }
- pidl mapType($switch_type) . " _level;";
- }
-
- my %double_cases = ();
- foreach my $el (@{$e->{ELEMENTS}}) {
- next if ($el->{TYPE} eq "EMPTY");
- next if ($double_cases{"$el->{NAME}"});
- DeclareMemCtxVariables($el);
- $double_cases{"$el->{NAME}"} = 1;
- }
-
- start_flags($e);
-
- pidl "level = ndr_pull_get_switch_value(ndr, r);";
-
- pidl "if (ndr_flags & NDR_SCALARS) {";
- indent;
if (defined($switch_type)) {
pidl "NDR_CHECK(ndr_pull_$switch_type(ndr, NDR_SCALARS, &_level));";
pidl "if (_level != level) {";
- pidl "\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $name\", _level);";
+ pidl "\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $varname\", _level);";
pidl "}";
}
pidl "NDR_CHECK(ndr_pull_align(ndr, $el->{ALIGN}));";
# set the current offset as base for relative pointers
# and store it based on the toplevel struct/union
- pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));";
+ pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, $varname, ndr->offset));";
}
- ParseElementPull($el, "ndr", "r->", {}, 1, 0);
+ ParseElementPull($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0);
deindent;
}
pidl "break; }";
}
deindent;
pidl "}";
- deindent;
- pidl "}";
- pidl "if (ndr_flags & NDR_BUFFERS) {";
- indent;
+}
+
+sub ParseUnionPullDeferred($$)
+{
+ my ($e,$varname) = @_;
+ my $have_default = 0;
+
if (defined($e->{PROPERTIES}{relative_base})) {
# retrieve the current offset as base for relative pointers
# based on the toplevel struct/union
- pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));";
+ pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, $varname));";
}
pidl "switch (level) {";
indent;
foreach my $el (@{$e->{ELEMENTS}}) {
+ if ($el->{CASE} eq "default") {
+ $have_default = 1;
+ }
+
pidl "$el->{CASE}:";
if ($el->{TYPE} ne "EMPTY") {
indent;
- ParseElementPull($el, "ndr", "r->", {}, 0, 1);
+ ParseElementPull($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1);
deindent;
}
pidl "break;";
deindent;
pidl "}";
+
+}
+
+#####################################################################
+# parse a union - pull side
+sub ParseUnionPull($$)
+{
+ my ($e,$varname) = @_;
+ my $switch_type = $e->{SWITCH_TYPE};
+
+ pidl "int level;";
+ if (defined($switch_type)) {
+ if (Parse::Pidl::Typelist::typeIs($switch_type, "ENUM")) {
+ $switch_type = Parse::Pidl::Typelist::enum_type_fn(getType($switch_type)->{DATA});
+ }
+ pidl mapTypeName($switch_type) . " _level;";
+ }
+
+ my %double_cases = ();
+ foreach my $el (@{$e->{ELEMENTS}}) {
+ next if ($el->{TYPE} eq "EMPTY");
+ next if ($double_cases{"$el->{NAME}"});
+ DeclareMemCtxVariables($el);
+ $double_cases{"$el->{NAME}"} = 1;
+ }
+
+ start_flags($e);
+
+ pidl "level = ndr_pull_get_switch_value(ndr, $varname);";
+
+ pidl "if (ndr_flags & NDR_SCALARS) {";
+ indent;
+ ParseUnionPullPrimitives($e,$varname,$switch_type);
+ deindent;
+ pidl "}";
+
+ pidl "if (ndr_flags & NDR_BUFFERS) {";
+ indent;
+ ParseUnionPullDeferred($e,$varname);
deindent;
pidl "}";
add_deferred();
end_flags($e);
- # restore the old relative_base_offset
- pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($e->{PROPERTIES}{relative_base});
}
-sub DeclUnion($$)
+sub DeclUnion($$$$)
{
- my ($e,$t) = @_;
- return ($t ne "pull"?"const ":"") . "union $e->{NAME} *r";
+ my ($e,$t,$name,$varname) = @_;
+ return ($t ne "pull"?"const ":"") . "union $name *$varname";
}
-sub ArgsUnionNdrSize($)
+sub ArgsUnionNdrSize($$)
{
- my $d = shift;
- return "const union $d->{NAME} *r, uint32_t level, int flags";
+ my ($d,$name) = @_;
+ return "const union $name *r, uint32_t level, int flags";
}
$typefamily{UNION} = {
#####################################################################
# parse a typedef - push side
-sub ParseTypedefPush($)
+sub ParseTypedefPush($$)
{
- my($e) = shift;
+ my($e,$varname) = @_;
- my $args = $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e,"push");
- fn_declare("push", $e, "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, $args)") or return;
-
- pidl "{";
- indent;
- $typefamily{$e->{DATA}->{TYPE}}->{PUSH_FN_BODY}->($e->{DATA}, $e->{NAME});
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}";
- pidl "";;
+ $typefamily{$e->{DATA}->{TYPE}}->{PUSH_FN_BODY}->($e->{DATA}, $varname);
}
#####################################################################
# parse a typedef - pull side
-sub ParseTypedefPull($)
+sub ParseTypedefPull($$)
{
- my($e) = shift;
-
- my $args = $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e,"pull");
-
- fn_declare("pull", $e, "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, $args)") or return;
+ my($e,$varname) = @_;
- pidl "{";
- indent;
- $typefamily{$e->{DATA}->{TYPE}}->{PULL_FN_BODY}->($e->{DATA}, $e->{NAME});
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}";
- pidl "";
+ $typefamily{$e->{DATA}->{TYPE}}->{PULL_FN_BODY}->($e->{DATA}, $varname);
}
#####################################################################
# parse a typedef - print side
-sub ParseTypedefPrint($)
+sub ParseTypedefPrint($$$)
{
- my($e) = shift;
-
- my $args = $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e,"print");
-
- pidl_hdr "void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args);";
-
- return if (has_property($e, "noprint"));
+ my($e,$name,$varname) = @_;
- pidl "_PUBLIC_ void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args)";
- pidl "{";
- indent;
- $typefamily{$e->{DATA}->{TYPE}}->{PRINT_FN_BODY}->($e->{DATA}, $e->{NAME});
- deindent;
- pidl "}";
- pidl "";
+ $typefamily{$e->{DATA}->{TYPE}}->{PRINT_FN_BODY}->($e->{DATA}, $name, $varname);
}
#####################################################################
## calculate the size of a structure
-sub ParseTypedefNdrSize($)
+sub ParseTypedefNdrSize($$$)
{
- my($t) = shift;
+ my($t,$name,$varname) = @_;
- my $tf = $typefamily{$t->{DATA}->{TYPE}};
- my $args = $tf->{SIZE_FN_ARGS}->($t);
+ $typefamily{$t->{DATA}->{TYPE}}->{SIZE_FN_BODY}->($t->{DATA}, $name, $varname);
+}
- fn_declare("size", $t, "size_t ndr_size_$t->{NAME}($args)") or return;
+sub DeclTypedef($$$$)
+{
+ my ($e, $t, $name, $varname) = @_;
+
+ return $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e->{DATA}, $t, $name, $varname);
+}
- pidl "{";
- indent;
- $typefamily{$t->{DATA}->{TYPE}}->{SIZE_FN_BODY}->($t);
- deindent;
- pidl "}";
- pidl "";
+sub ArgsTypedefNdrSize($$$)
+{
+ my ($d, $name, $varname) = @_;
+ return $typefamily{$d->{DATA}->{TYPE}}->{SIZE_FN_ARGS}->($d->{DATA}, $name, $varname);
}
+$typefamily{TYPEDEF} = {
+ PUSH_FN_BODY => \&ParseTypedefPush,
+ DECL => \&DeclTypedef,
+ PULL_FN_BODY => \&ParseTypedefPull,
+ PRINT_FN_BODY => \&ParseTypedefPrint,
+ SIZE_FN_ARGS => \&ArgsTypedefNdrSize,
+ SIZE_FN_BODY => \&ParseTypedefNdrSize,
+};
+
#####################################################################
# parse a function - print side
sub ParseFunctionPrint($)
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/in/,@{$e->{DIRECTION}})) {
- ParseElementPrint($e, "r->in.$e->{NAME}", $env);
+ ParseElementPrint($e, $env->{$e->{NAME}}, $env);
}
}
pidl "ndr->depth--;";
$env = GenerateFunctionOutEnv($fn);
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/out/,@{$e->{DIRECTION}})) {
- ParseElementPrint($e, "r->out.$e->{NAME}", $env);
+ ParseElementPrint($e, $env->{$e->{NAME}}, $env);
}
}
if ($fn->{RETURN_TYPE}) {
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/in/,@{$e->{DIRECTION}})) {
- ParseElementPush($e, "ndr", "r->in.", $env, 1, 1);
+ ParseElementPush($e, "ndr", $env, 1, 1);
}
}
$env = GenerateFunctionOutEnv($fn);
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/out/,@{$e->{DIRECTION}})) {
- ParseElementPush($e, "ndr", "r->out.", $env, 1, 1);
+ ParseElementPush($e, "ndr", $env, 1, 1);
}
}
{
my ($e,$l,$ndr,$env,$size) = @_;
- my $var = ParseExpr($e->{NAME}, $env);
+ my $var = ParseExpr($e->{NAME}, $env, $e->{ORIGINAL});
- check_null_pointer($size);
my $pl = GetPrevLevel($e, $l);
if (defined($pl) and
$pl->{TYPE} eq "POINTER" and
pidl "}";
if (grep(/in/,@{$e->{DIRECTION}}) and
grep(/out/,@{$e->{DIRECTION}})) {
- pidl "memcpy(r->out.$e->{NAME},r->in.$e->{NAME},$size * sizeof(*r->in.$e->{NAME}));";
+ pidl "memcpy(r->out.$e->{NAME}, r->in.$e->{NAME}, $size * sizeof(*r->in.$e->{NAME}));";
}
return;
}
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless (grep(/in/, @{$e->{DIRECTION}}));
- ParseElementPull($e, "ndr", "r->in.", $env, 1, 1);
+ ParseElementPull($e, "ndr", $env, 1, 1);
}
# allocate the "simple" out ref variables. FIXME: Shouldn't this have it's
and $e->{LEVELS}[1]->{IS_ZERO_TERMINATED});
if ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") {
- my $size = ParseExpr($e->{LEVELS}[1]->{SIZE_IS}, $env);
- check_null_pointer($size);
+ my $size = ParseExprExt($e->{LEVELS}[1]->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"),
+ check_fully_dereferenced($e, $env));
pidl "NDR_PULL_ALLOC_N(ndr, r->out.$e->{NAME}, $size);";
$env = GenerateFunctionOutEnv($fn);
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless grep(/out/, @{$e->{DIRECTION}});
- ParseElementPull($e, "ndr", "r->out.", $env, 1, 1);
+ ParseElementPull($e, "ndr", $env, 1, 1);
}
if ($fn->{RETURN_TYPE}) {
}
+#####################################################################
+# generate include statements for imported idl files
+sub HeaderImport
+{
+ my @imports = @_;
+ foreach (@imports) {
+ s/\.idl\"$//;
+ s/^\"//;
+ pidl choose_header("librpc/gen_ndr/ndr_$_\.h", "gen_ndr/ndr_$_.h");
+ }
+}
+
+#####################################################################
+# generate include statements for included header files
+sub HeaderInclude
+{
+ my @includes = @_;
+ foreach (@includes) {
+ pidl_hdr "#include $_";
+ }
+}
+
#####################################################################
# generate prototypes and defines for the interface definitions
# FIXME: these prototypes are for the DCE/RPC client functions, not the
pidl choose_header("librpc/gen_ndr/ndr_orpc.h", "ndr/orpc.h");
}
- if (defined $interface->{PROPERTIES}->{depends}) {
- my @d = split / /, $interface->{PROPERTIES}->{depends};
- foreach my $i (@d) {
- pidl choose_header("librpc/gen_ndr/ndr_$i\.h", "gen_ndr/ndr_$i.h");
- }
- }
-
if (defined $interface->{PROPERTIES}->{helper}) {
- foreach (split / /, $interface->{PROPERTIES}->{helper}) {
- pidl_hdr "#include $_";
- }
+ HeaderInclude(split / /, $interface->{PROPERTIES}->{helper});
}
if (defined $interface->{PROPERTIES}->{uuid}) {
}
+sub ParseTypePush($$$$)
+{
+ my ($e, $varname, $primitives, $deferred) = @_;
+
+ # save the old relative_base_offset
+ pidl "uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);" if defined(has_property($e, "relative_base"));
+ $typefamily{$e->{TYPE}}->{PUSH_FN_BODY}->($e, $varname);
+ # restore the old relative_base_offset
+ pidl "ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined(has_property($e, "relative_base"));
+}
+
+sub ParseTypePushFunction($$)
+{
+ my ($e, $varname) = @_;
+
+ my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "push", $e->{NAME}, $varname);
+ fn_declare("push", $e, "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, $args)") or return;
+
+ pidl "{";
+ indent;
+ ParseTypePush($e, $varname, 1, 1);
+ pidl "return NT_STATUS_OK;";
+ deindent;
+ pidl "}";
+ pidl "";;
+}
+
+sub ParseTypePull($$$$)
+{
+ my ($e, $varname, $primitives, $deferred) = @_;
+
+ # save the old relative_base_offset
+ pidl "uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);" if defined(has_property($e, "relative_base"));
+ $typefamily{$e->{TYPE}}->{PULL_FN_BODY}->($e, $varname);
+ # restore the old relative_base_offset
+ pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined(has_property($e, "relative_base"));
+}
+
+
+sub ParseTypePullFunction($$)
+{
+ my ($e, $varname) = @_;
+
+ my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "pull", $e->{NAME}, $varname);
+
+ fn_declare("pull", $e, "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, $args)") or return;
+
+ pidl "{";
+ indent;
+ ParseTypePull($e, $varname, 1, 1);
+ pidl "return NT_STATUS_OK;";
+ deindent;
+ pidl "}";
+ pidl "";
+}
+
+sub ParseTypePrint($$)
+{
+ my ($e, $varname) = @_;
+
+ $typefamily{$e->{TYPE}}->{PRINT_FN_BODY}->($e, $e->{NAME}, $varname);
+}
+
+sub ParseTypePrintFunction($$)
+{
+ my ($e, $varname) = @_;
+ my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "print", $e->{NAME}, $varname);
+
+ pidl_hdr "void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args);";
+
+ return if (has_property($e, "noprint"));
+
+ pidl "_PUBLIC_ void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args)";
+ pidl "{";
+ indent;
+ ParseTypePrint($e, $varname);
+ deindent;
+ pidl "}";
+ pidl "";
+}
+
+sub ParseTypeNdrSize($)
+{
+ my ($t) = @_;
+
+ my $varname = "r";
+ my $tf = $typefamily{$t->{TYPE}};
+ my $args = $tf->{SIZE_FN_ARGS}->($t, $t->{NAME}, $varname);
+
+ fn_declare("size", $t, "size_t ndr_size_$t->{NAME}($args)") or return;
+
+ pidl "{";
+ indent;
+ $typefamily{$t->{TYPE}}->{SIZE_FN_BODY}->($t, $t->{NAME}, $varname);
+ deindent;
+ pidl "}";
+ pidl "";
+}
+
#####################################################################
# parse the interface definitions
sub ParseInterface($$)
# Typedefs
foreach my $d (@{$interface->{TYPES}}) {
- ($needed->{"push_$d->{NAME}"}) && ParseTypedefPush($d);
- ($needed->{"pull_$d->{NAME}"}) && ParseTypedefPull($d);
- ($needed->{"print_$d->{NAME}"}) && ParseTypedefPrint($d);
+ ($needed->{"push_$d->{NAME}"}) && ParseTypePushFunction($d, "r");
+ ($needed->{"pull_$d->{NAME}"}) && ParseTypePullFunction($d, "r");
+ ($needed->{"print_$d->{NAME}"}) && ParseTypePrintFunction($d, "r");
# Make sure we don't generate a function twice...
$needed->{"push_$d->{NAME}"} = $needed->{"pull_$d->{NAME}"} =
$needed->{"print_$d->{NAME}"} = 0;
- ($needed->{"ndr_size_$d->{NAME}"}) && ParseTypedefNdrSize($d);
+ ($needed->{"ndr_size_$d->{NAME}"}) && ParseTypeNdrSize($d);
}
# Functions
foreach (@{$ndr}) {
($_->{TYPE} eq "INTERFACE") && ParseInterface($_, \%needed);
+ ($_->{TYPE} eq "IMPORT") && HeaderImport(@{$_->{PATHS}});
+ ($_->{TYPE} eq "INCLUDE") && HeaderInclude(@{$_->{PATHS}});
}
return ($res_hdr, $res);
}
+sub NeededElement($$$)
+{
+ my ($e, $dir, $needed) = @_;
+
+ return if ($e->{TYPE} eq "EMPTY");
+
+ my ($t, $rt);
+ if (ref($e->{TYPE}) eq "HASH") {
+ $t = $e->{TYPE}->{TYPE}."_".$e->{TYPE}->{NAME};
+ } else {
+ $t = $e->{TYPE};
+ }
+
+ if (ref($e->{REPRESENTATION_TYPE}) eq "HASH") {
+ $rt = $e->{REPRESENTATION_TYPE}->{TYPE}."_".$e->{REPRESENTATION_TYPE}->{NAME};
+ } else {
+ $rt = $e->{REPRESENTATION_TYPE};
+ }
+
+ die ("$e->{NAME} $t, $rt FOO") unless ($rt ne "");
+
+ my @fn = ();
+ if ($dir eq "print") {
+ push(@fn, "print_$rt");
+ } elsif ($dir eq "pull") {
+ push (@fn, "pull_$t");
+ push (@fn, "ndr_$t\_to_$rt")
+ if ($rt ne $t);
+ } elsif ($dir eq "push") {
+ push (@fn, "push_$t");
+ push (@fn, "ndr_$rt\_to_$t")
+ if ($rt ne $t);
+ } else {
+ die("invalid direction `$dir'");
+ }
+
+ foreach (@fn) {
+ unless (defined($needed->{$_})) {
+ $needed->{$_} = 1;
+ }
+ }
+}
+
sub NeededFunction($$)
{
my ($fn,$needed) = @_;
$needed->{"print_$fn->{NAME}"} = 1;
foreach my $e (@{$fn->{ELEMENTS}}) {
$e->{PARENT} = $fn;
- unless(defined($needed->{"pull_$e->{TYPE}"})) {
- $needed->{"pull_$e->{TYPE}"} = 1;
- }
- unless(defined($needed->{"push_$e->{TYPE}"})) {
- $needed->{"push_$e->{TYPE}"} = 1;
- }
- unless(defined($needed->{"print_$e->{TYPE}"})) {
- $needed->{"print_$e->{TYPE}"} = 1;
- }
+ NeededElement($e, $_, $needed) foreach ("pull", "push", "print");
}
}
-sub NeededTypedef($$)
+sub NeededType($$$)
{
- my ($t,$needed) = @_;
- if (has_property($t, "public")) {
- $needed->{"pull_$t->{NAME}"} = 1;
- $needed->{"push_$t->{NAME}"} = 1;
- $needed->{"print_$t->{NAME}"} = 1;
- }
+ sub NeededType($$$);
+ my ($t,$needed,$req) = @_;
- if ($t->{DATA}->{TYPE} eq "STRUCT" or $t->{DATA}->{TYPE} eq "UNION") {
- if (has_property($t, "gensize")) {
- $needed->{"ndr_size_$t->{NAME}"} = 1;
- }
+ NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "TYPEDEF");
- for my $e (@{$t->{DATA}->{ELEMENTS}}) {
- $e->{PARENT} = $t->{DATA};
+ if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "UNION") {
+ for my $e (@{$t->{ELEMENTS}}) {
+ $e->{PARENT} = $t;
if (has_property($e, "compression")) {
$needed->{"compression"} = 1;
}
- if ($needed->{"pull_$t->{NAME}"} and
- not defined($needed->{"pull_$e->{TYPE}"})) {
- $needed->{"pull_$e->{TYPE}"} = 1;
- }
- if ($needed->{"push_$t->{NAME}"} and
- not defined($needed->{"push_$e->{TYPE}"})) {
- $needed->{"push_$e->{TYPE}"} = 1;
- }
- if ($needed->{"print_$t->{NAME}"} and
- not defined($needed->{"print_$e->{TYPE}"})) {
- $needed->{"print_$e->{TYPE}"} = 1;
- }
+ NeededElement($e, $req, $needed);
+ NeededType($e->{TYPE}, $needed, $req) if (ref($e->{TYPE}) eq "HASH");
}
}
}
{
my ($interface,$needed) = @_;
NeededFunction($_, $needed) foreach (@{$interface->{FUNCTIONS}});
- NeededTypedef($_, $needed) foreach (reverse @{$interface->{TYPES}});
+ foreach (reverse @{$interface->{TYPES}}) {
+ if (has_property($_, "public")) {
+ $needed->{"pull\_$_->{NAME}"} = $needed->{"push\_$_->{NAME}"} =
+ $needed->{"print\_$_->{NAME}"} = 1;
+ }
+
+ NeededType($_, $needed, "pull") if ($needed->{"pull_$_->{NAME}"});
+ NeededType($_, $needed, "push") if ($needed->{"push_$_->{NAME}"});
+ NeededType($_, $needed, "print") if ($needed->{"print_$_->{NAME}"});
+ if (has_property($_, "gensize")) {
+ $needed->{"ndr_size_$_->{NAME}"} = 1;
+ }
+ }
}
1;