-#!/usr/bin/perl -w
+#!/usr/bin/env perl
###################################################
# package to parse IDL files and generate code for
pidl --help
-pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--python[=OUTPUT]] [--swig[=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]] [--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]...
=head1 DESCRIPTION
-pidl is an IDL compiler written in Perl that aims to be somewhat
-compatible with the midl compiler. IDL is short for
+pidl is an IDL compiler written in Perl that aims to be somewhat
+compatible with the midl compiler. IDL is short for
"Interface Definition Language".
-pidl can generate stubs for DCE/RPC server code, DCE/RPC
+pidl can generate stubs for DCE/RPC server code, DCE/RPC
client code and Wireshark dissectors for DCE/RPC traffic.
-IDL compilers like pidl take a description
-of an interface as their input and use it to generate C
-(though support for other languages may be added later) code that
-can use these interfaces, pretty print data sent
-using these interfaces, or even generate Wireshark
-dissectors that can parse data sent over the
-wire by these interfaces.
+IDL compilers like pidl take a description
+of an interface as their input and use it to generate C
+(though support for other languages may be added later) code that
+can use these interfaces, pretty print data sent
+using these interfaces, or even generate Wireshark
+dissectors that can parse data sent over the
+wire by these interfaces.
-pidl takes IDL files in the same format as is used by midl,
+pidl takes IDL files in the same format as is used by midl,
converts it to a .pidl file (which contains pidl's internal representation of the interface) and can then generate whatever output you need.
-.pidl files should be used for debugging purposes only. Write your
+.pidl files should be used for debugging purposes only. Write your
interface definitions in .idl format.
-The goal of pidl is to implement a IDL compiler that can be used
-while developing the RPC subsystem in Samba (for
+The goal of pidl is to implement a IDL compiler that can be used
+while developing the RPC subsystem in Samba (for
both marshalling/unmarshalling and debugging purposes).
=head1 OPTIONS
=item I<--version>
Show pidl version
-
+
=item I<--outputdir OUTNAME>
-Write output files to the specified directory. Defaults to the current
+Write output files to the specified directory. Defaults to the current
directory.
=item I<--includedir DIR>
-Add DIR to the search path used by the preprocessor. This option can be
+Add DIR to the search path used by the preprocessor. This option can be
specified multiple times.
-
+
=item I<--parse-idl-tree>
-Read internal tree structure from input files rather
+Read internal tree structure from input files rather
than assuming they contain IDL.
=item I<--dump-idl>
=item I<--ndr-parser>
-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
+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<--tdr-parser>
-Generate a C file and C header containing TDR parsers. The filename for
-the parser defaults to tdr_OUTNAME.c. The header filename will be the
+Generate a C file and C header containing TDR parsers. The filename for
+the parser defaults to tdr_OUTNAME.c. The header filename will be the
parser filename with the extension changed from .c to .h.
=item I<--typelib>
=item I<--server>
-Generate boilerplate for the RPC server that implements
+Generate boilerplate for the RPC server that implements
the interface. Filename defaults to ndr_OUTNAME_s.c.
=item I<--template>
-Generate stubs for a RPC server that implements the interface. Output will
+Generate stubs for a RPC server that implements the interface. Output will
be written to stdout.
=item I<--ws-parser>
Generate an Wireshark dissector (in C) and header file. The dissector filename
-defaults to packet-dcerpc-OUTNAME.c while the header filename defaults to
+defaults to packet-dcerpc-OUTNAME.c while the header filename defaults to
packet-dcerpc-OUTNAME.h.
-
-Pidl will read additional data from an Wireshark conformance file if present.
-Such a file should have the same location as the IDL file but with the
+
+Pidl will read additional data from an Wireshark conformance file if present.
+Such a file should have the same location as the IDL file but with the
extension I<cnf> rather than I<idl>. See L<Parse::Pidl::Wireshark::Conformance>
for details on the format of this file.
=item I<--diff>
-Parse an IDL file, generate a new IDL file based on the internal data
-structures and see if there are any differences with the original IDL file.
+Parse an IDL file, generate a new IDL file based on the internal data
+structures and see if there are any differences with the original IDL file.
Useful for debugging pidl.
=item I<--dump-idl-tree>
-Tell pidl to dump the internal tree representation of an IDL
+Tell pidl to dump the internal tree representation of an IDL
file the to disk. Useful for debugging pidl.
=item I<--dump-ndr-tree>
-Tell pidl to dump the internal NDR information tree it generated
+Tell pidl to dump the internal NDR information tree it generated
from the IDL file to disk. Useful for debugging pidl.
=item I<--samba3-ndr-client>
-Generate client calls for Samba3, to be placed in rpc_client/. Instead of
-calling out to the code in Samba3's rpc_parse/, this will call out to
+Generate client calls for Samba3, to be placed in rpc_client/. Instead of
+calling out to the code in Samba3's rpc_parse/, this will call out to
Samba4's NDR code instead.
=item I<--samba3-ndr-server>
-Generate server calls for Samba3, to be placed in rpc_server/. Instead of
-calling out to the code in Samba3's rpc_parse/, this will call out to
+Generate server calls for Samba3, to be placed in rpc_server/. Instead of
+calling out to the code in Samba3's rpc_parse/, this will call out to
Samba4's NDR code instead.
=back
IDL files are always preprocessed using the C preprocessor.
-Pretty much everything in an interface (the interface itself, functions,
-parameters) can have attributes (or properties whatever name you give them).
-Attributes always prepend the element they apply to and are surrounded
-by square brackets ([]). Multiple attributes are separated by comma's;
-arguments to attributes are specified between parentheses.
+Pretty much everything in an interface (the interface itself, functions,
+parameters) can have attributes (or properties whatever name you give them).
+Attributes always prepend the element they apply to and are surrounded
+by square brackets ([]). Multiple attributes are separated by comma's;
+arguments to attributes are specified between parentheses.
-See the section COMPATIBILITY for the list of attributes that
+See the section COMPATIBILITY for the list of attributes that
pidl supports.
C-style comments can be used.
-
+
=head2 CONFORMANT ARRAYS
A conformant array is one with that ends in [*] or []. The strange
-things about conformant arrays are that they can only appear as the last
-element of a structure (unless there is a pointer to the conformant array,
-of course) and the array size appears before the structure itself on the wire.
+things about conformant arrays are that they can only appear as the last
+element of a structure (unless there is a pointer to the conformant array,
+of course) and the array size appears before the structure itself on the wire.
So, in this example:
typedef struct {
long abc;
- long count;
+ long count;
long foo;
[size_is(count)] long s[*];
} Struct1;
typedef struct {
long abc;
- long count;
+ long count;
long foo;
long s[1];
} Struct1;
typedef struct {
long abc;
- long count;
+ long count;
long foo;
long *s;
} Struct1;
typedef struct {
long abc;
- long count;
+ long count;
long foo;
[size_is(count)] long *s;
} Struct1;
[foo] [count] [bar] [s...]
Fixed arrays are an extension added to support some of the strange
-embedded structures in security descriptors and spoolss.
+embedded structures in security descriptors and spoolss.
-This section is by no means complete. See the OpenGroup and MSDN
+This section is by no means complete. See the OpenGroup and MSDN
documentation for additional information.
=head1 COMPATIBILITY WITH MIDL
=head2 Missing features in pidl
-The following MIDL features are not (yet) implemented in pidl
+The following MIDL features are not (yet) implemented in pidl
or are implemented with an incompatible interface:
=over
Asynchronous communication
-=item *
+=item *
Typelibs (.tlb files)
=head2 Supported attributes and statements
-in, out, ref, length_is, switch_is, size_is, uuid, case, default, string,
-unique, ptr, pointer_default, v1_enum, object, helpstring, range, local,
-call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as,
+in, out, ref, length_is, switch_is, size_is, uuid, case, default, string,
+unique, ptr, pointer_default, v1_enum, object, helpstring, range, local,
+call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as,
transmit_as, import, include, cpp_quote.
=head2 PIDL Specific properties
you to declare types that can be used between modules. If you don't
specify [public] then pull/push functions for other than top-level
functions are declared static.
-
+
=item noprint
The [noprint] property is a pidl extension that allows you to specify
=item subcontext(length)
Specifies that a size of I<length>
-bytes should be read, followed by a blob of that size,
+bytes should be read, followed by a blob of that size,
which will be parsed as NDR.
-subcontext() is deprecated now, and should not be used in new code.
+subcontext() is deprecated now, and should not be used in new code.
Instead, use represent_as() or transmit_as().
=item flag
-Specify boolean options, mostly used for
-low-level NDR options. Several options
+Specify boolean options, mostly used for
+low-level NDR options. Several options
can be specified using the | character.
Note that flags are inherited by substructures!
=item charset(name)
-Specify that the array or string uses the specified
-charset. If this attribute is specified, pidl will
-take care of converting the character data from this format
+Specify that the array or string uses the specified
+charset. If this attribute is specified, pidl will
+take care of converting the character data from this format
to the host format. Commonly used values are UCS2, DOS and UTF8.
=back
=head2 Unsupported MIDL properties or statements
-aggregatable, appobject, async_uuid, bindable, control,
-defaultbind, defaultcollelem, defaultvalue, defaultvtable, dispinterface,
-displaybind, dual, entry, first_is, helpcontext, helpfile, helpstringcontext,
-helpstringdll, hidden, idl_module, idl_quote, id, immediatebind, importlib,
-includelib, last_is, lcid, licensed, max_is, module,
-ms_union, no_injected_text, nonbrowsable, noncreatable, nonextensible, odl,
-oleautomation, optional, pragma, propget, propputref, propput, readonly,
-requestedit, restricted, retval, source, uidefault,
-usesgetlasterror, vararg, vi_progid, wire_marshal.
+aggregatable, appobject, async_uuid, bindable, control,
+defaultbind, defaultcollelem, defaultvalue, defaultvtable, dispinterface,
+displaybind, dual, entry, first_is, helpcontext, helpfile, helpstringcontext,
+helpstringdll, hidden, idl_module, idl_quote, id, immediatebind, importlib,
+includelib, last_is, lcid, licensed, max_is, module,
+ms_union, no_injected_text, nonbrowsable, noncreatable, nonextensible, odl,
+oleautomation, optional, pragma, propget, propputref, propput, readonly,
+requestedit, restricted, retval, source, uidefault,
+usesgetlasterror, vararg, vi_progid, wire_marshal.
=head1 EXAMPLES
# Generating an Wireshark parser
$ ./pidl --ws-parser -- atsvc.idl
-
+
# Generating a TDR parser and header
$ ./pidl --tdr-parser --header -- regf.idl
=head1 SEE ALSO
L<http://msdn.microsoft.com/library/en-us/rpc/rpc/field_attributes.asp>,
-L<http://wiki.wireshark.org/DCE/RPC>,
+L<http://wiki.wireshark.org/DCE/RPC>,
L<http://www.samba.org/>,
L<yapp(1)>
=head1 AUTHOR
-pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim Potter and Jelmer
+pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim Potter and Jelmer
Vernooij. The current maintainer is Jelmer Vernooij.
-This manpage was written by Jelmer Vernooij, partially based on the original
-pidl README by Andrew Tridgell.
-
+This manpage was written by Jelmer Vernooij, partially based on the original
+pidl README by Andrew Tridgell.
+
=cut
use strict;
use FindBin qw($RealBin $Script);
use lib "$RealBin/lib";
-use lib "$RealBin/../share/perl5";
use Getopt::Long;
use File::Basename;
use Parse::Pidl qw ( $VERSION );
my($filename) = shift;
my($v) = shift;
local(*FILE);
- open(FILE, ">$filename") || die "can't open $filename";
+ open(FILE, ">$filename") || die "can't open $filename";
print FILE $v;
close(FILE);
}
-my(@opt_incdirs) = ();
+my(@opt_incdirs) = ();
my($opt_help) = 0;
my($opt_version) = 0;
my($opt_parse_idl_tree) = 0;
my($opt_ndr_parser);
my($opt_tdr_parser);
my($opt_ws_parser);
-my($opt_swig);
my($opt_python);
my($opt_quiet) = 0;
my($opt_outputdir) = '.';
--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]
- --swig[=OUTFILE] create swig wrapper file [BASENAME.i]
--server[=OUTFILE] create server boilerplate [ndr_BASENAME_s.c]
--template print a template for a pipe
--dcom-proxy[=OUTFILE] create DCOM proxy [ndr_BASENAME_p.c]
--com-header[=OUTFILE] create header for COM [com_BASENAME.h]
Samba 3 output:
- --samba3-ndr-client[=OUTF] create client calls for Samba3
+ --samba3-ndr-client[=OUTF] create client calls for Samba3
using Samba4's NDR code [cli_BASENAME.c]
- --samba3-ndr-server[=OUTF] create server call wrapper for Samba3
+ --samba3-ndr-server[=OUTF] create server call wrapper for Samba3
using Samba4's NDR code [srv_BASENAME.c]
Wireshark parsers:
# main program
my $result = GetOptions (
- 'help|h|?' => \$opt_help,
+ 'help|h|?' => \$opt_help,
'version' => \$opt_version,
'outputdir=s' => \$opt_outputdir,
'dump-idl' => \$opt_dump_idl,
'ws-parser:s' => \$opt_ws_parser,
'python' => \$opt_python,
'diff' => \$opt_diff,
- 'swig:s' => \$opt_swig,
'dcom-proxy:s' => \$opt_dcom_proxy,
'com-header:s' => \$opt_com_header,
'quiet' => \$opt_quiet,
require Parse::Pidl::IDL;
$pidl = Parse::Pidl::IDL::parse_file($idl_file, \@opt_incdirs);
- defined @$pidl || die "Failed to parse $idl_file";
+ defined $pidl || die "Failed to parse $idl_file";
}
require Parse::Pidl::Typelist;
- Parse::Pidl::Typelist::LoadIdl($pidl);
+ Parse::Pidl::Typelist::LoadIdl($pidl, $basename);
if (defined($opt_dump_idl_tree)) {
my($pidl_file) = ($opt_dump_idl_tree or "$outputdir/$basename.pidl");
$pidl = Parse::Pidl::ODL::ODL2IDL($pidl, dirname($idl_file), \@opt_incdirs);
- if (defined($opt_ws_parser) or
+ if (defined($opt_ws_parser)) {
+ require Parse::Pidl::Wireshark::NDR;
+
+ my $cnffile = $idl_file;
+ $cnffile =~ s/\.idl$/\.cnf/;
+
+ my $generator = new Parse::Pidl::Wireshark::NDR();
+ $generator->Initialize($cnffile);
+ }
+
+
+ if (defined($opt_ws_parser) or
defined($opt_client) or
- defined($opt_server) or
+ defined($opt_server) or
defined($opt_header) or
defined($opt_ndr_parser) or
- defined($opt_python) or
+ defined($opt_python) or
defined($opt_dump_ndr_tree) or
- defined($opt_samba3_header) or
- defined($opt_samba3_parser) or
- defined($opt_samba3_server) or
- defined($opt_swig) or
+ defined($opt_samba3_header) or
+ defined($opt_samba3_parser) or
+ defined($opt_samba3_server) or
defined($opt_samba3_ndr_client) or
defined($opt_samba3_ndr_server)) {
require Parse::Pidl::NDR;
}
my $h_filename = "$outputdir/ndr_$basename.h";
- if (defined($opt_client)) {
+ my $c_header = "$outputdir/ndr_$basename\_c.h";
+ if (defined($opt_client) or defined($opt_samba3_ndr_client)) {
require Parse::Pidl::Samba4::NDR::Client;
my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c");
- my ($c_header) = $c_client;
+ $c_header = $c_client;
$c_header =~ s/\.c$/.h/;
- my ($srcd,$hdrd) = Parse::Pidl::Samba4::NDR::Client::Parse(
+ my $generator = new Parse::Pidl::Samba4::NDR::Client();
+ my ($srcd,$hdrd) = $generator->Parse(
$ndr,$gen_header,$h_filename,$c_header);
FileSave($c_client, $srcd);
FileSave($c_header, $hdrd);
}
- if (defined($opt_swig)) {
- require Parse::Pidl::Samba4::SWIG;
- my($filename) = ($opt_swig or "$outputdir/$basename.i");
- my $code = Parse::Pidl::Samba4::SWIG::Parse($ndr, $basename, "$outputdir/ndr_$basename\_c.h", $gen_header);
- FileSave($filename, $code);
- }
-
if (defined($opt_python)) {
require Parse::Pidl::Samba4::Python;
- my $generator = new Parse::Pidl::Samba4::Python();
- my ($hdr,$prsr) = $generator->Parse($basename, $ndr,
+ my $generator = new Parse::Pidl::Samba4::Python();
+ my ($prsr) = $generator->Parse($basename, $ndr,
"$outputdir/ndr_$basename\_c.h", $h_filename);
FileSave("$outputdir/py_$basename.c", $prsr);
- FileSave("$outputdir/py_$basename.h", $hdr);
}
if (defined($opt_server)) {
my $header = $client; $header =~ s/\.c$/\.h/;
require Parse::Pidl::Samba3::ClientNDR;
my $generator = new Parse::Pidl::Samba3::ClientNDR();
- my ($c_code,$h_code) = $generator->Parse($ndr, $header, $h_filename);
+ my ($c_code,$h_code) = $generator->Parse($ndr, $header, $c_header);
FileSave($client, $c_code);
FileSave($header, $h_code);
}