summaryrefslogtreecommitdiff
path: root/source4/build/pidl
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-07-08 08:18:52 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:19:23 -0500
commitf55b2b96108d71197807b46af16085167556bf6e (patch)
tree2b566f6a0c7e16d8f65f3653c9737c68f3954be3 /source4/build/pidl
parent0b92507760910872d5f0f3fe2c45f4f3af3466eb (diff)
downloadsamba-f55b2b96108d71197807b46af16085167556bf6e.tar.gz
samba-f55b2b96108d71197807b46af16085167556bf6e.tar.bz2
samba-f55b2b96108d71197807b46af16085167556bf6e.zip
r8233: - added support for more base types in pidl ejs
- added auto generation of a header with prototypes for public ejs functions - make public functions non-static - fixed allocation of fixed sized arrays - added 'noejs' flag indicating that a typedef will be handled manually by ejs - added manual functions for sid and GUID, so they show up as nice strings in ejs scripts This allows ejs to bring in samr, security, lsa and misc IDL functions (This used to be commit a8cb2dbdcc2871090a26f580f67db8f0636d1e7e)
Diffstat (limited to 'source4/build/pidl')
-rw-r--r--source4/build/pidl/ejs.pm86
-rw-r--r--source4/build/pidl/ejs_header.pm75
-rwxr-xr-xsource4/build/pidl/pidl.pl5
-rw-r--r--source4/build/pidl/validator.pm1
4 files changed, 149 insertions, 18 deletions
diff --git a/source4/build/pidl/ejs.pm b/source4/build/pidl/ejs.pm
index 24204b79b3..751f7f326e 100644
--- a/source4/build/pidl/ejs.pm
+++ b/source4/build/pidl/ejs.pm
@@ -88,6 +88,15 @@ sub get_value_of($)
}
}
+#####################################################################
+# work out is a parse function should be declared static or not
+sub fn_prefix($)
+{
+ my $fn = shift;
+
+ return "" if (util::has_property($fn, "public"));
+ return "static ";
+}
###########################
# pull a scalar element
@@ -95,6 +104,10 @@ sub EjsPullScalar($$$$$)
{
my ($e, $l, $var, $name, $env) = @_;
$var = get_pointer_to($var);
+ # have to handle strings specially :(
+ if ($e->{TYPE} eq "string") {
+ $var = get_pointer_to($var);
+ }
pidl "\tNDR_CHECK(ejs_pull_$e->{TYPE}(ejs, v, $name, $var));\n";
}
@@ -103,7 +116,7 @@ sub EjsPullScalar($$$$$)
sub EjsPullPointer($$$$$)
{
my ($e, $l, $var, $name, $env) = @_;
- pidl "EJS_ALLOC(ejs, $var);\n";
+ pidl "\tEJS_ALLOC(ejs, $var);\n";
$var = get_value_of($var);
EjsPullElement($e, Ndr::GetNextLevel($e, $l), $var, $name, $env);
}
@@ -124,10 +137,20 @@ sub EjsPullArray($$$$$)
{
my ($e, $l, $var, $name, $env) = @_;
my $length = util::ParseExpr($l->{LENGTH_IS}, $env);
- 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";
+ my $pl = Ndr::GetPrevLevel($e, $l);
+ if ($pl && $pl->{TYPE} eq "POINTER") {
+ $var = get_pointer_to($var);
+ }
+ my $avar = $var . "[i]";
+ pidl "\t{ uint32_t i;\n";
+ if (!$l->{IS_FIXED}) {
+ pidl "\tEJS_ALLOC_N(ejs, $var, $length);\n";
+ }
+ pidl "\tfor (i=0;i<$length;i++) {\n";
+ pidl "\tchar *id = talloc_asprintf(ejs, \"%s.%u\", $name, i);\n";
+ EjsPullElement($e, Ndr::GetNextLevel($e, $l), $avar, "id", $env);
+ pidl "\ttalloc_free(id);\n";
+ pidl "\t}\nejs_push_uint32(ejs, v, $name \".length\", &i); }\n";
}
###########################
@@ -179,7 +202,8 @@ sub EjsStructPull($$)
my $name = shift;
my $d = shift;
my $env = GenerateStructEnv($d);
- pidl "\nstatic NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, struct $name *r)\n{\n";
+ pidl fn_prefix($d);
+ pidl "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}}) {
EjsPullElementTop($e, $env);
@@ -196,7 +220,8 @@ sub EjsUnionPull($$)
my $d = shift;
my $have_default = 0;
my $env = GenerateStructEnv($d);
- pidl "\nstatic NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, union $name *r)\n{\n";
+ pidl fn_prefix($d);
+ pidl "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, union $name *r)\n{\n";
pidl "\tNDR_CHECK(ejs_pull_struct_start(ejs, &v, name));\n";
pidl "switch (ejs->switch_var) {\n";
foreach my $e (@{$d->{ELEMENTS}}) {
@@ -222,7 +247,8 @@ sub EjsEnumPull($$)
{
my $name = shift;
my $d = shift;
- pidl "\nstatic NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, enum $name *r)\n{\n";
+ pidl fn_prefix($d);
+ pidl "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, enum $name *r)\n{\n";
pidl "\tunsigned e;\n";
pidl "\tNDR_CHECK(ejs_pull_enum(ejs, v, name, &e));\n";
pidl "\t*r = e;\n";
@@ -234,7 +260,14 @@ sub EjsEnumPull($$)
# pull a bitmap
sub EjsBitmapPull($$)
{
-# ignored for now
+ my $name = shift;
+ my $d = shift;
+ my $type_fn = $d->{BASE_TYPE};
+ my($type_decl) = typelist::mapType($d->{BASE_TYPE});
+ pidl fn_prefix($d);
+ pidl "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, $type_decl *r)\n{\n";
+ pidl "return ejs_pull_$type_fn(ejs, v, name, r);\n";
+ pidl "}\n";
}
@@ -243,6 +276,7 @@ sub EjsBitmapPull($$)
sub EjsTypedefPull($)
{
my $d = shift;
+ return if (util::has_property($d, "noejs"));
if ($d->{DATA}->{TYPE} eq 'STRUCT') {
EjsStructPull($d->{NAME}, $d->{DATA});
} elsif ($d->{DATA}->{TYPE} eq 'UNION') {
@@ -322,9 +356,14 @@ sub EjsPushArray($$$$$)
{
my ($e, $l, $var, $name, $env) = @_;
my $length = util::ParseExpr($l->{LENGTH_IS}, $env);
+ my $pl = Ndr::GetPrevLevel($e, $l);
+ if ($pl && $pl->{TYPE} eq "POINTER") {
+ $var = get_pointer_to($var);
+ }
+ my $avar = $var . "[i]";
pidl "{ uint32_t i; for (i=0;i<$length;i++) {\n";
pidl "\tconst char *id = talloc_asprintf(ejs, \"%s.%u\", $name, i);\n";
- EjsPushElement($e, Ndr::GetNextLevel($e, $l), $var . "[i]", "id", $env);
+ EjsPushElement($e, Ndr::GetNextLevel($e, $l), $avar, "id", $env);
pidl "}\nejs_push_uint32(ejs, v, $name \".length\", &i); }\n";
}
@@ -367,7 +406,8 @@ sub EjsStructPush($$)
my $name = shift;
my $d = shift;
my $env = GenerateStructEnv($d);
- pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const struct $name *r)\n{\n";
+ pidl fn_prefix($d);
+ pidl "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const struct $name *r)\n{\n";
pidl "\tNDR_CHECK(ejs_push_struct_start(ejs, &v, name));\n";
foreach my $e (@{$d->{ELEMENTS}}) {
EjsPushElementTop($e, $env);
@@ -384,7 +424,8 @@ sub EjsUnionPush($$)
my $d = shift;
my $have_default = 0;
my $env = GenerateStructEnv($d);
- pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const union $name *r)\n{\n";
+ pidl fn_prefix($d);
+ pidl "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const union $name *r)\n{\n";
pidl "\tNDR_CHECK(ejs_push_struct_start(ejs, &v, name));\n";
pidl "switch (ejs->switch_var) {\n";
foreach my $e (@{$d->{ELEMENTS}}) {
@@ -421,7 +462,8 @@ sub EjsEnumPush($$)
$constants{$e} = $v;
$v++;
}
- pidl "\nstatic NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const enum $name *r)\n{\n";
+ pidl fn_prefix($d);
+ pidl "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const enum $name *r)\n{\n";
pidl "\tunsigned e = *r;\n";
pidl "\tNDR_CHECK(ejs_push_enum(ejs, v, name, &e));\n";
pidl "\treturn NT_STATUS_OK;\n";
@@ -433,8 +475,13 @@ sub EjsEnumPush($$)
sub EjsBitmapPush($$)
{
my $name = shift;
- my $e = shift;
-# print util::MyDumper($e);
+ my $d = shift;
+ my $type_fn = $d->{BASE_TYPE};
+ my($type_decl) = typelist::mapType($d->{BASE_TYPE});
+ pidl fn_prefix($d);
+ pidl "NTSTATUS ejs_push_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, const $type_decl *r)\n{\n";
+ pidl "return ejs_push_$type_fn(ejs, v, name, r);\n";
+ pidl "}\n";
}
@@ -443,6 +490,7 @@ sub EjsBitmapPush($$)
sub EjsTypedefPush($)
{
my $d = shift;
+ return if (util::has_property($d, "noejs"));
if ($d->{DATA}->{TYPE} eq 'STRUCT') {
EjsStructPush($d->{NAME}, $d->{DATA});
} elsif ($d->{DATA}->{TYPE} eq 'UNION') {
@@ -542,14 +590,18 @@ sub EjsInterface($)
sub Parse($$)
{
my($ndr,$hdr) = @_;
-
+
+ my $ejs_hdr = $hdr;
+ $ejs_hdr =~ s/.h$/_ejs.h/;
$res = "";
pidl "
/* EJS wrapper functions auto-generated by pidl */
#include \"includes.h\"
#include \"lib/ejs/ejs.h\"
-#include \"$hdr\"
#include \"scripting/ejs/ejsrpc.h\"
+#include \"librpc/gen_ndr/ndr_misc_ejs.h\"
+#include \"$hdr\"
+#include \"$ejs_hdr\"
";
foreach my $x (@{$ndr}) {
diff --git a/source4/build/pidl/ejs_header.pm b/source4/build/pidl/ejs_header.pm
new file mode 100644
index 0000000000..af6b4d426d
--- /dev/null
+++ b/source4/build/pidl/ejs_header.pm
@@ -0,0 +1,75 @@
+###################################################
+# create C header files for an EJS mapping functions
+# Copyright tridge@samba.org 2005
+# released under the GNU GPL
+
+package EjsHeader;
+
+use strict;
+use pidl::typelist;
+
+my($res);
+
+sub pidl ($)
+{
+ $res .= shift;
+}
+
+#####################################################################
+# prototype a typedef
+sub HeaderTypedefProto($)
+{
+ my $d = shift;
+ my $name = $d->{NAME};
+
+ return unless util::has_property($d, "public");
+
+ my $type_decl = typelist::mapType($name);
+
+ pidl "NTSTATUS ejs_push_$d->{NAME}(struct ejs_rpc *, struct MprVar *, const char *, const $type_decl *);\n";
+ pidl "NTSTATUS ejs_pull_$d->{NAME}(struct ejs_rpc *, struct MprVar *, const char *, $type_decl *);\n";
+}
+
+#####################################################################
+# parse the interface definitions
+sub HeaderInterface($)
+{
+ my($interface) = shift;
+
+ my $count = 0;
+
+ pidl "#ifndef _HEADER_EJS_$interface->{NAME}\n";
+ pidl "#define _HEADER_EJS_$interface->{NAME}\n\n";
+
+ if (defined $interface->{PROPERTIES}->{depends}) {
+ my @d = split / /, $interface->{PROPERTIES}->{depends};
+ foreach my $i (@d) {
+ pidl "#include \"librpc/gen_ndr/ndr_$i\_ejs\.h\"\n";
+ }
+ }
+
+ pidl "\n";
+
+ foreach my $d (@{$interface->{TYPEDEFS}}) {
+ HeaderTypedefProto($d);
+ }
+
+ pidl "\n";
+ pidl "#endif /* _HEADER_EJS_$interface->{NAME} */\n";
+}
+
+#####################################################################
+# parse a parsed IDL into a C header
+sub Parse($)
+{
+ my($idl) = shift;
+
+ $res = "";
+ pidl "/* header auto-generated by pidl */\n\n";
+ foreach my $x (@{$idl}) {
+ ($x->{TYPE} eq "INTERFACE") && HeaderInterface($x);
+ }
+ return $res;
+}
+
+1;
diff --git a/source4/build/pidl/pidl.pl b/source4/build/pidl/pidl.pl
index daf404d38f..9f37f7e795 100755
--- a/source4/build/pidl/pidl.pl
+++ b/source4/build/pidl/pidl.pl
@@ -32,6 +32,7 @@ use pidl::template;
use pidl::swig;
use pidl::compat;
use pidl::ejs;
+use pidl::ejs_header;
my($opt_help) = 0;
my($opt_parse) = 0;
@@ -209,7 +210,6 @@ sub process_file($)
defined($opt_server) or defined($opt_parser) or
defined($opt_ejs)) {
$ndr = Ndr::Parse($pidl);
-# print util::MyDumper($ndr);
}
if (defined($opt_header)) {
@@ -242,6 +242,9 @@ sub process_file($)
if (defined($opt_ejs)) {
my $ejs = ($opt_ejs or util::ChangeExtension($output, "_ejs.c"));
util::FileSave($ejs, EjsClient::Parse($ndr, $h_filename));
+
+ $ejs = ($opt_ejs or util::ChangeExtension($output, "_ejs.h"));
+ util::FileSave($ejs, EjsHeader::Parse($ndr));
}
if (defined($opt_server)) {
diff --git a/source4/build/pidl/validator.pm b/source4/build/pidl/validator.pm
index fe4dc03c4d..37dc916ffd 100644
--- a/source4/build/pidl/validator.pm
+++ b/source4/build/pidl/validator.pm
@@ -98,6 +98,7 @@ my %property_list = (
"nopush" => ["FUNCTION", "TYPEDEF"],
"nopull" => ["FUNCTION", "TYPEDEF"],
"noprint" => ["FUNCTION", "TYPEDEF"],
+ "noejs" => ["FUNCTION", "TYPEDEF"],
# union
"switch_is" => ["ELEMENT"],