Rev 11561: Finish work on nested type support in EJS. in file:///home/jelmer/bzr.samba/SAMBA_4_0/

Jelmer Vernooij jelmer at samba.org
Wed Feb 21 14:32:55 GMT 2007


At file:///home/jelmer/bzr.samba/SAMBA_4_0/

------------------------------------------------------------
revno: 11561
revision-id: jelmer at samba.org-20070221141543-vl5ror4myglk0fer
parent: svn-v2:21491 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818-branches%2fSAMBA_4_0
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: SAMBA_4_0
timestamp: Wed 2007-02-21 15:15:43 +0100
message:
  Finish work on nested type support in EJS.
modified:
  source/pidl/TODO               svn-v2:9459 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818-branches%2fSAMBA_4_0-source%2fpidl%2fTODO
  source/pidl/lib/Parse/Pidl/Samba4/EJS.pm svn-v2:12463 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818-branches%2fSAMBA_4_0-source%2fpidl%2flib%2fParse%2fPidl%2fSamba4%2fEJS.pm
  source/pidl/lib/Parse/Pidl/Samba4/Header.pm svn-v2:12463 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818-branches%2fSAMBA_4_0-source%2fpidl%2flib%2fParse%2fPidl%2fSamba4%2fHeader.pm
=== modified file 'source/pidl/TODO'
--- a/source/pidl/TODO	2007-02-18 16:21:28 +0000
+++ b/source/pidl/TODO	2007-02-21 14:15:43 +0000
@@ -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

=== modified file 'source/pidl/lib/Parse/Pidl/Samba4/EJS.pm'
--- a/source/pidl/lib/Parse/Pidl/Samba4/EJS.pm	2007-02-21 12:35:21 +0000
+++ b/source/pidl/lib/Parse/Pidl/Samba4/EJS.pm	2007-02-21 14:15:43 +0000
@@ -110,22 +110,25 @@
 
 	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 @@
 	pidl "NDR_CHECK(ejs_pull_string(ejs, v, $name, $var));";
 }
 
-
 ###########################
 # pull an array element
 sub EjsPullArray($$$$$)
@@ -250,29 +252,20 @@
 # 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 @@
 		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 @@
 	}
 	deindent;
 	pidl "}";
-	pidl "return NT_STATUS_OK;";
-	deindent;
-	pidl "}";
 }
 
 ##############################################
@@ -323,50 +313,66 @@
 # 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 @@
 	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);
-        }
-
-	my $t;
-	if (ref($e->{TYPE}) eq "HASH") {
-		$t = "$e->{TYPE}->{TYPE}_$e->{TYPE}->{NAME}";
-	} else {
-		$t = $e->{TYPE};
+		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};
+		}
+
+		pidl "NDR_CHECK(ejs_push_$t(ejs, v, $name, $var));";
 	}
-
-	pidl "NDR_CHECK(ejs_push_$t(ejs, v, $name, $var));";
 }
 
 ###########################
@@ -470,7 +480,6 @@
 	EjsPushElement($e, GetNextLevel($e, $l), $var, $name, $env);
 }
 
-
 ###########################
 # push an array element
 sub EjsPushArray($$$$$)
@@ -538,29 +547,20 @@
 # 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 @@
 		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 @@
 	}
 	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 @@
 			$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 @@
 	pidl "}\n";
 }
 
-
 #################################
 # generate a ejs mapping function
 sub EjsFunction($$)
@@ -730,8 +737,8 @@
 	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}}) {

=== modified file 'source/pidl/lib/Parse/Pidl/Samba4/Header.pm'
--- a/source/pidl/lib/Parse/Pidl/Samba4/Header.pm	2007-02-21 10:55:03 +0000
+++ b/source/pidl/lib/Parse/Pidl/Samba4/Header.pm	2007-02-21 14:15:43 +0000
@@ -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 @@
 		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}})
 		{



More information about the samba-cvs mailing list