r26657: pidl: Add basics for generating Python modules.
[ira/wip.git] / source / pidl / pidl
index d1b8c4480bc1d4b33b7859a5e7005240e8d21ca7..4395df2020c25dc5961f8748e293b1a29c7541d8 100755 (executable)
@@ -4,7 +4,7 @@
 # package to parse IDL files and generate code for
 # rpc functions in Samba
 # Copyright tridge@samba.org 2000-2003
-# Copyright jelmer@samba.org 2005
+# Copyright jelmer@samba.org 2005-2007
 # released under the GNU GPL
 
 =pod
@@ -17,7 +17,7 @@ pidl - An IDL compiler written in Perl
 
 pidl --help
 
-pidl [--outputdir[=OUTNAME]] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--uint-enums] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--eth-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-header[=OUTPUT]] [--samba3-parser=[OUTPUT]] [--samba3-server=[OUTPUT]] [--samba3-template[=OUTPUT]] [--samba3-client[=OUTPUT]] [<idlfile>.idl]...
+pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=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]] [<idlfile>.idl]...
 
 =head1 DESCRIPTION
 
@@ -26,13 +26,13 @@ compatible with the midl compiler. IDL is short for
 "Interface Definition Language".
 
 pidl can generate stubs for DCE/RPC server code, DCE/RPC 
-client code and ethereal dissectors for DCE/RPC traffic.
+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 ethereal 
+using these interfaces, or even generate Wireshark 
 dissectors that can parse data sent over the 
 wire by these interfaces. 
 
@@ -57,11 +57,16 @@ Show list of available options.
 
 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 
+specified multiple times.
                
 =item I<--parse-idl-tree>
 
 Read internal tree structure from input files rather 
-then assuming they contain IDL.
+than assuming they contain IDL.
 
 =item I<--dump-idl>
 
@@ -93,15 +98,15 @@ the interface. Filename defaults to ndr_OUTNAME_s.c.
 Generate stubs for a RPC server that implements the interface. Output will 
 be written to stdout.
 
-=item I<--eth-parser>
+=item I<--ws-parser>
 
-Generate an Ethereal dissector (in C) and header file. The dissector filename
+Generate an Wireshark dissector (in C) and header file. The dissector filename
 defaults to packet-dcerpc-OUTNAME.c while the header filename defaults to 
 packet-dcerpc-OUTNAME.h.
        
-Pidl will read additional data from an ethereal conformance file if present. 
+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 then I<idl>. See L<Parse::Pidl::Ethereal::Conformance>
+extension I<cnf> rather than I<idl>. See L<Parse::Pidl::Wireshark::Conformance>
 for details on the format of this file.
 
 =item I<--diff>
@@ -120,29 +125,17 @@ file the to disk. Useful for debugging pidl.
 Tell pidl to dump the internal NDR information tree it generated 
 from the IDL file to disk.  Useful for debugging pidl.
 
-=item I<--samba3-header>
-
-Generate Samba3-style RPC header file. Filename defaults to rpc_BASENAME.h.
-
-=item I<--samba3-parser>
-
-Generate parser file for Samba3, to be placed in rpc_parse/. Filename defaults 
-to parse_BASENAME.c.
+=item I<--samba3-ndr-client>
 
-=item I<--samba3-server>
+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.
 
-Generate server file for Samba3, to be placed in rpc_server/. Filename defaults 
-to srv_BASENAME.c.
+=item I<--samba3-ndr-server>
 
-=item I<--samba3-template>
-
-Generate template for server-side implementation in Samba3, to be placed in 
-rpc_server/. Filename defaults to srv_BASENAME_nt.c
-
-=item I<--samba3-client>
-
-Generate client calls for Samba 3, to be placed in rpc_client/. Filename 
-defaults to cli_BASENAME.c.
+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
 
@@ -275,11 +268,12 @@ Datagram support (ncadg_*)
 
 =back
 
-=head2 Supported attributes
+=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.
+call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as, 
+transmit_as, import, include, cpp_quote.
 
 =head2 PIDL Specific properties
 
