From a465add90f3291f022104600c6221e8d90287e64 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Nov 2003 13:14:17 +0000 Subject: * changed the way strings are handled in pidl to a much more general interface. We now support an arbitrary set of flags to each parser, and these can be used to control the string types. I have provided some common IDL string types in librpc/idl/idl_types.h which needs to be included in every IDL file. * added IDL for the endpoint mapper. Added a test suite that enumerates all endpoints on the server. (This used to be commit d2665f36a75b482ff82733f72ffac938c2acf87a) --- source4/build/pidl/NOTES.txt | 11 +++++ source4/build/pidl/header.pm | 9 ++-- source4/build/pidl/idl.gram | 5 ++- source4/build/pidl/parser.pm | 105 ++++++++++++++++++++++++++++++++++++------- source4/build/pidl/util.pm | 16 +++---- 5 files changed, 113 insertions(+), 33 deletions(-) (limited to 'source4/build/pidl') diff --git a/source4/build/pidl/NOTES.txt b/source4/build/pidl/NOTES.txt index 4f729ecb95..6210281244 100644 --- a/source4/build/pidl/NOTES.txt +++ b/source4/build/pidl/NOTES.txt @@ -64,6 +64,17 @@ midl.exe would write the above array as the following C header: long s[1]; } Struct1; +pidl takes a different approach, and writes it like this: + + typedef struct { + long abc; + long count; + long foo; + long *s; + } Struct1; + + + VARYING ARRAYS -------------- diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/header.pm index ec8b8451ad..25f0fecd47 100644 --- a/source4/build/pidl/header.pm +++ b/source4/build/pidl/header.pm @@ -49,7 +49,8 @@ sub HeaderElement($) $res .= tabs(); HeaderType($element, $element->{TYPE}, ""); $res .= " "; - if ($element->{POINTERS}) { + if ($element->{POINTERS} && + $element->{TYPE} ne "string") { my($n) = $element->{POINTERS}; for (my($i)=$n; $i > 0; $i--) { $res .= "*"; @@ -125,11 +126,7 @@ sub HeaderType($$$) HeaderUnion($data, $name); return; } - if ($data =~ "unistr" || - $data =~ "ascstr") { - $res .= "const char"; - } elsif ($data =~ "nstring" || - $data =~ "lstring") { + if ($data =~ "string") { $res .= "const char *"; } elsif (util::is_scalar_type($data)) { $res .= "$data"; diff --git a/source4/build/pidl/idl.gram b/source4/build/pidl/idl.gram index d90c2238b4..ac373a5260 100644 --- a/source4/build/pidl/idl.gram +++ b/source4/build/pidl/idl.gram @@ -120,7 +120,8 @@ property: 'unique' | 'noprint' | 'relative' | 'nodiscriminant' - | 'subcontext' + | 'subcontext' '(' constant ')' {{ "$item[1]" => "$item{constant}" }} + | 'flag' '(' anytext ')' {{ "$item[1]" => "$item{anytext}" }} | 'byte_count_pointer' '(' expression ')' {{ "$item[1]" => "$item{expression}" }} | 'size_is' '(' expression ')' {{ "$item[1]" => "$item{expression}" }} | 'length_is' '(' expression ')' {{ "$item[1]" => "$item{expression}" }} @@ -153,7 +154,7 @@ type : text: /[\w\s\..?-]*/ -text2: /[\w\s\*\>\/\..?-]*/ +text2: /[\|\w\s\*\>\/\..?-]*/ anytext: text2 '(' anytext ')' anytext {{ "$item[1]($item[4])$item[6]" }} diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm index 2438ef902a..c57610e9ae 100644 --- a/source4/build/pidl/parser.pm +++ b/source4/build/pidl/parser.pm @@ -42,6 +42,10 @@ sub find_sibling($$) my($name) = shift; my($fn) = $e->{PARENT}; + if ($name =~ /\*(.*)/) { + $name = $1; + } + if ($fn->{TYPE} eq "FUNCTION") { for my $e2 (@{$fn->{DATA}}) { if ($e2->{NAME} eq $name) { @@ -74,17 +78,24 @@ sub find_size_var($$) return $size; } + my $prefix = ""; + + if ($size =~ /\*(.*)/) { + $size = $1; + $prefix = "*"; + } + if ($fn->{TYPE} ne "FUNCTION") { - return "r->$size"; + return $prefix . "r->$size"; } my $e2 = find_sibling($e, $size); if (util::has_property($e2, "in")) { - return "r->in.$size"; + return $prefix . "r->in.$size"; } if (util::has_property($e2, "out")) { - return "r->out.$size"; + return $prefix . "r->out.$size"; } die "invalid variable in $size for element $e->{NAME} in $fn->{NAME}\n"; @@ -103,6 +114,30 @@ sub fn_prefix($) } +################################################################### +# setup any special flags for an element or structure +sub start_flags($) +{ + my $e = shift; + my $flags = util::has_property($e, "flag"); + if (defined $flags) { + pidl "\t{ uint32 _flags_save_$e->{TYPE} = ndr->flags;\n"; + pidl "\tndr->flags |= $flags;\n"; + } +} + +################################################################### +# end any special flags for an element or structure +sub end_flags($) +{ + my $e = shift; + my $flags = util::has_property($e, "flag"); + if (defined $flags) { + pidl "\tndr->flags = _flags_save_$e->{TYPE};\n\t}\n"; + } +} + + ##################################################################### # work out the correct alignment for a structure sub struct_alignment @@ -287,6 +322,8 @@ sub ParseElementPushScalar($$$) my($ndr_flags) = shift; my $cprefix = util::c_push_prefix($e); + start_flags($e); + if (util::has_property($e, "relative")) { pidl "\tNDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, $var_prefix$e->{NAME}, (ndr_push_const_fn_t) ndr_push_$e->{TYPE}));\n"; } elsif (util::is_inline_array($e)) { @@ -304,6 +341,8 @@ sub ParseElementPushScalar($$$) } else { pidl "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n"; } + + end_flags($e); } ##################################################################### @@ -351,8 +390,9 @@ sub ParseElementPullSwitch($$$$) pidl "\t}\n"; } - if (util::has_property($e, "subcontext")) { - pidl "\tNDR_CHECK(ndr_pull_subcontext_union_fn(ndr, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE}));\n"; + my $sub_size = util::has_property($e, "subcontext"); + if (defined $sub_size) { + pidl "\tNDR_CHECK(ndr_pull_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE}));\n"; } else { pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n"; } @@ -378,8 +418,9 @@ sub ParseElementPushSwitch($$$$) pidl "\tNDR_CHECK(ndr_push_$e2->{TYPE}(ndr, $switch_var));\n"; } - if (util::has_property($e, "subcontext")) { - pidl "\tNDR_CHECK(ndr_push_subcontext_union_fn(ndr, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_push_union_fn_t) ndr_pull_$e->{TYPE}));\n"; + my $sub_size = util::has_property($e, "subcontext"); + if (defined $sub_size) { + pidl "\tNDR_CHECK(ndr_push_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_push_union_fn_t) ndr_pull_$e->{TYPE}));\n"; } else { pidl "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n"; } @@ -407,6 +448,9 @@ sub ParseElementPullScalar($$$) my($var_prefix) = shift; my($ndr_flags) = shift; my $cprefix = util::c_pull_prefix($e); + my $sub_size = util::has_property($e, "subcontext"); + + start_flags($e); if (util::has_property($e, "relative")) { pidl "\tNDR_CHECK(ndr_pull_relative(ndr, (const void **)&$var_prefix$e->{NAME}, sizeof(*$var_prefix$e->{NAME}), (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE}));\n"; @@ -425,17 +469,19 @@ sub ParseElementPullScalar($$$) # no scalar component } elsif (my $switch = util::has_property($e, "switch_is")) { ParseElementPullSwitch($e, $var_prefix, $ndr_flags, $switch); - } elsif (util::has_property($e, "subcontext")) { + } elsif (defined $sub_size) { if (util::is_builtin_type($e->{TYPE})) { - pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n"; + pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n"; } else { - pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n"; + pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n"; } } elsif (util::is_builtin_type($e->{TYPE})) { pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n"; } else { pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n"; } + + end_flags($e); } ##################################################################### @@ -451,6 +497,8 @@ sub ParseElementPushBuffer($$$) return; } + start_flags($e); + if (util::need_wire_pointer($e)) { pidl "\tif ($var_prefix$e->{NAME}) {\n"; } @@ -478,6 +526,8 @@ sub ParseElementPushBuffer($$$) if (util::need_wire_pointer($e)) { pidl "\t}\n"; } + + end_flags($e); } ##################################################################### @@ -514,6 +564,7 @@ sub ParseElementPullBuffer($$$) my($var_prefix) = shift; my($ndr_flags) = shift; my $cprefix = util::c_pull_prefix($e); + my $sub_size = util::has_property($e, "subcontext"); if (util::is_pure_scalar($e)) { return; @@ -523,6 +574,8 @@ sub ParseElementPullBuffer($$$) return; } + start_flags($e); + if (util::need_wire_pointer($e)) { pidl "\tif ($var_prefix$e->{NAME}) {\n"; } @@ -537,11 +590,13 @@ sub ParseElementPullBuffer($$$) } else { ParseElementPullSwitch($e, $var_prefix, "NDR_BUFFERS", $switch); } - } elsif (util::has_property($e, "subcontext")) { - if (util::is_builtin_type($e->{TYPE})) { - pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n"; - } else { - pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n"; + } elsif (defined $sub_size) { + if ($e->{POINTERS}) { + if (util::is_builtin_type($e->{TYPE})) { + pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n"; + } else { + pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n"; + } } } elsif (util::is_builtin_type($e->{TYPE})) { pidl "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n"; @@ -554,6 +609,8 @@ sub ParseElementPullBuffer($$$) if (util::need_wire_pointer($e)) { pidl "\t}\n"; } + + end_flags($e); } ##################################################################### @@ -562,11 +619,13 @@ sub ParseStructPush($) { my($struct) = shift; my $conform_e; - + if (! defined $struct->{ELEMENTS}) { return; } + start_flags($struct); + # see if the structure contains a conformant array. If it # does, then it must be the last element of the structure, and # we need to push the conformant length early, as it fits on @@ -600,6 +659,8 @@ sub ParseStructPush($) } pidl "done:\n"; + + end_flags($struct); } ##################################################################### @@ -630,6 +691,8 @@ sub ParseStructPull($) return; } + start_flags($struct); + # see if the structure contains a conformant array. If it # does, then it must be the last element of the structure, and # we need to pull the conformant length early, as it fits on @@ -674,6 +737,8 @@ sub ParseStructPull($) } pidl "done:\n"; + + end_flags($struct); } @@ -683,8 +748,10 @@ sub ParseUnionPush($) { my $e = shift; my $have_default = 0; - pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; + start_flags($e); + + pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; pidl "\tNDR_CHECK(ndr_push_struct_start(ndr));\n"; # my $align = union_alignment($e); @@ -729,6 +796,7 @@ sub ParseUnionPush($) } pidl "\t}\n"; pidl "done:\n"; + end_flags($e); } ##################################################################### @@ -764,6 +832,8 @@ sub ParseUnionPull($) my $e = shift; my $have_default = 0; + start_flags($e); + pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; pidl "\tNDR_CHECK(ndr_pull_struct_start(ndr));\n"; @@ -814,6 +884,7 @@ sub ParseUnionPull($) } pidl "\t}\n"; pidl "done:\n"; + end_flags($e); } ##################################################################### diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm index 566253699d..2f94d80012 100644 --- a/source4/build/pidl/util.pm +++ b/source4/build/pidl/util.pm @@ -149,7 +149,7 @@ sub has_property($$) my($p) = shift; if (!defined $e->{PROPERTIES}) { - return; + return undef; } my($props) = $e->{PROPERTIES}; @@ -168,7 +168,7 @@ sub has_property($$) } } - return undef; + return undef; } @@ -222,8 +222,6 @@ sub is_builtin_type($) my($type) = shift; return 1, if (is_scalar_type($type)); - return 1, if ($type =~ "unistr.*"); - return 1, if ($type =~ "ascstr.*"); return 0; } @@ -304,6 +302,11 @@ sub need_alloc($) sub c_push_prefix($) { my $e = shift; + + if ($e->{TYPE} =~ "string") { + return ""; + } + if (is_scalar_type($e->{TYPE}) && $e->{POINTERS}) { return "*"; @@ -327,10 +330,7 @@ sub c_pull_prefix($) return "&"; } - if ($e->{TYPE} =~ "unistr.*" || - $e->{TYPE} =~ "nstring.*" || - $e->{TYPE} =~ "ascstr.*" || - $e->{TYPE} =~ "lstring.*") { + if ($e->{TYPE} =~ "string") { return "&"; } -- cgit