summaryrefslogtreecommitdiff
path: root/source4/pidl
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2007-02-21 14:35:25 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:48:43 -0500
commit79a1b1a928f0f8cdd6c60d74291bf048c8484f0b (patch)
treee58279ecfbd1d7b14960cb00fc5f08262125259c /source4/pidl
parentbf5cfb5f3d7bf315d6869d16fcb061234fef1f92 (diff)
downloadsamba-79a1b1a928f0f8cdd6c60d74291bf048c8484f0b.tar.gz
samba-79a1b1a928f0f8cdd6c60d74291bf048c8484f0b.tar.bz2
samba-79a1b1a928f0f8cdd6c60d74291bf048c8484f0b.zip
r21492: Finish work on nested type support in EJS.
(This used to be commit e88055b76a3d81fcc40773d880f76a1c3f53fbf0)
Diffstat (limited to 'source4/pidl')
-rw-r--r--source4/pidl/TODO2
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm243
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba4/Header.pm4
3 files changed, 127 insertions, 122 deletions
diff --git a/source4/pidl/TODO b/source4/pidl/TODO
index 2d4ca8a265..47cd956c4f 100644
--- a/source4/pidl/TODO
+++ b/source4/pidl/TODO
@@ -7,8 +7,6 @@
- strip out pidl-specific properties
- support nested elements
- - allow non-typedef structs
- - generate names for anonymous tagged types. Simple MD5Sum of contents?
- support typedefs properly
- improve represent_as(): allow it to be used for arrays and other complex
types
diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm b/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm
index 910b47a4a1..9edd2a4a33 100644
--- a/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm
+++ b/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm
@@ -110,22 +110,25 @@ sub EjsPullScalar($$$$$)
return if (has_property($e, "value"));
- my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);
+ if (ref($e->{TYPE}) eq "HASH" and not defined($e->{TYPE}->{NAME})) {
+ EjsTypePull($e->{TYPE}, $var);
+ } else {
+ my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);
$var = get_pointer_to($var);
# have to handle strings specially :(
- if (Parse::Pidl::Typelist::scalar_is_reference($e->{TYPE})
- and (defined($pl) and $pl->{TYPE} eq "POINTER")) {
+ if (Parse::Pidl::Typelist::scalar_is_reference($e->{TYPE})
+ and (defined($pl) and $pl->{TYPE} eq "POINTER")) {
$var = get_pointer_to($var);
}
- my $t;
- if (ref($e->{TYPE}) eq "HASH") {
- $t = "$e->{TYPE}->{TYPE}_$e->{TYPE}->{NAME}";
- } else {
- $t = $e->{TYPE};
+ my $t;
+ if (ref($e->{TYPE}) eq "HASH") {
+ $t = "$e->{TYPE}->{TYPE}_$e->{TYPE}->{NAME}";
+ } else {
+ $t = $e->{TYPE};
+ }
+ pidl "NDR_CHECK(ejs_pull_$t(ejs, v, $name, $var));";
}
-
- pidl "NDR_CHECK(ejs_pull_$t(ejs, v, $name, $var));";
}
###########################
@@ -163,7 +166,6 @@ sub EjsPullString($$$$$)
pidl "NDR_CHECK(ejs_pull_string(ejs, v, $name, $var));";
}
-
###########################
# pull an array element
sub EjsPullArray($$$$$)
@@ -250,29 +252,20 @@ sub EjsPullElementTop($$)
# pull a struct
sub EjsStructPull($$)
{
- my ($name, $d) = @_;
- my $env = GenerateStructEnv($d, "r");
- fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, struct $name *r)");
- pidl "{";
- indent;
+ my ($d, $varname) = @_;
+ my $env = GenerateStructEnv($d, $varname);
pidl "NDR_CHECK(ejs_pull_struct_start(ejs, &v, name));";
- foreach my $e (@{$d->{ELEMENTS}}) {
+ foreach my $e (@{$d->{ELEMENTS}}) {
EjsPullElementTop($e, $env);
}
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}\n";
}
###########################
# pull a union
sub EjsUnionPull($$)
{
- my ($name, $d) = @_;
+ my ($d, $varname) = @_;
my $have_default = 0;
- fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, union $name *r)");
- pidl "{";
- indent;
pidl "NDR_CHECK(ejs_pull_struct_start(ejs, &v, name));";
pidl "switch (ejs->switch_var) {";
indent;
@@ -283,7 +276,7 @@ sub EjsUnionPull($$)
pidl "$e->{CASE}:";
indent;
if ($e->{TYPE} ne "EMPTY") {
- EjsPullElementTop($e, { $e->{NAME} => "r->$e->{NAME}"});
+ EjsPullElementTop($e, { $e->{NAME} => "$varname->$e->{NAME}"});
}
pidl "break;";
deindent;
@@ -296,9 +289,6 @@ sub EjsUnionPull($$)
}
deindent;
pidl "}";
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}";
}
##############################################
@@ -323,50 +313,66 @@ sub EjsEnumConstant($)
# pull a enum
sub EjsEnumPull($$)
{
- my ($name, $d) = @_;
+ my ($d, $varname) = @_;
EjsEnumConstant($d);
- fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, enum $name *r)");
- pidl "{";
- indent;
pidl "unsigned e;";
pidl "NDR_CHECK(ejs_pull_enum(ejs, v, name, &e));";
- pidl "*r = e;";
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}\n";
+ pidl "*$varname = e;";
}
###########################
# pull a bitmap
sub EjsBitmapPull($$)
{
- my ($name, $d) = @_;
+ my ($d, $varname) = @_;
my $type_fn = $d->{BASE_TYPE};
- my($type_decl) = Parse::Pidl::Typelist::mapTypeName($d->{BASE_TYPE});
- fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, $type_decl *r)");
+ pidl "NDR_CHECK(ejs_pull_$type_fn(ejs, v, name, $varname));";
+}
+
+sub EjsTypePullFunction($$)
+{
+ sub EjsTypePullFunction($$);
+ my ($d, $name) = @_;
+ return if (has_property($d, "noejs"));
+
+ if ($d->{TYPE} eq "TYPEDEF") {
+ EjsTypePullFunction($d->{DATA}, $name);
+ return;
+ }
+
+ if ($d->{TYPE} eq "STRUCT") {
+ fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, struct $name *r)");
+ } elsif ($d->{TYPE} eq "UNION") {
+ fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, union $name *r)");
+ } elsif ($d->{TYPE} eq "ENUM") {
+ fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, enum $name *r)");
+ } elsif ($d->{TYPE} eq "BITMAP") {
+ my($type_decl) = Parse::Pidl::Typelist::mapTypeName($d->{BASE_TYPE});
+ fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, $type_decl *r)");
+ }
pidl "{";
indent;
- pidl "return ejs_pull_$type_fn(ejs, v, name, r);";
+
+ EjsTypePull($d, "r");
+
+ pidl "return NT_STATUS_OK;";
deindent;
- pidl "}";
+ pidl "}\n";
}
-###########################
-# generate a structure pull
-sub EjsTypedefPull($)
+sub EjsTypePull($$)
{
- my $d = shift;
- return if (has_property($d, "noejs"));
- if ($d->{DATA}->{TYPE} eq 'STRUCT') {
- EjsStructPull($d->{NAME}, $d->{DATA});
- } elsif ($d->{DATA}->{TYPE} eq 'UNION') {
- EjsUnionPull($d->{NAME}, $d->{DATA});
- } elsif ($d->{DATA}->{TYPE} eq 'ENUM') {
- EjsEnumPull($d->{NAME}, $d->{DATA});
- } elsif ($d->{DATA}->{TYPE} eq 'BITMAP') {
- EjsBitmapPull($d->{NAME}, $d->{DATA});
+ my ($d, $varname) = @_;
+ if ($d->{TYPE} eq 'STRUCT') {
+ EjsStructPull($d, $varname);
+ } elsif ($d->{TYPE} eq 'UNION') {
+ EjsUnionPull($d, $varname);
+ } elsif ($d->{TYPE} eq 'ENUM') {
+ EjsEnumPull($d, $varname);
+ } elsif ($d->{TYPE} eq 'BITMAP') {
+ EjsBitmapPull($d, $varname);
} else {
- warn "Unhandled pull typedef $d->{NAME} of type $d->{DATA}->{TYPE}";
+ warn "Unhandled pull $varname of type $d->{TYPE}";
}
}
@@ -403,28 +409,32 @@ sub EjsPullFunction($)
pidl "}\n";
}
-
###########################
# push a scalar element
sub EjsPushScalar($$$$$)
{
my ($e, $l, $var, $name, $env) = @_;
- # have to handle strings specially :(
+
+ if (ref($e->{TYPE}) eq "HASH" and not defined($e->{TYPE}->{NAME})) {
+ EjsTypePush($e->{TYPE}, get_pointer_to($var));
+ } else {
+ # have to handle strings specially :(
my $pl = GetPrevLevel($e, $l);
- if ((not Parse::Pidl::Typelist::scalar_is_reference($e->{TYPE}))
- or (defined($pl) and $pl->{TYPE} eq "POINTER")) {
- $var = get_pointer_to($var);
- }
+ if ((not Parse::Pidl::Typelist::scalar_is_reference($e->{TYPE}))
+ or (defined($pl) and $pl->{TYPE} eq "POINTER")) {
+ $var = get_pointer_to($var);
+ }
- my $t;
- if (ref($e->{TYPE}) eq "HASH") {
- $t = "$e->{TYPE}->{TYPE}_$e->{TYPE}->{NAME}";
- } else {
- $t = $e->{TYPE};
- }
+ my $t;
+ if (ref($e->{TYPE}) eq "HASH") {
+ $t = "$e->{TYPE}->{TYPE}_$e->{TYPE}->{NAME}";
+ } else {
+ $t = $e->{TYPE};
+ }
- pidl "NDR_CHECK(ejs_push_$t(ejs, v, $name, $var));";
+ pidl "NDR_CHECK(ejs_push_$t(ejs, v, $name, $var));";
+ }
}
###########################
@@ -470,7 +480,6 @@ sub EjsPushSwitch($$$$$)
EjsPushElement($e, GetNextLevel($e, $l), $var, $name, $env);
}
-
###########################
# push an array element
sub EjsPushArray($$$$$)
@@ -538,29 +547,20 @@ sub EjsPushElementTop($$)
# push a struct
sub EjsStructPush($$)
{
- my ($name, $d) = @_;
- my $env = GenerateStructEnv($d, "r");
- fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const struct $name *r)");
- pidl "{";
- indent;
+ my ($d, $varname) = @_;
+ my $env = GenerateStructEnv($d, $varname);
pidl "NDR_CHECK(ejs_push_struct_start(ejs, &v, name));";
foreach my $e (@{$d->{ELEMENTS}}) {
EjsPushElementTop($e, $env);
}
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}\n";
}
###########################
# push a union
sub EjsUnionPush($$)
{
- my ($name, $d) = @_;
+ my ($d, $varname) = @_;
my $have_default = 0;
- fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const union $name *r)");
- pidl "{";
- indent;
pidl "NDR_CHECK(ejs_push_struct_start(ejs, &v, name));";
pidl "switch (ejs->switch_var) {";
indent;
@@ -571,7 +571,7 @@ sub EjsUnionPush($$)
pidl "$e->{CASE}:";
indent;
if ($e->{TYPE} ne "EMPTY") {
- EjsPushElementTop($e, { $e->{NAME} => "r->$e->{NAME}"} );
+ EjsPushElementTop($e, { $e->{NAME} => "$varname->$e->{NAME}"} );
}
pidl "break;";
deindent;
@@ -584,35 +584,24 @@ sub EjsUnionPush($$)
}
deindent;
pidl "}";
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}";
}
###########################
# push a enum
sub EjsEnumPush($$)
{
- my $name = shift;
- my $d = shift;
+ my ($d, $varname) = @_;
EjsEnumConstant($d);
- fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const enum $name *r)");
- pidl "{";
- indent;
- pidl "unsigned e = *r;";
+ pidl "unsigned e = ".get_value_of($varname).";";
pidl "NDR_CHECK(ejs_push_enum(ejs, v, name, &e));";
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}\n";
}
###########################
# push a bitmap
sub EjsBitmapPush($$)
{
- my ($name, $d) = @_;
+ my ($d, $varname) = @_;
my $type_fn = $d->{BASE_TYPE};
- my($type_decl) = Parse::Pidl::Typelist::mapTypeName($d->{BASE_TYPE});
# put the bitmap elements in the constants array
foreach my $e (@{$d->{ELEMENTS}}) {
if ($e =~ /^(\w*)\s*(.*)\s*$/) {
@@ -621,36 +610,55 @@ sub EjsBitmapPush($$)
$constants{$bname} = $v;
}
}
- fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const $type_decl *r)");
+ pidl "NDR_CHECK(ejs_push_$type_fn(ejs, v, name, $varname));";
+}
+
+sub EjsTypePushFunction($$)
+{
+ sub EjsTypePushFunction($$);
+ my ($d, $name) = @_;
+ return if (has_property($d, "noejs"));
+
+ if ($d->{TYPE} eq "TYPEDEF") {
+ EjsTypePushFunction($d->{DATA}, $name);
+ return;
+ }
+
+ if ($d->{TYPE} eq "STRUCT") {
+ fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const struct $name *r)");
+ } elsif ($d->{TYPE} eq "UNION") {
+ fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const union $name *r)");
+ } elsif ($d->{TYPE} eq "ENUM") {
+ fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const enum $name *r)");
+ } elsif ($d->{TYPE} eq "BITMAP") {
+ my($type_decl) = Parse::Pidl::Typelist::mapTypeName($d->{BASE_TYPE});
+ fn_declare($d, "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const $type_decl *r)");
+ }
pidl "{";
indent;
- pidl "return ejs_push_$type_fn(ejs, v, name, r);";
+ EjsTypePush($d, "r");
+ pidl "return NT_STATUS_OK;";
deindent;
- pidl "}";
+ pidl "}\n";
}
-
-###########################
-# generate a structure push
-sub EjsTypedefPush($)
+sub EjsTypePush($$)
{
- my $d = shift;
- return if (has_property($d, "noejs"));
+ my ($d, $varname) = @_;
- if ($d->{DATA}->{TYPE} eq 'STRUCT') {
- EjsStructPush($d->{NAME}, $d->{DATA});
- } elsif ($d->{DATA}->{TYPE} eq 'UNION') {
- EjsUnionPush($d->{NAME}, $d->{DATA});
- } elsif ($d->{DATA}->{TYPE} eq 'ENUM') {
- EjsEnumPush($d->{NAME}, $d->{DATA});
- } elsif ($d->{DATA}->{TYPE} eq 'BITMAP') {
- EjsBitmapPush($d->{NAME}, $d->{DATA});
+ if ($d->{TYPE} eq 'STRUCT') {
+ EjsStructPush($d, $varname);
+ } elsif ($d->{TYPE} eq 'UNION') {
+ EjsUnionPush($d, $varname);
+ } elsif ($d->{TYPE} eq 'ENUM') {
+ EjsEnumPush($d, $varname);
+ } elsif ($d->{TYPE} eq 'BITMAP') {
+ EjsBitmapPush($d, $varname);
} else {
- warn "Unhandled push typedef $d->{NAME} of type $d->{DATA}->{TYPE}";
+ warn "Unhandled push $varname of type $d->{TYPE}";
}
}
-
#####################
# generate a function
sub EjsPushFunction($)
@@ -678,7 +686,6 @@ sub EjsPushFunction($)
pidl "}\n";
}
-
#################################
# generate a ejs mapping function
sub EjsFunction($$)
@@ -730,8 +737,8 @@ sub EjsInterface($$)
pidl_hdr "\n";
foreach my $d (@{$interface->{TYPES}}) {
- ($needed->{"push_$d->{NAME}"}) && EjsTypedefPush($d);
- ($needed->{"pull_$d->{NAME}"}) && EjsTypedefPull($d);
+ ($needed->{"push_$d->{NAME}"}) && EjsTypePushFunction($d, $d->{NAME});
+ ($needed->{"pull_$d->{NAME}"}) && EjsTypePullFunction($d, $d->{NAME});
}
foreach my $d (@{$interface->{FUNCTIONS}}) {
diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm
index 39e6c4233c..11ecc17001 100644
--- a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm
+++ b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm
@@ -7,7 +7,7 @@
package Parse::Pidl::Samba4::Header;
use strict;
-use Parse::Pidl::Typelist qw(mapTypeName);
+use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
use Parse::Pidl::Util qw(has_property is_constant);
use Parse::Pidl::Samba4 qw(is_intree);
@@ -61,7 +61,7 @@ sub HeaderElement($)
pidl " ";
my $numstar = $element->{POINTERS};
if ($numstar >= 1) {
- $numstar-- if Parse::Pidl::Typelist::scalar_is_reference($element->{TYPE});
+ $numstar-- if (scalar_is_reference($element->{TYPE}));
}
foreach (@{$element->{ARRAY_LEN}})
{