@@ -325,6 +319,9 @@ Specifies that a size of I<length>
 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. 
+Instead, use represent_as() or transmit_as().
+
 =item flag
 
 Specify boolean options, mostly used for 
@@ -348,28 +345,28 @@ to the host format. Commonly used values are UCS2, DOS and UTF8.
 
 =back
 
-=head2 Unsupported MIDL properties
+=head2 Unsupported MIDL properties or statements
 
-aggregatable, appobject, async_uuid, bindable, control, cpp_quote, 
+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, 
-import, include, includelib, last_is, lcid, licensed, max_is, module, 
+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, transmit_as, uidefault, 
+requestedit, restricted, retval, source, uidefault, 
 usesgetlasterror, vararg, vi_progid, wire_marshal. 
 
 =head1 EXAMPLES
 
-       # Generating an ethereal parser
-       $ ./pidl --eth-parser -- atsvc.idl
+       # Generating an Wireshark parser
+       $ ./pidl --ws-parser -- atsvc.idl
        
        # Generating a TDR parser and header
        $ ./pidl --tdr-parser --header -- regf.idl
 
-       # Generating a Samba3 parser, client and server
-       $ ./pidl --samba3-parser --samba3-server --samba3-client -- dfs.idl
+       # Generating a Samba3 client and server
+       $ ./pidl --samba3-ndr-client --samba3-ndr-server -- dfs.idl
 
        # Generating a Samba4 NDR parser, client and server
        $ ./pidl --ndr-parser --ndr-client --ndr-server -- samr.idl
@@ -377,7 +374,7 @@ usesgetlasterror, vararg, vi_progid, wire_marshal.
 =head1 SEE ALSO
 
 L<http://msdn.microsoft.com/library/en-us/rpc/rpc/field_attributes.asp>,
-L<http://wiki.ethereal.com/DCE/RPC>, 
+L<http://wiki.wireshark.org/DCE/RPC>, 
 L<http://www.samba.org/>,
 L<yapp(1)>
 
@@ -397,14 +394,13 @@ pidl README by Andrew Tridgell.
 
 
 use strict;
-use FindBin qw($RealBin);
+use FindBin qw($RealBin $Script);
 use lib "$RealBin";
 use lib "$RealBin/lib";
 use Getopt::Long;
 use File::Basename;
 use Parse::Pidl;
 use Parse::Pidl::Util;
-use Parse::Pidl::ODL;
 
 #####################################################################
 # save a data structure into a file
@@ -451,29 +447,28 @@ sub FileSave($$)
     close(FILE);
 }
 
+my(@opt_incdirs) = (); 
 my($opt_help) = 0;
 my($opt_parse_idl_tree) = 0;
 my($opt_dump_idl_tree);
 my($opt_dump_ndr_tree);
 my($opt_dump_idl) = 0;
-my($opt_uint_enums) = 0;
 my($opt_diff) = 0;
 my($opt_header);
 my($opt_samba3_header);
 my($opt_samba3_parser);
 my($opt_samba3_server);
-my($opt_samba3_template);
-my($opt_samba3_client);
+my($opt_samba3_ndr_client);
+my($opt_samba3_ndr_server);
 my($opt_template) = 0;
 my($opt_client);
 my($opt_server);
 my($opt_ndr_parser);
 my($opt_tdr_parser);
-my($opt_eth_parser);
+my($opt_ws_parser);
 my($opt_swig);
-my($opt_dcom_proxy);
-my($opt_com_header);
 my($opt_ejs);
+my($opt_python);
 my($opt_quiet) = 0;
 my($opt_outputdir) = '.';
 my($opt_verbose) = 0;
@@ -487,7 +482,7 @@ print "perl IDL parser and code generator
 Copyright (C) Andrew Tridgell <tridge\@samba.org>
 Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
 
-Usage: pidl [options] [--] <idlfile> [<idlfile>...]
+Usage: $Script [options] [--] <idlfile> [<idlfile>...]
 
 Generic Options:
  --help                  this help page
