diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-11-11 01:59:28 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-11-11 01:59:28 +0000 |
commit | be443f914af377fc97d4cfd56f13d95edbcc645f (patch) | |
tree | 6d5af6e49984f5b53492f313445eb5a4ca6c5fbe /source4/build | |
parent | 657dc577b614f388b55bd52a16e8e014c72bf2db (diff) | |
download | samba-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')
-rw-r--r-- | source4/build/pidl/header.pm | 105 | ||||
-rw-r--r-- | source4/build/pidl/idl.gram | 4 | ||||
-rw-r--r-- | source4/build/pidl/parser.pm | 185 | ||||
-rwxr-xr-x | source4/build/pidl/pidl.pl | 2 | ||||
-rw-r--r-- | source4/build/pidl/util.pm | 1 |
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"); |