was Re: PIDL/IDL question(s) now RFC patch

Noel Power nopower at suse.com
Thu Aug 7 08:36:25 MDT 2014

On 09/05/14 12:32, Noel Power wrote:
> Hi,
> the following is a set of structures (simplified) expressed in c ( or
> more likely pseudo-c ) that I wish to marshall. Using PIDL would be
> ideal, I have tried but still I have some difficulty expressing the
> structures so they would be marshalled in the correct way. Note: I don't
> have control of the structures representation and cannot adjust them to
> suit what is possible in idl. Note: I am pretty pidl disabled also so
> any advice welcome
>   struct bounds {
>       uint16 nelems;
>       uint16 lbound;
>   };
>   struct ndim_arraytype {
>       uint16 ndims;
>       uint16 somefield;
>       struct bounds *bounds; /* bounds[ndims] */
>       string values; /* values[elems] - where elems is calculated by
> summing the nelems values from each bound struct stored above */
>   };
> PROBLEM A: Although I can see howto to represent the bounds array above
> (simple inline array) in idl I can't see how to do that for the elements
> array where the number of elements is determined at runtime from the
> contents of the bounds array. Aspirationally I would like to do
> something like
>   typedef [public] struct {
>       uint16 ndims;    
>       uint16 somefield;    
>       struct bounds bounds[ndims]
>       string values[custom_fn(bounds, ndims)];
>   } ndim_arraytype;
> and indeed the generated code looks like it would do what I require,
> however the custom_fn is obviously undefined and therefore wont build. I
> can I guess create a new source & header file that contains the custom
> function I need and build it with the generated ndr_xyz files, but is
> this the correct thing to do?, am I depending on some unintentional
> behaviour by using 'variant elements[custom_fn(bounds, ndims)];'? or
> indeed is there a better way to do this ?
presuming that using an expression for the array size is something that
can be depended on (as being legal and supported) the following patch
allows for a custom '#include' (or set of includes) to be injected into
the generated ndr parser code to allow the prototype to be defined
-------------- next part --------------
>From 3ccb9a92f1ff55274e0c95d3f006432d1bdf2464 Mon Sep 17 00:00:00 2001
From: Noel Power <noel.power at suse.com>
Date: Wed, 6 Aug 2014 13:15:19 +0100
Subject: [PATCH] allow custom include be injected into ndr file

Signed-off-by: Noel Power <noel.power at suse.com>
 pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 11 +++++++++--
 pidl/pidl                                | 11 +++++++++--
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index 3deab2e..912fea6 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -2982,15 +2982,22 @@ sub GenerateIncludes($)
 # parse a parsed IDL structure back into an IDL file
-sub Parse($$$$)
+sub Parse($$$$$)
-	my($self, $ndr,$gen_header,$ndr_header) = @_;
+	my($self, $ndr,$gen_header,$ndr_header,$includes) = @_;
 	$self->pidl_hdr("/* header auto-generated by pidl */");
 	$self->pidl_hdr(choose_header("librpc/ndr/libndr.h", "ndr.h"));
 	$self->pidl_hdr("#include \"$gen_header\"") if ($gen_header);
+	if (defined($includes)) {
+		my @include_files = split(',', $includes);
+		foreach my $include (@include_files) {
+			$self->pidl_hdr("#include \"$include\"");
+		}
+		$self->pidl_hdr("");
+	}
 	$self->pidl("/* parser auto-generated by pidl */");
diff --git a/pidl/pidl b/pidl/pidl
index c65092e..ffd2c40 100755
--- a/pidl/pidl
+++ b/pidl/pidl
@@ -17,7 +17,7 @@ pidl - An IDL compiler written in Perl
 pidl --help
-pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--python[=OUTPUT]] [--ndr-parser[=OUTPUT]] [--client] [--server] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=OUTPUT]] [--typelib=[OUTPUT]] [<idlfile>.idl]...
+pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--python[=OUTPUT]] [--ndr-parser[=OUTPUT]] [--ndr-parser-includes[=INCLUDEFILES]] [--client] [--server] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=OUTPUT]] [--typelib=[OUTPUT]] [<idlfile>.idl]...
@@ -86,6 +86,10 @@ Generate a C file and C header containing NDR parsers. The filename for
 the parser defaults to ndr_OUTNAME.c. The header filename will be the 
 parser filename with the extension changed from .c to .h.
+=item I<--ndr-parser-includes>
+Injects include directives containing the INCLUDEFILES (where INCLUDEFILES is a comma seperated list of files to include) into ndr_OUTNAME.h.
 =item I<--tdr-parser>
 Generate a C file and C header containing TDR parsers. The filename for 
@@ -475,6 +479,7 @@ my($opt_client);
@@ -517,6 +522,7 @@ Debugging:
 Samba 4 output:
  --header[=OUTFILE]      create generic header file [BASENAME.h]
  --ndr-parser[=OUTFILE]  create a C NDR parser [ndr_BASENAME.c]
+ --ndr-parser-includes[=INCLUDEFILES]  injects include directives for INCLUDEFILES into [ndr_BASENAME.h]
  --client[=OUTFILE]      create a C NDR client [ndr_BASENAME_c.c]
  --tdr-parser[=OUTFILE]  create a C TDR parser [tdr_BASENAME.c]
  --python[=OUTFILE]      create python wrapper file [py_BASENAME.c]
@@ -561,6 +567,7 @@ my $result = GetOptions (
 	    'tdr-parser:s' => \$opt_tdr_parser,
 	    'template' => \$opt_template,
 	    'ndr-parser:s' => \$opt_ndr_parser,
+	    'ndr-parser-includes:s' => \$opt_ndr_parser_includes,
 	    'client:s' => \$opt_client,
 	    'ws-parser:s' => \$opt_ws_parser,
 		'python' => \$opt_python,
@@ -725,7 +732,7 @@ sub process_file($)
 		my $parser_fname = ($opt_ndr_parser or "$outputdir/ndr_$basename.c");
 		require Parse::Pidl::Samba4::NDR::Parser;
 		my $generator = new Parse::Pidl::Samba4::NDR::Parser();
-		my ($header,$parser) = $generator->Parse($ndr, $gen_header, $h_filename);
+		my ($header,$parser) = $generator->Parse($ndr, $gen_header, $h_filename,$opt_ndr_parser_includes);
 		FileSave($parser_fname, $parser);
 		FileSave($h_filename, $header);

More information about the samba-technical mailing list