@@ -495,6 +490,7 @@ Generic Options:
  --warn-compat           warn about incompatibility with other compilers
  --quiet                 be quiet
  --verbose               be verbose
+ --includedir DIR        search DIR for included files
 
 Debugging:
  --dump-idl-tree[=FILE]  dump internal representation to file [BASENAME.pidl]
@@ -505,26 +501,23 @@ Debugging:
 
 Samba 4 output:
  --header[=OUTFILE]      create generic header file [BASENAME.h]
- --uint-enums            don't use C enums, instead use uint* types
  --ndr-parser[=OUTFILE]  create a C NDR parser [ndr_BASENAME.c]
  --client[=OUTFILE]      create a C NDR client [ndr_BASENAME_c.c]
  --tdr-parser[=OUTFILE]  create a C TDR parser [tdr_BASENAME.c]
  --ejs[=OUTFILE]         create ejs wrapper file [BASENAME_ejs.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-header[=OUTF]  create Samba3-style header [rpc_BASENAME.h]
- --samba3-parser[=OUTF]  create parser for Samba3 [parse_BASENAME.c]
- --samba3-template[=OUTF]create template implementation [srv_BASENAME_nt.c]
- --samba3-server[=OUTF]  create server side wrappers for Samba3 [srv_BASENAME.c]
- --samba3-client[=OUTF]  create client calls for Samba3 [cli_BASENAME.c]
-
-Ethereal parsers:
- --eth-parser[=OUTFILE]  create ethereal parser and header
+ --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 
+                            using Samba4's NDR code [srv_BASENAME.c]
+
+Wireshark parsers:
+ --ws-parser[=OUTFILE]  create Wireshark parser and header
 \n";
     exit(0);
 }
@@ -537,27 +530,23 @@ my $result = GetOptions (
                'dump-idl-tree:s' => \$opt_dump_idl_tree,
                'parse-idl-tree' => \$opt_parse_idl_tree,
                'dump-ndr-tree:s' => \$opt_dump_ndr_tree,
-           'uint-enums' => \$opt_uint_enums,
-               'samba3-header:s' => \$opt_samba3_header,
-               'samba3-parser:s' => \$opt_samba3_parser,
-               'samba3-server:s' => \$opt_samba3_server,
-               'samba3-template:s' => \$opt_samba3_template,
-               'samba3-client:s' => \$opt_samba3_client,
+               'samba3-ndr-client:s' => \$opt_samba3_ndr_client,
+               'samba3-ndr-server:s' => \$opt_samba3_ndr_server,
                'header:s' => \$opt_header,
            'server:s' => \$opt_server,
            'tdr-parser:s' => \$opt_tdr_parser,
            'template' => \$opt_template,
            'ndr-parser:s' => \$opt_ndr_parser,
            'client:s' => \$opt_client,
-           'eth-parser:s' => \$opt_eth_parser,
+           'ws-parser:s' => \$opt_ws_parser,
            'ejs' => \$opt_ejs,
+               '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,
                'verbose' => \$opt_verbose,
-           'warn-compat' => \$opt_warn_compat
+           'warn-compat' => \$opt_warn_compat,
+               'includedir=s@' => \@opt_incdirs
            );
 
 if (not $result) {
@@ -586,7 +575,7 @@ sub process_file($)
        } else {
                require Parse::Pidl::IDL;
 
-               $pidl = Parse::Pidl::IDL::parse_file($idl_file);
+               $pidl = Parse::Pidl::IDL::parse_file($idl_file, \@opt_incdirs);
                defined @$pidl || die "Failed to parse $idl_file";
                require Parse::Pidl::Typelist;
                Parse::Pidl::Typelist::LoadIdl($pidl);
@@ -597,10 +586,6 @@ sub process_file($)
                SaveStructure($pidl_file, $pidl) or die "Failed to save $pidl_file\n";
        }
 
