summaryrefslogtreecommitdiff
path: root/source4/build/pidl
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-11-11 01:59:28 +0000
committerAndrew Tridgell <tridge@samba.org>2003-11-11 01:59:28 +0000
commitbe443f914af377fc97d4cfd56f13d95edbcc645f (patch)
tree6d5af6e49984f5b53492f313445eb5a4ca6c5fbe /source4/build/pidl
parent657dc577b614f388b55bd52a16e8e014c72bf2db (diff)
downloadsamba-be443f914af377fc97d4cfd56f13d95edbcc645f.tar.gz
samba-be443f914af377fc97d4cfd56f13d95edbcc645f.tar.bz2
samba-be443f914af377fc97d4cfd56f13d95edbcc645f.zip
- added support for the pull side of unions
- don't generate parse functions for pull/push functions that are not used (This used to be commit 54613574bcd8b365c13848c6aa9366cadeb5da0e)
Diffstat (limited to 'source4/build/pidl')
-rw-r--r--source4/build/pidl/header.pm105
-rw-r--r--source4/build/pidl/idl.gram4
-rw-r--r--source4/build/pidl/parser.pm185
-rwxr-xr-xsource4/build/pidl/pidl.pl2
-rw-r--r--source4/build/pidl/util.pm1
5 files changed, 216 insertions, 81 deletions
diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/header.pm
index 561a16a1e2..6e8842b1d7 100644
--- a/source4/build/pidl/header.pm
+++ b/source4/build/pidl/header.pm
@@ -17,8 +17,8 @@ sub tabs()
}
#####################################################################
-# dump a properties list
-sub DumpProperties($)
+# parse a properties list
+sub HeaderProperties($)
{
my($props) = shift;
@@ -36,8 +36,8 @@ sub DumpProperties($)
}
#####################################################################
-# dump a structure element
-sub DumpElement($)
+# parse a structure element
+sub HeaderElement($)
{
my($element) = shift;
@@ -49,9 +49,9 @@ sub DumpElement($)
}
- (defined $element->{PROPERTIES}) && DumpProperties($element->{PROPERTIES});
+ (defined $element->{PROPERTIES}) && HeaderProperties($element->{PROPERTIES});
$res .= tabs();
- DumpType($element->{TYPE}, "");
+ HeaderType($element, $element->{TYPE}, "");
$res .= " ";
if ($element->{POINTERS}) {
my($n) = $element->{POINTERS};
@@ -72,8 +72,8 @@ sub DumpElement($)
}
#####################################################################
-# dump a struct
-sub DumpStruct($$)
+# parse a struct
+sub HeaderStruct($$)
{
my($struct) = shift;
my($name) = shift;
@@ -81,7 +81,7 @@ sub DumpStruct($$)
$tab_depth++;
if (defined $struct->{ELEMENTS}) {
foreach my $e (@{$struct->{ELEMENTS}}) {
- DumpElement($e);
+ HeaderElement($e);
}
}
$tab_depth--;
@@ -90,76 +90,79 @@ sub DumpStruct($$)
#####################################################################
-# dump a union element
-sub DumpUnionElement($)
+# parse a union element
+sub HeaderUnionElement($)
{
my($element) = shift;
$res .= "/* [case($element->{CASE})] */ ";
- DumpElement($element->{DATA});
+ HeaderElement($element->{DATA});
}
#####################################################################
-# dump a union
-sub DumpUnion($$)
+# parse a union
+sub HeaderUnion($$)
{
my($union) = shift;
my($name) = shift;
- (defined $union->{PROPERTIES}) && DumpProperties($union->{PROPERTIES});
+ (defined $union->{PROPERTIES}) && HeaderProperties($union->{PROPERTIES});
$res .= "union $name {\n";
foreach my $e (@{$union->{DATA}}) {
- DumpUnionElement($e);
+ HeaderUnionElement($e);
}
$res .= "}";
}
#####################################################################
-# dump a type
-sub DumpType($$)
+# parse a type
+sub HeaderType($$$)
{
- my($data) = shift;
- my($name) = shift;
- if (ref($data) eq "HASH") {
- ($data->{TYPE} eq "STRUCT") &&
- DumpStruct($data, $name);
- ($data->{TYPE} eq "UNION") &&
- DumpUnion($data, $name);
- return;
- }
- if ($data =~ "unistr") {
- $res .= "const char";
- } elsif (util::is_scalar_type($data)) {
- $res .= "$data";
- } else {
- $res .= "struct $data";
- }
+ my $e = shift;
+ my($data) = shift;
+ my($name) = shift;
+ if (ref($data) eq "HASH") {
+ ($data->{TYPE} eq "STRUCT") &&
+ HeaderStruct($data, $name);
+ ($data->{TYPE} eq "UNION") &&
+ HeaderUnion($data, $name);
+ return;
+ }
+ if ($data =~ "unistr") {
+ $res .= "const char";
+ } elsif (util::is_scalar_type($data)) {
+ $res .= "$data";
+ } elsif (util::has_property($e, "switch_is")) {
+ $res .= "union $data";
+ } else {
+ $res .= "struct $data";
+ }
}
#####################################################################
-# dump a typedef
-sub DumpTypedef($)
+# parse a typedef
+sub HeaderTypedef($)
{
my($typedef) = shift;
- DumpType($typedef->{DATA}, $typedef->{NAME});
+ HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
$res .= ";\n\n";
}
#####################################################################
-# dump a function
-sub DumpFunctionInOut($$)
+# parse a function
+sub HeaderFunctionInOut($$)
{
my($fn) = shift;
my($prop) = shift;
foreach my $e (@{$fn->{DATA}}) {
if (util::has_property($e, $prop)) {
- DumpElement($e);
+ HeaderElement($e);
}
}
}
#####################################################################
-# dump a function
-sub DumpFunction($)
+# parse a function
+sub HeaderFunction($)
{
my($fn) = shift;
$res .= "struct $fn->{NAME} {\n";
@@ -167,14 +170,14 @@ sub DumpFunction($)
tabs();
$res .= "struct {\n";
$tab_depth++;
- DumpFunctionInOut($fn, "in");
+ HeaderFunctionInOut($fn, "in");
$tab_depth--;
tabs();
$res .= "} in;\n\n";
tabs();
$res .= "struct {\n";
$tab_depth++;
- DumpFunctionInOut($fn, "out");
+ HeaderFunctionInOut($fn, "out");
if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
tabs();
$res .= "$fn->{RETURN_TYPE} result;\n";
@@ -187,16 +190,16 @@ sub DumpFunction($)
}
#####################################################################
-# dump the interface definitions
-sub DumpInterface($)
+# parse the interface definitions
+sub HeaderInterface($)
{
my($interface) = shift;
my($data) = $interface->{DATA};
foreach my $d (@{$data}) {
($d->{TYPE} eq "TYPEDEF") &&
- DumpTypedef($d);
+ HeaderTypedef($d);
($d->{TYPE} eq "FUNCTION") &&
- DumpFunction($d);
+ HeaderFunction($d);
}
my $count = 0;
@@ -212,8 +215,8 @@ sub DumpInterface($)
#####################################################################
-# dump a parsed IDL structure back into an IDL file
-sub Dump($)
+# parse a parsed IDL into a C header
+sub Parse($)
{
my($idl) = shift;
$tab_depth = 0;
@@ -221,7 +224,7 @@ sub Dump($)
$res = "/* header auto-generated by pidl */\n\n";
foreach my $x (@{$idl}) {
($x->{TYPE} eq "INTERFACE") &&
- DumpInterface($x);
+ HeaderInterface($x);
}
return $res;
}
diff --git a/source4/build/pidl/idl.gram b/source4/build/pidl/idl.gram
index c3723a14af..c08c6b0e81 100644
--- a/source4/build/pidl/idl.gram
+++ b/source4/build/pidl/idl.gram
@@ -53,13 +53,13 @@ union: property_list(s?) 'union' <commit> '{' union_element(s?) '}'
}}
| <error?>
-union_element: '[case(' constant ')]' base_element ';'
+union_element: '[' 'case' '(' constant ')' ']' base_element ';'
{{
"TYPE" => "UNION_ELEMENT",
"CASE" => $item{constant},
"DATA" => $item{base_element}
}}
- | 'case(' constant ')' base_element ';'
+ | 'case' '(' constant ')' base_element ';'
{{
"TYPE" => "UNION_ELEMENT",
"CASE" => $item{constant},
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index 32fa66f416..1b09347052 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -10,6 +10,9 @@ use Data::Dumper;
my($res);
+# the list of needed functions
+my %needed;
+
#####################################################################
# parse a properties list
sub ParseProperties($)
@@ -28,11 +31,11 @@ sub ParseProperties($)
####################################################################
# work out the name of a size_is() variable
-sub find_size_var($)
+sub find_size_var($$)
{
my($e) = shift;
+ my($size) = shift;
my($fn) = $e->{PARENT};
- my($size) = util::array_size($e);
if ($fn->{TYPE} ne "FUNCTION") {
return "r->$size";
@@ -48,7 +51,7 @@ sub find_size_var($)
}
}
}
- die "invalid variable in size_is($size) for element $e->{NAME} in $fn->{NAME}\n";
+ die "invalid variable in $size for element $e->{NAME} in $fn->{NAME}\n";
}
@@ -58,7 +61,7 @@ sub ParseArrayPush($$)
{
my $e = shift;
my $var_prefix = shift;
- my $size = find_size_var($e);
+ my $size = find_size_var($e, util::array_size($e));
if (util::is_scalar_type($e->{TYPE})) {
$res .= "\t\tNDR_CHECK(ndr_push_array_$e->{TYPE}(ndr, $var_prefix$e->{NAME}, $size));\n";
@@ -73,7 +76,7 @@ sub ParseArrayPull($$)
{
my $e = shift;
my $var_prefix = shift;
- my $size = find_size_var($e);
+ my $size = find_size_var($e, util::array_size($e));
if (util::need_alloc($e)) {
$res .= "\t\tNDR_ALLOC_N_SIZE(ndr, $var_prefix$e->{NAME}, $size, sizeof($var_prefix$e->{NAME}\[0]));\n";
@@ -108,6 +111,25 @@ sub ParseElementPushScalar($$$)
#####################################################################
# parse scalars in a structure element - pull size
+sub ParseElementPullSwitch($$$$)
+{
+ my($e) = shift;
+ my($var_prefix) = shift;
+ my($ndr_flags) = shift;
+ my $switch = shift;
+ my $switch_var = find_size_var($e, $switch);
+
+ my $cprefix = util::c_pull_prefix($e);
+
+ $res .= "\t{ uint16 _level;\n";
+ $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, &_level, $cprefix$var_prefix$e->{NAME}));\n";
+ $res .= "\tif (_level != $switch_var) return NT_STATUS_INVALID_LEVEL;\n";
+ $res .= "\t}\n";
+}
+
+
+#####################################################################
+# parse scalars in a structure element - pull size
sub ParseElementPullScalar($$$)
{
my($e) = shift;
@@ -126,6 +148,8 @@ sub ParseElementPullScalar($$$)
$res .= "\t}\n";
} elsif (util::need_alloc($e)) {
# no scalar component
+ } elsif (my $switch = util::has_property($e, "switch_is")) {
+ ParseElementPullSwitch($e, $var_prefix, $ndr_flags, $switch);
} elsif (util::is_builtin_type($e->{TYPE})) {
$res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
} else {
@@ -182,6 +206,8 @@ sub ParseElementPullBuffer($$$)
if (util::array_size($e)) {
ParseArrayPull($e, "r->");
+ } elsif (my $switch = util::has_property($e, "switch_is")) {
+ ParseElementPullSwitch($e, $var_prefix, $ndr_flags, $switch);
} elsif (util::is_builtin_type($e->{TYPE})) {
$res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
} else {
@@ -307,24 +333,41 @@ sub ParseStructPull($)
#####################################################################
-# parse a union element
-sub ParseUnionElementPush($)
-{
- die "unions not done";
-}
-
-#####################################################################
# parse a union - push side
sub ParseUnionPush($)
{
- die "unions not done";
+ my $e = shift;
+ print "WARNING! union push not done\n";
}
#####################################################################
# parse a union - pull side
sub ParseUnionPull($)
{
- die "unions not done";
+ my $e = shift;
+ print "union pull not done\n";
+
+ $res .= "\tNDR_CHECK(ndr_pull_uint16(ndr, level));\n";
+ $res .= "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
+ $res .= "\tswitch (*level) {\n";
+ foreach my $el (@{$e->{DATA}}) {
+ $res .= "\tcase $el->{CASE}:\n";
+ ParseElementPullScalar($el->{DATA}, "r->", "NDR_SCALARS");
+ $res .= "\tbreak;\n\n";
+ }
+ $res .= "\tdefault:\n\t\treturn NT_STATUS_INVALID_LEVEL;\n";
+ $res .= "\t}\n";
+ $res .= "buffers:\n";
+ $res .= "\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
+ $res .= "\tswitch (*level) {\n";
+ foreach my $el (@{$e->{DATA}}) {
+ $res .= "\tcase $el->{CASE}:\n";
+ ParseElementPullBuffer($el->{DATA}, "r->", "NDR_BUFFERS");
+ $res .= "\tbreak;\n\n";
+ }
+ $res .= "\tdefault:\n\t\treturn NT_STATUS_INVALID_LEVEL;\n";
+ $res .= "\t}\n";
+ $res .= "done:\n";
}
#####################################################################
@@ -337,7 +380,7 @@ sub ParseTypePush($)
($data->{TYPE} eq "STRUCT") &&
ParseStructPush($data);
($data->{TYPE} eq "UNION") &&
- ParseUnionPush($data);
+ ParseUnionPush($data);
}
}
@@ -361,11 +404,26 @@ sub ParseTypedefPush($)
{
my($e) = shift;
- $res .= "static NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, struct $e->{NAME} *r)";
- $res .= "\n{\n";
- ParseTypePush($e->{DATA});
- $res .= "\treturn NT_STATUS_OK;\n";
- $res .= "}\n\n";
+ if (! $needed{"push_$e->{NAME}"}) {
+# print "push_$e->{NAME} not needed\n";
+ return;
+ }
+
+ if ($e->{DATA}->{TYPE} eq "STRUCT") {
+ $res .= "static NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, struct $e->{NAME} *r)";
+ $res .= "\n{\n";
+ ParseTypePush($e->{DATA});
+ $res .= "\treturn NT_STATUS_OK;\n";
+ $res .= "}\n\n";
+ }
+
+ if ($e->{DATA}->{TYPE} eq "UNION") {
+ $res .= "static NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, uint16 level, union $e->{NAME} *r)";
+ $res .= "\n{\n";
+ ParseTypePush($e->{DATA});
+ $res .= "\treturn NT_STATUS_OK;\n";
+ $res .= "}\n\n";
+ }
}
@@ -375,11 +433,26 @@ sub ParseTypedefPull($)
{
my($e) = shift;
- $res .= "static NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, struct $e->{NAME} *r)";
- $res .= "\n{\n";
- ParseTypePull($e->{DATA});
- $res .= "\treturn NT_STATUS_OK;\n";
- $res .= "}\n\n";
+ if (! $needed{"pull_$e->{NAME}"}) {
+# print "pull_$e->{NAME} not needed\n";
+ return;
+ }
+
+ if ($e->{DATA}->{TYPE} eq "STRUCT") {
+ $res .= "static NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, struct $e->{NAME} *r)";
+ $res .= "\n{\n";
+ ParseTypePull($e->{DATA});
+ $res .= "\treturn NT_STATUS_OK;\n";
+ $res .= "}\n\n";
+ }
+
+ if ($e->{DATA}->{TYPE} eq "UNION") {
+ $res .= "static NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, uint16 *level, union $e->{NAME} *r)";
+ $res .= "\n{\n";
+ ParseTypePull($e->{DATA});
+ $res .= "\treturn NT_STATUS_OK;\n";
+ $res .= "}\n\n";
+ }
}
@@ -489,6 +562,62 @@ sub ParseInterface($)
}
}
+sub NeededFunction($)
+{
+ my $fn = shift;
+ $needed{"pull_$fn->{NAME}"} = 1;
+ $needed{"push_$fn->{NAME}"} = 1;
+ foreach my $e (@{$fn->{DATA}}) {
+ if (util::has_property($e, "out")) {
+ $needed{"pull_$e->{TYPE}"} = 1;
+ }
+ if (util::has_property($e, "in")) {
+ $needed{"push_$e->{TYPE}"} = 1;
+ }
+ }
+}
+
+sub NeededTypedef($)
+{
+ my $t = shift;
+ if ($t->{DATA}->{TYPE} eq "STRUCT") {
+ 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;
+ }
+ }
+ }
+ if ($t->{DATA}->{TYPE} eq "UNION") {
+ for my $e (@{$t->{DATA}->{DATA}}) {
+ if ($needed{"pull_$t->{NAME}"}) {
+ $needed{"pull_$e->{DATA}->{TYPE}"} = 1;
+ }
+ if ($needed{"push_$t->{NAME}"}) {
+ $needed{"push_$e->{DATA}->{TYPE}"} = 1;
+ }
+ }
+ }
+}
+
+#####################################################################
+# work out what parse functions are needed
+sub BuildNeeded($)
+{
+ my($interface) = shift;
+ my($data) = $interface->{DATA};
+ foreach my $d (@{$data}) {
+ ($d->{TYPE} eq "FUNCTION") &&
+ NeededFunction($d);
+ }
+ foreach my $d (reverse @{$data}) {
+ ($d->{TYPE} eq "TYPEDEF") &&
+ NeededTypedef($d);
+ }
+}
+
#####################################################################
# parse a parsed IDL structure back into an IDL file
@@ -498,8 +627,10 @@ sub Parse($)
$res = "/* parser auto-generated by pidl */\n\n";
$res .= "#include \"includes.h\"\n\n";
foreach my $x (@{$idl}) {
- ($x->{TYPE} eq "INTERFACE") &&
- ParseInterface($x);
+ if ($x->{TYPE} eq "INTERFACE") {
+ BuildNeeded($x);
+ ParseInterface($x);
+ }
}
return $res;
}
diff --git a/source4/build/pidl/pidl.pl b/source4/build/pidl/pidl.pl
index 8d15d86347..cd2ad9d7fc 100755
--- a/source4/build/pidl/pidl.pl
+++ b/source4/build/pidl/pidl.pl
@@ -123,7 +123,7 @@ if ($opt_header) {
my($idl) = util::LoadStructure($pidl_file);
my($header) = util::ChangeExtension($opt_output, "h");
print "Generating $header\n";
- util::FileSave($header, IdlHeader::Dump($idl));
+ util::FileSave($header, IdlHeader::Parse($idl));
}
if ($opt_parser) {
diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm
index 5bf8ac4d9a..910684a919 100644
--- a/source4/build/pidl/util.pm
+++ b/source4/build/pidl/util.pm
@@ -180,6 +180,7 @@ sub is_scalar_type($)
return 1, if ($type eq "char");
return 1, if ($type eq "uint8");
return 1, if ($type eq "uint16");
+ return 1, if ($type eq "NTTIME");
return 1, if ($type eq "hyper");
return 1, if ($type eq "wchar_t");