r8215: switched the pull side of the ejs generator over to the recursive LEVELS based...
authorAndrew Tridgell <tridge@samba.org>
Fri, 8 Jul 2005 03:33:32 +0000 (03:33 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:19:20 +0000 (13:19 -0500)
This allows for much more complex structure mappings to be generated.
(This used to be commit 49fc14d13291b02f7b16ab0eefe7bfb26f51b1c8)

source4/build/pidl/ejs.pm
source4/scripting/ejs/ejsrpc.c
source4/scripting/ejs/ejsrpc.h

index db8db0001414bc5f6cf7a774f5939dd8963858be..1b5c34510cb91394babafc55829119c28f1dba15 100644 (file)
@@ -90,60 +90,87 @@ sub get_value_of($)
 
 ###########################
 # pull a scalar element
-sub EjsPullScalar($$)
+sub EjsPullScalar($$$$$)
 {
-       my $e = shift;
-       my $env = shift;
-       my $var = util::ParseExpr($e->{NAME}, $env);
-       my $ptr = get_pointer_to($var);
-       pidl "\tNDR_CHECK(ejs_pull_$e->{TYPE}(ejs, v, \"$e->{NAME}\", $ptr));\n";
+       my ($e, $l, $var, $name, $env) = @_;
+       $var = get_pointer_to($var);
+       pidl "\tNDR_CHECK(ejs_pull_$e->{TYPE}(ejs, v, $name, $var));\n";
+}
+
+###########################
+# pull a pointer element
+sub EjsPullPointer($$$$$)
+{
+       my ($e, $l, $var, $name, $env) = @_;
+       pidl "EJS_ALLOC(ejs, $var);\n";
+       $var = get_value_of($var);              
+       EjsPullElement($e, Ndr::GetNextLevel($e, $l), $var, $name, $env);
 }
 
 ###########################
 # pull a string element
-sub EjsPullString($$$)
+sub EjsPullString($$$$$)
 {
-       my $e = shift;
-       my $l = shift;
-       my $env = shift;
-       my $var = util::ParseExpr($e->{NAME}, $env);
-       my $ptr = get_pointer_to($var);
-       pidl "\tNDR_CHECK(ejs_pull_string(ejs, v, \"$e->{NAME}\", $ptr));\n";
+       my ($e, $l, $var, $name, $env) = @_;
+       $var = get_pointer_to($var);
+       pidl "\tNDR_CHECK(ejs_pull_string(ejs, v, $name, $var));\n";
 }
 
 
 ###########################
 # pull an arrar element
-# only handles a very limited range of array types so far
-sub EjsPullArray($$$)
+sub EjsPullArray($$$$$)
 {
-       my $e = shift;
-       my $l = shift;
-       my $env = shift;
+       my ($e, $l, $var, $name, $env) = @_;
        my $length = util::ParseExpr($l->{LENGTH_IS}, $env);
-       my $var = util::ParseExpr($e->{NAME}, $env);
-       my $ptr = get_pointer_to($var);
-       pidl "\tNDR_CHECK(ejs_pull_array(ejs, v, \"$e->{NAME}\", $length, sizeof($var\[0]), (void **)$ptr, (ejs_pull_t)ejs_pull_$e->{TYPE}));\n";
+       pidl "{ uint32_t i; EJS_ALLOC_N(ejs, $var, $length); for (i=0;i<$length;i++) {\n";
+       pidl "\tconst char *id = talloc_asprintf(ejs, \"%s.%u\", $name, i);\n";
+       EjsPullElement($e, Ndr::GetNextLevel($e, $l), $var . "[i]", "id", $env);
+       pidl "}\nejs_push_uint32(ejs, v, $name \".length\", &i); }\n";
+}
+
+###########################
+# pull a switch element
+sub EjsPullSwitch($$$$$)
+{
+       my ($e, $l, $var, $name, $env) = @_;
+       my $switch_var = util::ParseExpr($l->{SWITCH_IS}, $env);
+       pidl "ejs_set_switch(ejs, $switch_var);\n";
+       EjsPullElement($e, Ndr::GetNextLevel($e, $l), $var, $name, $env);
 }
 
 ###########################
 # pull a structure element
-sub EjsPullElement($$)
+sub EjsPullElement($$$$$)
 {
-       my $e = shift;
-       my $env = shift;
-       my $l = $e->{LEVELS}[0];
+       my ($e, $l, $var, $name, $env) = @_;
        if (util::has_property($e, "charset")) {
-               EjsPullString($e, $l, $env);
+               EjsPullString($e, $l, $var, $name, $env);
        } elsif ($l->{TYPE} eq "ARRAY") {
-               EjsPullArray($e, $l, $env);
+               EjsPullArray($e, $l, $var, $name, $env);
        } elsif ($l->{TYPE} eq "DATA") {
-               EjsPullScalar($e, $env);
+               EjsPullScalar($e, $l, $var, $name, $env);
+       } elsif (($l->{TYPE} eq "POINTER")) {
+               EjsPullPointer($e, $l, $var, $name, $env);
+       } elsif (($l->{TYPE} eq "SWITCH")) {
+               EjsPullSwitch($e, $l, $var, $name, $env);
        } else {
                pidl "return ejs_panic(ejs, \"unhandled pull type $l->{TYPE}\");\n";
        }
 }
 
+#############################################
+# pull a structure/union element at top level
+sub EjsPullElementTop($$)
+{
+       my $e = shift;
+       my $env = shift;
+       my $l = $e->{LEVELS}[0];
+       my $var = util::ParseExpr($e->{NAME}, $env);
+       my $name = "\"$e->{NAME}\"";
+       EjsPullElement($e, $l, $var, $name, $env);
+}
+
 ###########################
 # pull a struct
 sub EjsStructPull($$)
@@ -154,7 +181,7 @@ sub EjsStructPull($$)
        pidl "\nstatic NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, struct $name *r)\n{\n";
        pidl "\tNDR_CHECK(ejs_pull_struct_start(ejs, &v, name));\n";
         foreach my $e (@{$d->{ELEMENTS}}) {
-               EjsPullElement($e, $env);
+               EjsPullElementTop($e, $env);
        }
        pidl "\treturn NT_STATUS_OK;\n";
        pidl "}\n\n";
@@ -227,7 +254,7 @@ sub EjsPullFunction($)
 
        foreach my $e (@{$d->{ELEMENTS}}) {
                next unless (grep(/in/, @{$e->{DIRECTION}}));
-               EjsPullElement($e, $env);
+               EjsPullElementTop($e, $env);
        }
 
        pidl "\treturn NT_STATUS_OK;\n";
@@ -274,7 +301,6 @@ sub EjsPushSwitch($$$$$)
 
 ###########################
 # push an arrar element
-# only handles a very limited range of array types so far
 sub EjsPushArray($$$$$)
 {
        my ($e, $l, $var, $name, $env) = @_;
index 965fd8d4478e9f021a78647e1fb86d18292ffe48..574c75b7de9b5301ce68e4fa2e49efcf945e5b44 100644 (file)
@@ -253,33 +253,6 @@ NTSTATUS ejs_push_enum(struct ejs_rpc *ejs,
 }
 
 
-/*
-  pull an array of elements
-*/
-NTSTATUS ejs_pull_array(struct ejs_rpc *ejs, 
-                       struct MprVar *v, const char *name, uint32_t length,
-                       size_t elsize, void **r, ejs_pull_t ejs_pull)
-{
-       int i;
-       char *data;
-
-       NDR_CHECK(ejs_pull_struct_start(ejs, &v, name));
-
-       (*r) = talloc_array_size(ejs, elsize, length);
-       NT_STATUS_HAVE_NO_MEMORY(*r);
-
-       data = *r;
-
-       for (i=0;i<length;i++) {
-               char *id = talloc_asprintf(ejs, "%u", i);
-               NT_STATUS_HAVE_NO_MEMORY(id);
-               NDR_CHECK(ejs_pull(ejs, v, id, (i*elsize)+data));
-               talloc_free(id);
-       }
-       return NT_STATUS_OK;
-}
-
-
 /*
   pull a string
 */
index 67b81b341169fb1816dc658c336d89681e558de9..fdf15c027cb91f53a1523697b136bca894d50b9c 100644 (file)
@@ -64,10 +64,21 @@ NTSTATUS ejs_pull_enum(struct ejs_rpc *ejs,
                       struct MprVar *v, const char *name, unsigned *r);
 NTSTATUS ejs_push_enum(struct ejs_rpc *ejs, 
                       struct MprVar *v, const char *name, const unsigned *r);
-NTSTATUS ejs_pull_array(struct ejs_rpc *ejs, 
-                       struct MprVar *v, const char *name, uint32_t length,
-                       size_t elsize, void **r, ejs_pull_t ejs_pull);
 NTSTATUS ejs_pull_string(struct ejs_rpc *ejs, 
                         struct MprVar *v, const char *name, char **s);
 NTSTATUS ejs_push_string(struct ejs_rpc *ejs, 
                         struct MprVar *v, const char *name, const char *s);
+
+#define EJS_ALLOC_SIZE(ejs, s, size) do { \
+  (s) = talloc_size(ejs, size); \
+  if (!(s)) return ejs_panic(ejs, "out of memory"); \
+} while (0)
+
+#define EJS_ALLOC(ejs, s) EJS_ALLOC_SIZE(ejs, s, sizeof(*(s)))
+
+#define EJS_ALLOC_N_SIZE(ejs, s, n, elsize) do { \
+       (s) = talloc_array_size(ejs, elsize, n); \
+       if (!(s)) return ejs_panic(ejs, "out of memory"); \
+} while (0)
+
+#define EJS_ALLOC_N(ejs, s, n) EJS_ALLOC_N_SIZE(ejs, s, n, sizeof(*(s)))