-       if ($opt_uint_enums) {
-               Parse::Pidl::Util::setUseUintEnums(1);
-       }
-
        if ($opt_dump_idl) {
                require Parse::Pidl::Dump;
                print Parse::Pidl::Dump($pidl);
@@ -613,43 +598,25 @@ sub process_file($)
                unlink($tempfile);
        }
 
-       if (defined($opt_com_header)) {
-               require Parse::Pidl::Samba4::COM::Header;
-               my $res = Parse::Pidl::Samba4::COM::Header::Parse($pidl);
-               if ($res) {
-                       my $comh_filename = ($opt_com_header or "$outputdir/com_$basename.h");
-                       FileSave($comh_filename, 
-                       "#include \"librpc/gen_ndr/ndr_orpc.h\"\n" . 
-                       "#include \"$outputdir/ndr_$basename.h\"\n" . 
-                       $res);
-               }
-       }
-
-       if (defined($opt_dcom_proxy)) {
-               require Parse::Pidl::Samba4::COM::Proxy;
-               my $res = Parse::Pidl::Samba4::COM::Proxy::Parse($pidl);
-               if ($res) {
-                       my ($client) = ($opt_dcom_proxy or "$outputdir/$basename\_p.c");
-                       FileSave($client, 
-                       "#include \"includes.h\"\n" .
-                       "#include \"$outputdir/com_$basename.h\"\n" . 
-                       "#include \"lib/com/dcom/dcom.h\"\n" .$res);
-               }
-       }
-
        if ($opt_warn_compat) {
                require Parse::Pidl::Compat;
                Parse::Pidl::Compat::Check($pidl);
        }
 
-       $pidl = Parse::Pidl::ODL::ODL2IDL($pidl);
-
-       if (defined($opt_eth_parser) or 
-           defined($opt_client) or defined($opt_server) or 
-           defined($opt_ndr_parser) or defined($opt_ejs) or 
-               defined($opt_dump_ndr_tree) or defined($opt_samba3_header) or 
-           defined($opt_samba3_header) or defined($opt_samba3_server) or 
-               defined($opt_samba3_template) or defined($opt_samba3_client)) {
+       if (defined($opt_ws_parser) or 
+           defined($opt_client) or
+           defined($opt_server) or 
+           defined($opt_header) or
+           defined($opt_ndr_parser) or
+           defined($opt_ejs) 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_ndr_client) or
+           defined($opt_samba3_ndr_server)) {
                require Parse::Pidl::NDR;
                $ndr = Parse::Pidl::NDR::Parse($pidl);
        }
@@ -662,87 +629,73 @@ sub process_file($)
        my $gen_header = ($opt_header or "$outputdir/$basename.h");
        if (defined($opt_header)) {
                require Parse::Pidl::Samba4::Header;
-               FileSave($gen_header, Parse::Pidl::Samba4::Header::Parse($pidl));
+               FileSave($gen_header, Parse::Pidl::Samba4::Header::Parse($ndr));
        }
 
        my $h_filename = "$outputdir/ndr_$basename.h";
        if (defined($opt_client)) {
                require Parse::Pidl::Samba4::NDR::Client;
-               my ($client) = ($opt_client or "$outputdir/ndr_$basename\_c.c");
+               my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c");
+               my ($c_header) = $c_client;
+               $c_header =~ s/\.c$/.h/;
+
+               my ($srcd,$hdrd) = Parse::Pidl::Samba4::NDR::Client::Parse(
+                       $ndr,$gen_header,$h_filename,$c_header);
+
+               FileSave($c_client, $srcd);
+               FileSave($c_header, $hdrd);
+       }
 
-               FileSave($client, Parse::Pidl::Samba4::NDR::Client::Parse($ndr,$h_filename));
+       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_ejs)) {
                require Parse::Pidl::Samba4::EJS;
-               require Parse::Pidl::Samba4::EJSHeader;
-               FileSave("$outputdir/ndr_$basename\_ejs.c", Parse::Pidl::Samba4::EJS::Parse($ndr, $h_filename));
+               my $generator = new Parse::Pidl::Samba4::EJS(); 
+               my ($hdr,$prsr) = $generator->Parse($ndr, $h_filename);
+               FileSave("$outputdir/ndr_$basename\_ejs.c", $prsr);
+               FileSave("$outputdir/ndr_$basename\_ejs.h", $hdr);
+       }
 
