From fa3db33a5441ed31f9d8c19dc6984d160b86e4da Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Nov 2003 12:29:23 +0000 Subject: updated pidl to auto-generate the ndr_push_*() functions for the Samba4 rpc framework not complete, but sufficient for a number of lsa functions (This used to be commit 42cd6904f51bac1ff92f0aea0deffb11864dfac2) --- source4/build/pidl/parser.pm | 190 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 161 insertions(+), 29 deletions(-) (limited to 'source4/build/pidl/parser.pm') diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm index 03bc5f3aff..695d943ee2 100644 --- a/source4/build/pidl/parser.pm +++ b/source4/build/pidl/parser.pm @@ -1,5 +1,6 @@ ################################################### -# C parser generator for IDL structures +# Ethereal parser generator for IDL structures +# Copyright tpot@samba.org 2001 # Copyright tridge@samba.org 2000 # released under the GNU GPL @@ -26,35 +27,120 @@ sub ParseProperties($) } ##################################################################### -# parse a structure element -sub ParseElement($) +# parse an array - called in buffers context +sub ParseArray($) { - my($element) = shift; - (defined $element->{PROPERTIES}) && ParseProperties($element->{PROPERTIES}); - ParseType($element->{TYPE}); - $res .= " "; - if ($element->{POINTERS}) { - for (my($i)=0; $i < $element->{POINTERS}; $i++) { - $res .= "*"; - } + my($elt) = shift; + + $res .= "\tfor (i = 0; i < count; i++) {\n"; + if (util::is_scalar_type($elt)) { + $res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, NULL, \"$elt->{NAME});\n"; + $res .= "\t}\n\n"; + } else { + $res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, \"PARSE_SCALARS\", \"$elt->{NAME}\");\n"; + $res .= "\t}\n\n"; + + $res .= "\tfor (i = 0; i < count; i++) {\n"; + $res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, \"PARSE_BUFFERS\", \"$elt->{NAME}\");\n"; + $res .= "\t}\n\n"; } - $res .= "$element->{NAME}"; - (defined $element->{ARRAY_LEN}) && ($res .= "[$element->{ARRAY_LEN}]"); +} + + +##################################################################### +# parse scalars in a structure element +sub ParseElementScalars($$) +{ + my($elt) = 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"; + } else { + $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, $var_prefix$elt->{NAME}));\n"; + } +} + +##################################################################### +# parse buffers in a structure element +sub ParseElementBuffers($$) +{ + my($elt) = shift; + my($var_prefix) = shift; + + if (util::has_property($elt->{PROPERTIES}, "ref")) { + return; + } + + if (util::is_scalar_type($elt->{TYPE}) && !$elt->{POINTERS}) { + return; + } + + if ($elt->{POINTERS}) { + $res .= "\tif ($var_prefix$elt->{NAME}) {\n\t"; + } + + if (util::has_property($elt->{PROPERTIES}, "size_is")) { + ParseArray($elt); + } else { + if (util::is_scalar_type($elt->{TYPE})) { + $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, *$var_prefix$elt->{NAME}));\n"; + } else { + $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, $var_prefix$elt->{NAME}));\n"; + } + } + + if ($elt->{POINTERS}) { + $res .= "\t}\n"; + } } ##################################################################### # parse a struct sub ParseStruct($) { - my($struct) = shift; - $res .= "struct {\n"; - if (defined $struct->{ELEMENTS}) { + my($struct) = shift; + my($struct_len); + + if (! defined $struct->{ELEMENTS}) { + return; + } + + # see if we have a structure length foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElement($e); - $res .= ";\n"; + if (util::has_property($e->{PROPERTIES}, "struct_len")) { + $struct_len = $e; + $e->{VALUE} = "0"; + } + } + + if (defined $struct_len) { + $res .= "\tstruct ndr_push_save len_save1, len_save2, len_save3;\n"; + $res .= "\tndr_push_save(ndr, &len_save1);\n"; + } + + foreach my $e (@{$struct->{ELEMENTS}}) { + if ($e == $struct_len) { + $res .= "\tNDR_CHECK(ndr_push_align_$e->{TYPE}(ndr));\n"; + $res .= "\tndr_push_save(ndr, &len_save2);\n"; + } + ParseElementScalars($e, "r->"); + } + + foreach my $e (@{$struct->{ELEMENTS}}) { + ParseElementBuffers($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"; + ParseElementScalars($struct_len, "r->"); + $res .= "\tndr_push_restore(ndr, &len_save3);\n"; } - } - $res .= "}"; } @@ -63,9 +149,10 @@ sub ParseStruct($) sub ParseUnionElement($) { my($element) = shift; - $res .= "[case($element->{CASE})] "; - ParseElement($element->{DATA}); - $res .= ";\n"; + + $res .= "\tcase $element->{DATA}->{NAME}: \n"; + $res .= "\t\toffset = prs_$element->{DATA}->{TYPE}(tvb, offset, pinfo, tree, \"$element->{DATA}->{NAME}\");\n\t\tbreak;\n"; + } ##################################################################### @@ -73,12 +160,15 @@ sub ParseUnionElement($) sub ParseUnion($) { my($union) = shift; + + $res .= "\tswitch (level) {\n"; + (defined $union->{PROPERTIES}) && ParseProperties($union->{PROPERTIES}); - $res .= "union {\n"; foreach my $e (@{$union->{DATA}}) { ParseUnionElement($e); } - $res .= "}"; + + $res .= "\t}\n"; } ##################################################################### @@ -86,6 +176,7 @@ sub ParseUnion($) sub ParseType($) { my($data) = shift; + if (ref($data) eq "HASH") { ($data->{TYPE} eq "STRUCT") && ParseStruct($data); @@ -101,17 +192,58 @@ sub ParseType($) sub ParseTypedef($) { my($typedef) = shift; - $res .= "typedef "; + + $res .= "static NTSTATUS ndr_push_$typedef->{NAME}(struct ndr_push *ndr, struct $typedef->{NAME} *r)"; + $res .= "\n{\n"; ParseType($typedef->{DATA}); - $res .= " $typedef->{NAME};\n\n"; + $res .= "\treturn NT_STATUS_OK;\n"; + $res .= "}\n\n"; } ##################################################################### # parse a function -sub ParseFunction($) +sub ParseFunctionArg($$) +{ + my($arg) = shift; + my($io) = shift; # "in" or "out" + + if (!util::has_property($arg->{PROPERTIES}, $io)) { + return; + } + + ParseElementScalars($arg, "r->in."); + ParseElementBuffers($arg, "r->in."); +} + +##################################################################### +# parse a function +sub ParseFunctionPush($) { my($function) = shift; - $res .= "/* ignoring function $function->{NAME} */\n"; + + # Input function + $res .= "NTSTATUS ndr_push_$function->{NAME}(struct ndr_push *ndr, struct $function->{NAME} *r)\n{\n"; + + foreach my $arg (@{$function->{DATA}}) { + ParseFunctionArg($arg, "in"); + } + + $res .= "\n\treturn NT_STATUS_OK;\n}\n\n"; +} + +##################################################################### +# parse a function +sub ParseFunctionPull($) +{ +} + +##################################################################### +# parse a function +sub ParseFunction($) +{ + my $i = shift; + ParseFunctionPush($i); + ParseFunctionPull($i); } ##################################################################### -- cgit