diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-11-08 11:19:39 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-11-08 11:19:39 +0000 |
commit | 4e4a63d5185d1567c115e7cbf15022b0fbcbc870 (patch) | |
tree | b16be9157d0b5c68ec2cbe7daa8b9f1ecef7dc5f /source4/build | |
parent | 3043b766c86d2d814e617d33c48316addff762b5 (diff) | |
download | samba-4e4a63d5185d1567c115e7cbf15022b0fbcbc870.tar.gz samba-4e4a63d5185d1567c115e7cbf15022b0fbcbc870.tar.bz2 samba-4e4a63d5185d1567c115e7cbf15022b0fbcbc870.zip |
- generate both the pull and push side
- fixed lots of bugs
(This used to be commit 96e269fefedd1e8541eae7ad5e3fb98df978c81b)
Diffstat (limited to 'source4/build')
-rw-r--r-- | source4/build/pidl/idl.gram | 1 | ||||
-rw-r--r-- | source4/build/pidl/parser.pm | 354 | ||||
-rw-r--r-- | source4/build/pidl/util.pm | 43 |
3 files changed, 300 insertions, 98 deletions
diff --git a/source4/build/pidl/idl.gram b/source4/build/pidl/idl.gram index b700cb378e..4ebd8fabe1 100644 --- a/source4/build/pidl/idl.gram +++ b/source4/build/pidl/idl.gram @@ -93,7 +93,6 @@ property_list: '[' <commit> property(s /,/) ']' | <error?> property: 'unique' - | 'in,out' | 'in' | 'out' | 'ref' diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm index 9ba5b4b66c..0029aef603 100644 --- a/source4/build/pidl/parser.pm +++ b/source4/build/pidl/parser.pm @@ -27,60 +27,147 @@ sub ParseProperties($) } ##################################################################### -# parse an array - called in buffers context -sub ParseArray($) +# parse an array - push side +sub ParseArrayPush($) { - die "arrays not done"; + my $e = shift; + my $size = util::has_property($e->{PROPERTIES}, "size_is"); + if (util::is_scalar_type($e->{TYPE})) { + $res .= "\t\tNDR_CHECK(ndr_push_array_$e->{TYPE}(ndr, r->$e->{NAME}, r->$size));\n:"; + } else { + $res .= "\t\tNDR_CHECK(ndr_push_array(ndr, ndr_flags, r->$e->{NAME}, sizeof(r->$e->{NAME}\[0]), r->$size, (ndr_push_flags_fn_t)ndr_push_$e->{TYPE}));\n"; + } +} + +##################################################################### +# parse an array - pull side +sub ParseArrayPull($) +{ + my $e = shift; + my $size = util::has_property($e->{PROPERTIES}, "size_is"); + if (util::is_scalar_type($e->{TYPE})) { + $res .= "\t\tNDR_CHECK(ndr_pull_array_$e->{TYPE}(ndr, &r->$e->{NAME}, r->$size));\n:"; + } else { + $res .= "\t\tNDR_CHECK(ndr_pull_array(ndr, ndr_flags, (void **)&r->$e->{NAME}, sizeof(r->$e->{NAME}\[0]), r->$size, (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE}));\n"; + } } ##################################################################### # parse scalars in a structure element -sub ParseElementPushScalars($$) +sub ParseElementPushScalar($$$) +{ + my($e) = shift; + my($var_prefix) = shift; + my($ndr_flags) = shift; + + if (defined $e->{VALUE}) { + $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $e->{VALUE}));\n"; + } elsif ($e->{POINTERS} && + !util::has_property($e->{PROPERTIES}, "ref")) { + $res .= "\tNDR_CHECK(ndr_push_ptr(ndr, $var_prefix$e->{NAME}));\n"; + } elsif (util::is_builtin_type($e->{TYPE})) { + $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $var_prefix$e->{NAME}));\n"; + } else { + $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}));\n"; + } +} + +##################################################################### +# parse scalars in a structure element - pull size +sub ParseElementPullScalar($$) { - my($elt) = shift; + my($e) = shift; my($var_prefix) = shift; - if (defined $elt->{VALUE}) { - $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, $elt->{VALUE}));\n"; - } elsif ($elt->{POINTERS} && - !util::has_property($elt->{PROPERTIES}, "ref")) { - $res .= "\tNDR_CHECK(ndr_push_ptr(ndr, $var_prefix$elt->{NAME}));\n"; + if (defined $e->{VALUE}) { + $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $e->{VALUE}));\n"; + } elsif ($e->{POINTERS} && + !util::has_property($e->{PROPERTIES}, "ref")) { + $res .= "\tNDR_CHECK(ndr_pull_uint32(ndr, &_ptr_$e->{NAME}));\n"; + $res .= "\tif (_ptr_$e->{NAME}) {\n"; + $res .= "\t\tNDR_ALLOC(ndr, $var_prefix$e->{NAME});\n"; + $res .= "\t} else {\n"; + $res .= "\t\t$var_prefix$e->{NAME} = NULL;\n"; + $res .= "\t}\n"; } else { - $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, $var_prefix$elt->{NAME}));\n"; + $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, &$var_prefix$e->{NAME}));\n"; } } ##################################################################### # parse buffers in a structure element -sub ParseElementPushBuffers($$) +sub ParseElementPushBuffer($$) { - my($elt) = shift; + my($e) = shift; my($var_prefix) = shift; - if (util::has_property($elt->{PROPERTIES}, "ref")) { + if (util::has_property($e->{PROPERTIES}, "ref")) { return; } - if (util::is_scalar_type($elt->{TYPE}) && !$elt->{POINTERS}) { + if (util::is_scalar_type($e->{TYPE}) && !$e->{POINTERS}) { return; } - if ($elt->{POINTERS}) { - $res .= "\tif ($var_prefix$elt->{NAME}) {\n\t"; + if ($e->{POINTERS}) { + $res .= "\tif ($var_prefix$e->{NAME}) {\n"; } - if (util::has_property($elt->{PROPERTIES}, "size_is")) { - ParseArray($elt); + if (util::has_property($e->{PROPERTIES}, "size_is")) { + ParseArrayPush($e); } else { - if (util::is_scalar_type($elt->{TYPE})) { - $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, *$var_prefix$elt->{NAME}));\n"; + if (util::is_scalar_type($e->{TYPE})) { + $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, *$var_prefix$e->{NAME}));\n"; + } elsif (util::has_property($e->{PROPERTIES}, "ref") || !$e->{POINTERS}) { + $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, ndr_flags, *$var_prefix$e->{NAME}));\n"; + } elsif (util::is_builtin_type($e->{TYPE})) { + $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $var_prefix$e->{NAME}));\n"; } else { - $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, $var_prefix$elt->{NAME}));\n"; + $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, ndr_flags, $var_prefix$e->{NAME}));\n"; } } - if ($elt->{POINTERS}) { + if ($e->{POINTERS}) { + $res .= "\t}\n"; + } +} + + +##################################################################### +# parse buffers in a structure element - pull side +sub ParseElementPullBuffer($$) +{ + my($e) = shift; + my($var_prefix) = shift; + + if (util::has_property($e->{PROPERTIES}, "ref")) { + return; + } + + if (util::is_scalar_type($e->{TYPE}) && !$e->{POINTERS}) { + return; + } + + if ($e->{POINTERS}) { + $res .= "\tif ($var_prefix$e->{NAME}) {\n"; + } + + if (util::has_property($e->{PROPERTIES}, "size_is")) { + ParseArrayPull($e); + } else { + if (util::has_property($e->{PROPERTIES}, "ref") || + !$e->{POINTERS} || + $e->{TYPE} =~ "unistr") { + $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, \&$var_prefix$e->{NAME}));\n"; + } elsif (util::is_builtin_type($e->{TYPE})) { + $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $var_prefix$e->{NAME}));\n"; + } else { + $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, ndr_flags, $var_prefix$e->{NAME}));\n"; + } + } + + if ($e->{POINTERS}) { $res .= "\t}\n"; } } @@ -105,29 +192,95 @@ sub ParseStructPush($) } if (defined $struct_len) { - $res .= "\tstruct ndr_push_save len_save1, len_save2, len_save3;\n"; - $res .= "\tndr_push_save(ndr, &len_save1);\n"; + $res .= "\tstruct ndr_push_save _save1, _save2, _save3;\n"; + $res .= "\tndr_push_save(ndr, &_save1);\n"; } + $res .= "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; + foreach my $e (@{$struct->{ELEMENTS}}) { - if ($e == $struct_len) { + if (defined($struct_len) && $e == $struct_len) { $res .= "\tNDR_CHECK(ndr_push_align_$e->{TYPE}(ndr));\n"; - $res .= "\tndr_push_save(ndr, &len_save2);\n"; + $res .= "\tndr_push_save(ndr, &_save2);\n"; + } + ParseElementPushScalar($e, "r->", "NDR_SCALARS"); + } + + $res .= "buffers:\n"; + $res .= "\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n"; + foreach my $e (@{$struct->{ELEMENTS}}) { + ParseElementPushBuffer($e, "r->"); + } + + if (defined $struct_len) { + $res .= "\tndr_push_save(ndr, &_save3);\n"; + $res .= "\tndr_push_restore(ndr, &_save2);\n"; + $struct_len->{VALUE} = "_save3.offset - _save1.offset"; + ParseElementPushScalar($struct_len, "r->", "NDR_SCALARS"); + $res .= "\tndr_push_restore(ndr, &_save3);\n"; + } + + $res .= "done:\n"; +} + +##################################################################### +# parse a struct - pull side +sub ParseStructPull($) +{ + my($struct) = shift; + my($struct_len); + + if (! defined $struct->{ELEMENTS}) { + return; + } + + # declare any internal pointers we need + foreach my $e (@{$struct->{ELEMENTS}}) { + if ($e->{POINTERS} && + !util::has_property($e->{PROPERTIES}, "ref")) { + $res .= "\tuint32 _ptr_$e->{NAME};\n"; + } + } + + + # see if we have a structure length. If we do then we need to advance + # the ndr_pull offset to that length past the front of the structure + # when we have finished with the structure + # we also need to make sure that we limit the size of our parsing + # of this structure to the given size + foreach my $e (@{$struct->{ELEMENTS}}) { + if (util::has_property($e->{PROPERTIES}, "struct_len")) { + $struct_len = $e; + $e->{VALUE} = "&_size"; } - ParseElementPushScalars($e, "r->"); } + if (defined $struct_len) { + $res .= "\tuint32 _size;\n"; + $res .= "\tstruct ndr_pull_save _save;\n"; + $res .= "\tndr_pull_save(ndr, &_save);\n"; + } + + $res .= "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPushBuffers($e, "r->"); + ParseElementPullScalar($e, "r->"); + if (defined($struct_len) && $e == $struct_len) { + $res .= "\tNDR_CHECK(ndr_pull_limit_size(ndr, _size, 4));\n"; + } + } + + $res .= "buffers:\n"; + $res .= "\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n"; + foreach my $e (@{$struct->{ELEMENTS}}) { + ParseElementPullBuffer($e, "r->"); } if (defined $struct_len) { - $res .= "\tndr_push_save(ndr, &len_save3);\n"; - $res .= "\tndr_push_restore(ndr, &len_save2);\n"; - $struct_len->{VALUE} = "len_save3.offset - len_save1.offset"; - ParseElementPushScalars($struct_len, "r->"); - $res .= "\tndr_push_restore(ndr, &len_save3);\n"; + $res .= "\tndr_pull_restore(ndr, &_save);\n"; + $res .= "\tNDR_CHECK(ndr_pull_advance(ndr, _size));\n"; } + + $res .= "done:\n"; } @@ -139,70 +292,94 @@ sub ParseUnionElementPush($) } ##################################################################### -# parse a union +# parse a union - push side sub ParseUnionPush($) { die "unions not done"; } ##################################################################### +# parse a union - pull side +sub ParseUnionPull($) +{ + die "unions not done"; +} + +##################################################################### # parse a type sub ParseTypePush($) { - my($data) = shift; + my($data) = shift; - if (ref($data) eq "HASH") { - ($data->{TYPE} eq "STRUCT") && - ParseStructPush($data); - ($data->{TYPE} eq "UNION") && + if (ref($data) eq "HASH") { + ($data->{TYPE} eq "STRUCT") && + ParseStructPush($data); + ($data->{TYPE} eq "UNION") && ParseUnionPush($data); - } else { - $res .= "$data"; - } + } } ##################################################################### -# parse a typedef -sub ParseTypedefPush($) +# parse a type +sub ParseTypePull($) { - my($typedef) = shift; + my($data) = shift; - $res .= "static NTSTATUS ndr_push_$typedef->{NAME}(struct ndr_push *ndr, struct $typedef->{NAME} *r)"; - $res .= "\n{\n"; - ParseTypePush($typedef->{DATA}); - $res .= "\treturn NT_STATUS_OK;\n"; - $res .= "}\n\n"; + if (ref($data) eq "HASH") { + ($data->{TYPE} eq "STRUCT") && + ParseStructPull($data); + ($data->{TYPE} eq "UNION") && + ParseUnionPull($data); + } } ##################################################################### -# parse a function -sub ParseFunctionPushArg($$) -{ - my($arg) = shift; - my($io) = shift; # "in" or "out" +# parse a typedef - push side +sub ParseTypedefPush($) +{ + my($e) = shift; - if (!util::has_property($arg->{PROPERTIES}, $io)) { - return; - } + $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"; +} - ParseElementPushScalars($arg, "r->in."); - ParseElementPushBuffers($arg, "r->in."); + +##################################################################### +# parse a typedef - pull side +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"; } - + + + + ##################################################################### # parse a function sub ParseFunctionPush($) { - my($function) = shift; + my($function) = shift; - # Input function - $res .= "NTSTATUS ndr_push_$function->{NAME}(struct ndr_push *ndr, struct $function->{NAME} *r)\n{\n"; + # Input function + $res .= "NTSTATUS ndr_push_$function->{NAME}(struct ndr_push *ndr, struct $function->{NAME} *r)\n{\n"; - foreach my $arg (@{$function->{DATA}}) { - ParseFunctionPushArg($arg, "in"); - } + foreach my $arg (@{$function->{DATA}}) { + if (util::has_property($arg->{PROPERTIES}, "in")) { + ParseElementPushScalar($arg, "r->in.", "NDR_SCALARS|NDR_BUFFERS"); + ParseElementPushBuffer($arg, "r->in."); + } + } - $res .= "\n\treturn NT_STATUS_OK;\n}\n\n"; + $res .= "\n\treturn NT_STATUS_OK;\n}\n\n"; } ##################################################################### @@ -212,6 +389,15 @@ sub ParseFunctionPull($) } ##################################################################### +# parse a typedef +sub ParseTypedef($) +{ + my($e) = shift; + ParseTypedefPush($e); + ParseTypedefPull($e); +} + +##################################################################### # parse a function sub ParseFunction($) { @@ -224,14 +410,14 @@ sub ParseFunction($) # parse the interface definitions sub ParseInterface($) { - my($interface) = shift; - my($data) = $interface->{DATA}; - foreach my $d (@{$data}) { - ($d->{TYPE} eq "TYPEDEF") && - ParseTypedefPush($d); - ($d->{TYPE} eq "FUNCTION") && - ParseFunction($d); - } + my($interface) = shift; + my($data) = $interface->{DATA}; + foreach my $d (@{$data}) { + ($d->{TYPE} eq "TYPEDEF") && + ParseTypedef($d); + ($d->{TYPE} eq "FUNCTION") && + ParseFunction($d); + } } @@ -239,13 +425,13 @@ sub ParseInterface($) # parse a parsed IDL structure back into an IDL file sub Parse($) { - my($idl) = shift; - $res = "/* parser auto-generated by pidl */\n\n"; - foreach my $x (@{$idl}) { - ($x->{TYPE} eq "INTERFACE") && - ParseInterface($x); - } - return $res; + my($idl) = shift; + $res = "/* parser auto-generated by pidl */\n\n"; + foreach my $x (@{$idl}) { + ($x->{TYPE} eq "INTERFACE") && + ParseInterface($x); + } + return $res; } 1; diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm index 53e391eb42..1c8ad720bb 100644 --- a/source4/build/pidl/util.pm +++ b/source4/build/pidl/util.pm @@ -147,21 +147,24 @@ sub LoadStructure($) # see if a pidl property list contains a give property sub has_property($$) { - my($props) = shift; - my($p) = shift; - - foreach my $d (@{$props}) { - if (ref($d) ne "HASH") { - return 1, if ($d eq $p); - return 1, if ($d eq "in,out" && ($p eq "in" || $p eq "out")); - } else { - foreach my $k (keys %{$d}) { - return $d->{$k}, if ($k eq $p); - } + my($props) = shift; + my($p) = shift; + + foreach my $d (@{$props}) { + if (ref($d) ne "HASH") { + if ($d eq $p) { + return 1; + } + } else { + foreach my $k (keys %{$d}) { + if ($k eq $p) { + return $d->{$k}; + } + } + } } - } - return 0; + return undef; } @@ -181,6 +184,20 @@ sub is_scalar_type($) return 0; } +sub is_builtin_type($) +{ + my($type) = shift; + + return 1, if (is_scalar_type($type)); + return 1, if ($type eq "unistr"); + return 1, if ($type eq "security_descriptor"); + return 1, if ($type eq "dom_sid"); + return 1, if ($type eq "dom_sid2"); + return 1, if ($type eq "policy_handle"); + + return 0; +} + 1; |