-               FileSave("$outputdir/ndr_$basename\_ejs.h", Parse::Pidl::Samba4::EJSHeader::Parse($ndr));
+       if (defined($opt_python)) {
+               require Parse::Pidl::Samba4::Python;
+               my $generator = new Parse::Pidl::Samba4::Python(); 
+               my ($hdr,$prsr) = $generator->Parse($basename, $ndr, $h_filename);
+               FileSave("$outputdir/py_$basename.c", $prsr);
+               FileSave("$outputdir/py_$basename.h", $hdr);
        }
 
        if (defined($opt_server)) {
                require Parse::Pidl::Samba4::NDR::Server;
-               my $dcom = "";
-
-               foreach my $x (@{$pidl}) {
-                       next if ($x->{TYPE} ne "INTERFACE");
-
-                       if (Parse::Pidl::Util::has_property($x, "object")) {
-                               require Parse::Pidl::Samba4::COM::Stub;
-                               $dcom .= Parse::Pidl::Samba4::COM::Stub::ParseInterface($x);
-                       }
-               }
 
                FileSave(($opt_server or "$outputdir/ndr_$basename\_s.c"), Parse::Pidl::Samba4::NDR::Server::Parse($ndr,$h_filename));
-
-               if ($dcom ne "") {
-                       $dcom = "
-#include \"includes.h\"
-#include \"$h_filename\"
-#include \"rpc_server/dcerpc_server.h\"
-#include \"rpc_server/common/common.h\"
-
-$dcom
-";
-       FileSave("$outputdir/$basename\_d.c", $dcom);
-               }
        }
 
        if (defined($opt_ndr_parser)) {
                my $parser_fname = ($opt_ndr_parser or "$outputdir/ndr_$basename.c");
                require Parse::Pidl::Samba4::NDR::Parser;
-               my $header_fname = $parser_fname; 
-               $header_fname =~ s/\.c$/\.h/;
-               my ($header,$parser) = Parse::Pidl::Samba4::NDR::Parser::Parse($ndr, $basename);
-
-               my $baseheader = $h_filename; $baseheader =~ s/\/ndr_/\//;
-               $header = "#include \"$baseheader\"\n$header";
-
-               $parser = "#include \"includes.h\"\n"
-               . "#include \"librpc/gen_ndr/ndr_misc.h\"\n"
-               . "#include \"librpc/gen_ndr/ndr_dcerpc.h\"\n"
-               . "#include \"$header_fname\"\n\n$parser";
+               my $generator = new Parse::Pidl::Samba4::NDR::Parser();
+               my ($header,$parser) = $generator->Parse($ndr, $gen_header, $h_filename);
 
                FileSave($parser_fname, $parser);
-               FileSave($header_fname, $header);
+               FileSave($h_filename, $header);
 
-               if (defined($opt_swig)) {
-                 require Parse::Pidl::Samba4::SWIG;
-                 my($filename) = ($opt_swig or "$outputdir/$basename.i");
-                 Parse::Pidl::Samba4::SWIG::RewriteHeader($pidl, $header_fname, $filename);
-               }
        }
 
