use strict;
use Parse::Pidl::Typelist;
+use Parse::Pidl::Util qw(has_property);
my($res);
my %constants;
{
my $fn = shift;
- return "" if (Parse::Pidl::Util::has_property($fn, "public"));
+ return "" if (has_property($fn, "public"));
return "static ";
}
{
my ($e, $l, $var, $name, $env) = @_;
- return if (Parse::Pidl::Util::has_property($e, "value"));
+ return if (has_property($e, "value"));
- $var = get_pointer_to($var);
- # have to handle strings specially :(
- if ($e->{TYPE} eq "string") {
- $var = get_pointer_to($var);
- }
+ my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);
+ $var = get_pointer_to($var);
+ # have to handle strings specially :(
+ if ($e->{TYPE} eq "string" && $pl && $pl->{TYPE} eq "POINTER") {
+ $var = get_pointer_to($var);
+ }
pidl "NDR_CHECK(ejs_pull_$e->{TYPE}(ejs, v, $name, $var));";
}
sub EjsPullElement($$$$$)
{
my ($e, $l, $var, $name, $env) = @_;
- if (Parse::Pidl::Util::has_property($e, "charset")) {
+ if (has_property($e, "charset")) {
EjsPullString($e, $l, $var, $name, $env);
} elsif ($l->{TYPE} eq "ARRAY") {
EjsPullArray($e, $l, $var, $name, $env);
pidl "}";
}
+##############################################
+# put the enum elements in the constants array
+sub EjsEnumConstant($)
+{
+ my $d = shift;
+ my $v = 0;
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ my $el = $e;
+ chomp $el;
+ if ($el =~ /^(.*)=\s*(.*)\s*$/) {
+ $el = $1;
+ $v = $2;
+ }
+ $constants{$el} = $v;
+ $v++;
+ }
+}
+
###########################
# pull a enum
sub EjsEnumPull($$)
{
my $name = shift;
my $d = shift;
+ EjsEnumConstant($d);
pidl fn_prefix($d);
pidl "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, enum $name *r)\n{";
indent;
sub EjsTypedefPull($)
{
my $d = shift;
- return if (Parse::Pidl::Util::has_property($d, "noejs"));
+ return if (has_property($d, "noejs"));
if ($d->{DATA}->{TYPE} eq 'STRUCT') {
EjsStructPull($d->{NAME}, $d->{DATA});
} elsif ($d->{DATA}->{TYPE} eq 'UNION') {
sub EjsPushScalar($$$$$)
{
my ($e, $l, $var, $name, $env) = @_;
- $var = get_pointer_to($var);
+ # have to handle strings specially :(
+ my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);
+ if ($e->{TYPE} ne "string" || ($pl && $pl->{TYPE} eq "POINTER")) {
+ $var = get_pointer_to($var);
+ }
pidl "NDR_CHECK(ejs_push_$e->{TYPE}(ejs, v, $name, $var));";
}
sub EjsPushElement($$$$$)
{
my ($e, $l, $var, $name, $env) = @_;
- if (Parse::Pidl::Util::has_property($e, "charset")) {
+ if (has_property($e, "charset")) {
EjsPushString($e, $l, $var, $name, $env);
} elsif ($l->{TYPE} eq "ARRAY") {
EjsPushArray($e, $l, $var, $name, $env);
{
my $name = shift;
my $d = shift;
- my $v = 0;
- # put the enum elements in the constants array
- foreach my $e (@{$d->{ELEMENTS}}) {
- my $el = $e;
- chomp $el;
- if ($el =~ /^(.*)=\s*(.*)\s*$/) {
- $el = $1;
- $v = $2;
- }
- $constants{$el} = $v;
- $v++;
- }
+ EjsEnumConstant($d);
pidl fn_prefix($d);
pidl "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const enum $name *r)\n{";
indent;
sub EjsTypedefPush($)
{
my $d = shift;
- return if (Parse::Pidl::Util::has_property($d, "noejs"));
+ return if (has_property($d, "noejs"));
if ($d->{DATA}->{TYPE} eq 'STRUCT') {
EjsStructPush($d->{NAME}, $d->{DATA});
} elsif ($d->{DATA}->{TYPE} eq 'UNION') {
#################################
# generate a ejs mapping function
-sub EjsFunction($)
+sub EjsFunction($$)
{
my $d = shift;
+ my $iface = shift;
my $name = $d->{NAME};
+ my $callnum = uc("DCERPC_$name");
+ my $table = "&dcerpc_table_$iface";
pidl "static int ejs_$name(int eid, int argc, struct MprVar **argv)";
pidl "{";
indent;
- pidl "return ejs_rpc_call(eid, argc, argv, \"$name\", (ejs_pull_function_t)ejs_pull_$name, (ejs_push_function_t)ejs_push_$name);";
+ pidl "return ejs_rpc_call(eid, argc, argv, $table, $callnum, (ejs_pull_function_t)ejs_pull_$name, (ejs_push_function_t)ejs_push_$name);";
deindent;
pidl "}\n";
}
#####################################################################
# parse the interface definitions
-sub EjsInterface($)
+sub EjsInterface($$)
{
- my($interface) = shift;
+ my($interface,$needed) = @_;
my @fns = ();
my $name = $interface->{NAME};
%constants = ();
foreach my $d (@{$interface->{TYPEDEFS}}) {
- EjsTypedefPush($d);
- EjsTypedefPull($d);
+ ($needed->{"push_$d->{NAME}"}) && EjsTypedefPush($d);
+ ($needed->{"pull_$d->{NAME}"}) && EjsTypedefPull($d);
}
foreach my $d (@{$interface->{FUNCTIONS}}) {
EjsPullFunction($d);
EjsPushFunction($d);
- EjsFunction($d);
+ EjsFunction($d, $name);
push (@fns, $d->{NAME});
}
EjsConst($d);
}
- pidl "void setup_ejs_$name(void)";
+ pidl "static int ejs_$name\_init(int eid, int argc, struct MprVar **argv)";
pidl "{";
indent;
+ pidl "struct MprVar *obj = mprInitObject(eid, \"$name\", argc, argv);";
foreach (@fns) {
- pidl "ejsDefineCFunction(-1, \"dcerpc_$_\", ejs_$_, NULL, MPR_VAR_SCRIPT_HANDLE);";
+ pidl "mprSetCFunction(obj, \"$_\", ejs_$_);";
}
- deindent;
- pidl "}\n";
-
- pidl "void setup_ejs_constants_$name(int eid)";
- pidl "{";
- indent;
foreach my $v (keys %constants) {
my $value = $constants{$v};
if (substr($value, 0, 1) eq "\"") {
- pidl "ejs_set_constant_string(eid, \"$v\", $value);";
+ pidl "mprSetVar(obj, \"$v\", mprString($value));";
} else {
- pidl "ejs_set_constant_int(eid, \"$v\", $value);";
+ pidl "mprSetVar(obj, \"$v\", mprCreateNumberVar($value));";
}
}
+ pidl "return 0;";
deindent;
pidl "}\n";
pidl "NTSTATUS ejs_init_$name(void)";
pidl "{";
indent;
- pidl "return smbcalls_register_ejs(\"$name\", setup_ejs_$name, setup_ejs_constants_$name);";
+ pidl "return smbcalls_register_ejs(\"$name\_init\", ejs_$name\_init);";
deindent;
pidl "}";
}
pidl "
/* EJS wrapper functions auto-generated by pidl */
#include \"includes.h\"
-#include \"lib/ejs/ejs.h\"
+#include \"lib/appweb/ejs/ejs.h\"
#include \"scripting/ejs/ejsrpc.h\"
+#include \"scripting/ejs/smbcalls.h\"
#include \"librpc/gen_ndr/ndr_misc_ejs.h\"
#include \"$hdr\"
#include \"$ejs_hdr\"
";
+
+ my %needed = ();
+
+ foreach my $x (@{$ndr}) {
+ ($x->{TYPE} eq "INTERFACE") && NeededInterface($x, \%needed);
+ }
+
foreach my $x (@{$ndr}) {
- if ($x->{TYPE} eq "INTERFACE") {
- ($x->{TYPE} eq "INTERFACE") && EjsInterface($x);
- }
+ ($x->{TYPE} eq "INTERFACE") && EjsInterface($x, \%needed);
}
return $res;
}
+sub NeededFunction($$)
+{
+ my ($fn,$needed) = @_;
+ $needed->{"pull_$fn->{NAME}"} = 1;
+ $needed->{"push_$fn->{NAME}"} = 1;
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ if (grep (/in/, @{$e->{DIRECTION}})) {
+ $needed->{"pull_$e->{TYPE}"} = 1;
+ }
+ if (grep (/out/, @{$e->{DIRECTION}})) {
+ $needed->{"push_$e->{TYPE}"} = 1;
+ }
+ }
+}
+
+sub NeededTypedef($$)
+{
+ my ($t,$needed) = @_;
+ if (Parse::Pidl::Util::has_property($t, "public")) {
+ $needed->{"pull_$t->{NAME}"} = not Parse::Pidl::Util::has_property($t, "noejs");
+ $needed->{"push_$t->{NAME}"} = not Parse::Pidl::Util::has_property($t, "noejs");
+ }
+ if ($t->{DATA}->{TYPE} ne "STRUCT" &&
+ $t->{DATA}->{TYPE} ne "UNION") {
+ return;
+ }
+ for my $e (@{$t->{DATA}->{ELEMENTS}}) {
+ if ($needed->{"pull_$t->{NAME}"}) {
+ $needed->{"pull_$e->{TYPE}"} = 1;
+ }
+ if ($needed->{"push_$t->{NAME}"}) {
+ $needed->{"push_$e->{TYPE}"} = 1;
+ }
+ }
+}
+
+#####################################################################
+# work out what parse functions are needed
+sub NeededInterface($$)
+{
+ my ($interface,$needed) = @_;
+ foreach my $d (@{$interface->{FUNCTIONS}}) {
+ NeededFunction($d, $needed);
+ }
+ foreach my $d (reverse @{$interface->{TYPEDEFS}}) {
+ NeededTypedef($d, $needed);
+ }
+}
+
1;