From ac0433e3d3b5feb7629f67f35ea914c11686591c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 19 Feb 2007 21:37:54 +0000 Subject: r21456: Allow anonymous and non-anonymous nested structures/unions/enums/bitmaps to be used in the Samba 4 NDR parser. This doesn't actually work yet as Parse::Pidl::NDR doesn't handle nested data structures yet, but it's a first step. (This used to be commit 8aac1fc98b812a0668bc0d803d1e2831396b455e) --- source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 148 ++++++++++++++++------- 1 file changed, 105 insertions(+), 43 deletions(-) (limited to 'source4/pidl') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index 8393d6f3c0..8a72b1233e 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -752,6 +752,28 @@ sub ParsePtrPush($$$) } } +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($$$) @@ -816,10 +838,7 @@ sub ParseElementPrint($$$) $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 = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&pidl, "return;"), check_fully_dereferenced($e, $env)); @@ -875,20 +894,32 @@ sub ParseDataPull($$$$$) { my ($e,$l,$ndr,$var_name,$ndr_flags) = @_; - 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})) { + my $t; + if (ref($l->{DATA_TYPE}) eq "HASH") { + $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}"; + } else { + $t = $l->{DATA_TYPE}; + } - $var_name = get_pointer_to($var_name); + if (Parse::Pidl::Typelist::scalar_is_reference($t)) { + $var_name = get_pointer_to($var_name); + } - pidl "NDR_CHECK(ndr_pull_$l->{DATA_TYPE}($ndr, $ndr_flags, $var_name));"; + $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 "}"; + 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); } } @@ -896,12 +927,24 @@ sub ParseDataPush($$$$$) { my ($e,$l,$ndr,$var_name,$ndr_flags) = @_; - # 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));"; + pidl "NDR_CHECK(ndr_push_$t($ndr, $ndr_flags, $var_name));"; + } else { + ParseTypePush($l->{DATA_TYPE}, $var_name); + } } sub CalcNdrFlags($$$) @@ -2376,53 +2419,72 @@ sub HeaderInterface($) } -sub ParseTypePush($) +sub ParseTypePush($$) { - my ($e) = @_; - - my $varname = "r"; - 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; + my ($e, $varname) = @_; - pidl "{"; - indent; # 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, $e->{NAME}, $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); pidl "return NT_STATUS_OK;"; deindent; pidl "}"; pidl "";; } -sub ParseTypePull($) +sub ParseTypePull($$) { - my ($e) = @_; + my ($e, $varname) = @_; + + # 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, $e->{NAME}, $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 $varname = "r"; 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; - # 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, $e->{NAME}, $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")); + ParseTypePull($e, $varname); pidl "return NT_STATUS_OK;"; deindent; pidl "}"; pidl ""; } -sub ParseTypePrint($) +sub ParseTypePrint($$) { - my ($e) = @_; - my $varname = "r"; + 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);"; @@ -2432,7 +2494,7 @@ sub ParseTypePrint($) pidl "_PUBLIC_ void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $args)"; pidl "{"; indent; - $typefamily{$e->{TYPE}}->{PRINT_FN_BODY}->($e, $e->{NAME}, $varname); + ParseTypePrint($e, $varname); deindent; pidl "}"; pidl ""; @@ -2475,9 +2537,9 @@ sub ParseInterface($$) # Typedefs foreach my $d (@{$interface->{TYPES}}) { - ($needed->{"push_$d->{NAME}"}) && ParseTypePush($d); - ($needed->{"pull_$d->{NAME}"}) && ParseTypePull($d); - ($needed->{"print_$d->{NAME}"}) && ParseTypePrint($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}"} = -- cgit