-       if (defined($opt_eth_parser)) {
-         require Parse::Pidl::Ethereal::NDR;
-         my($eparser) = ($opt_eth_parser or "$outputdir/packet-dcerpc-$basename.c");
+       if (defined($opt_ws_parser)) {
+         require Parse::Pidl::Wireshark::NDR;
+         my($eparser) = ($opt_ws_parser or "$outputdir/packet-dcerpc-$basename.c");
          my $eheader = $eparser;
          $eheader =~ s/\.c$/\.h/;
          my $cnffile = $idl_file;
          $cnffile =~ s/\.idl$/\.cnf/;
 
-         my ($dp, $dh) = Parse::Pidl::Ethereal::NDR::Parse($ndr, $idl_file, $eheader, $cnffile);
+         my $generator = new Parse::Pidl::Wireshark::NDR();
+         my ($dp, $dh) = $generator->Parse($ndr, $idl_file, $eheader, $cnffile);
          FileSave($eparser, $dp) if defined($dp);
          FileSave($eheader, $dh) if defined($dh);
        }
@@ -752,7 +705,8 @@ $dcom
                my $tdr_header = $tdr_parser;
                $tdr_header =~ s/\.c$/\.h/;
                require Parse::Pidl::Samba4::TDR;
-               my ($hdr,$prsr) = Parse::Pidl::Samba4::TDR::Parser($pidl, $tdr_header, $gen_header);
+               my $generator = new Parse::Pidl::Samba4::TDR();
+               my ($hdr,$prsr) = $generator->Parser($pidl, $tdr_header, $gen_header);
                FileSave($tdr_parser, $prsr);
                FileSave($tdr_header, $hdr);
        }
@@ -762,47 +716,29 @@ $dcom
                print Parse::Pidl::Samba4::Template::Parse($pidl);
        }
 
-       if (defined($opt_samba3_header) or defined($opt_samba3_parser) or
-               defined($opt_samba3_server) or defined($opt_samba3_client) or
-               defined($opt_samba3_template)) {
-               require Parse::Pidl::Samba3::Types;
-               Parse::Pidl::Samba3::Types::LoadTypes($ndr);
-       }
-
-       if (defined($opt_samba3_header)) {
-               my $header = ($opt_samba3_header or "$outputdir/rpc_$basename.h");
-               require Parse::Pidl::Samba3::Header;
-               FileSave($header, Parse::Pidl::Samba3::Header::Parse($ndr, $basename));
-       }
-
-       if (defined($opt_samba3_parser)) {
-               my $header = ($opt_samba3_parser or "$outputdir/parse_$basename.c");
-               require Parse::Pidl::Samba3::Parser;
-               FileSave($header, Parse::Pidl::Samba3::Parser::Parse($ndr, $basename));
-       }
-
-       if (defined($opt_samba3_server)) {
-               my $header = ($opt_samba3_server or "$outputdir/srv_$basename.c");
-               require Parse::Pidl::Samba3::Server;
-               FileSave($header, Parse::Pidl::Samba3::Server::Parse($ndr, $basename));
-       }
-
-       if (defined($opt_samba3_template)) {
-               my $header = ($opt_samba3_template or "$outputdir/srv_$basename\_nt.c");
-               require Parse::Pidl::Samba3::Template;
-               FileSave($header, Parse::Pidl::Samba3::Template::Parse($ndr, $basename));
+       if (defined($opt_samba3_ndr_client)) {
+               my $client = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c");
+               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);
+               FileSave($client, $c_code);
+               FileSave($header, $h_code);
        }
 
-       if (defined($opt_samba3_client)) {
-               my $header = ($opt_samba3_client or "$outputdir/cli_$basename.c");
-               require Parse::Pidl::Samba3::Client;
-               FileSave($header, Parse::Pidl::Samba3::Client::Parse($ndr, $basename));
+       if (defined($opt_samba3_ndr_server)) {
+               my $server = ($opt_samba3_ndr_server or "$outputdir/srv_$basename.c");
+               my $header = $server; $header =~ s/\.c$/\.h/;
+               require Parse::Pidl::Samba3::ServerNDR;
+               my ($c_code,$h_code) = Parse::Pidl::Samba3::ServerNDR::Parse($ndr, $header, $h_filename);
+               FileSave($server, $c_code);
+               FileSave($header, $h_code);
        }
 
 }
 
 if (scalar(@ARGV) == 0) {
-       print "pidl: no input files\n";
+       print "$Script: no input files\n";
        exit(1);
 }