Install pidl by default if ExtUtils::MakeMaker is available. This should make the...
[samba.git] / source4 / pidl / pidl
index 2cc7143386d9877a3a3f7f4545d7a79aa13dcfba..b7a22f04997b307dc0ea1b523215f25af3daaaeb 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]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=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]] [--typelib=[OUTPUT]] [<idlfile>.idl]...
 
 =head1 DESCRIPTION
 
@@ -52,6 +52,10 @@ both marshalling/unmarshalling and debugging purposes).
 =item I<--help>
 
 Show list of available options.
+
+=item I<--version>
+
+Show pidl version
                
 =item I<--outputdir OUTNAME>
 
@@ -88,6 +92,10 @@ 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>
+
+Write type information to the specified file.
+
 =item I<--server>
 
 Generate boilerplate for the RPC server that implements 
@@ -273,7 +281,7 @@ Datagram support (ncadg_*)
 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.
+transmit_as, import, include, cpp_quote.
 
 =head2 PIDL Specific properties
 
@@ -319,6 +327,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 
@@ -344,7 +355,7 @@ to the host format. Commonly used values are UCS2, DOS and UTF8.
 
 =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, 
@@ -392,13 +403,12 @@ pidl README by Andrew Tridgell.
 
 use strict;
 use FindBin qw($RealBin $Script);
-use lib "$RealBin";
 use lib "$RealBin/lib";
+use lib "$RealBin/../share/perl5";
 use Getopt::Long;
 use File::Basename;
-use Parse::Pidl;
+use Parse::Pidl qw ( $VERSION );
 use Parse::Pidl::Util;
-use Parse::Pidl::ODL;
 
 #####################################################################
 # save a data structure into a file
@@ -447,6 +457,7 @@ sub FileSave($$)
 
 my(@opt_incdirs) = (); 
 my($opt_help) = 0;
+my($opt_version) = 0;
 my($opt_parse_idl_tree) = 0;
 my($opt_dump_idl_tree);
 my($opt_dump_ndr_tree);
@@ -460,14 +471,14 @@ my($opt_samba3_ndr_client);
 my($opt_samba3_ndr_server);
 my($opt_template) = 0;
 my($opt_client);
+my($opt_typelib);
 my($opt_server);
 my($opt_ndr_parser);
 my($opt_tdr_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;
@@ -477,7 +488,9 @@ my($opt_warn_compat) = 0;
 # display help text
 sub ShowHelp()
 {
-print "perl IDL parser and code generator
+print "perl IDL parser and code generator\n";
+ShowVersion();
+print"
 Copyright (C) Andrew Tridgell <tridge\@samba.org>
 Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
 
@@ -485,6 +498,7 @@ Usage: $Script [options] [--] <idlfile> [<idlfile>...]
 
 Generic Options:
  --help                  this help page
+ --version               show pidl version
  --outputdir=OUTDIR      put output in OUTDIR/ [.]
  --warn-compat           warn about incompatibility with other compilers
  --quiet                 be quiet
@@ -497,6 +511,7 @@ Debugging:
  --dump-ndr-tree[=FILE]  dump internal NDR data tree to file [BASENAME.ndr]
  --dump-idl              regenerate IDL file
  --diff                  run diff on original IDL and dumped output
+ --typelib               print type information
 
 Samba 4 output:
  --header[=OUTFILE]      create generic header file [BASENAME.h]
@@ -504,11 +519,10 @@ Samba 4 output:
  --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-ndr-client[=OUTF] create client calls for Samba3 
@@ -522,9 +536,17 @@ Wireshark parsers:
     exit(0);
 }
 
+#########################################
+# Display version
+sub ShowVersion()
+{
+    print "perl IDL version $VERSION\n";
+}
+
 # main program
 my $result = GetOptions (
            'help|h|?' => \$opt_help, 
+            'version' => \$opt_version,
            'outputdir=s' => \$opt_outputdir,
            'dump-idl' => \$opt_dump_idl,
                'dump-idl-tree:s' => \$opt_dump_idl_tree,
@@ -534,16 +556,16 @@ my $result = GetOptions (
                'samba3-ndr-server:s' => \$opt_samba3_ndr_server,
                'header:s' => \$opt_header,
            'server:s' => \$opt_server,
+               'typelib:s' => \$opt_typelib,
            'tdr-parser:s' => \$opt_tdr_parser,
            'template' => \$opt_template,
            'ndr-parser:s' => \$opt_ndr_parser,
            'client:s' => \$opt_client,
            '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,
@@ -559,6 +581,11 @@ if ($opt_help) {
     exit(0);
 }
 
+if ($opt_version) {
+    ShowVersion();
+    exit(0);
+}
+
 sub process_file($)
 {
        my $idl_file = shift;
@@ -599,38 +626,25 @@ sub process_file($)
                unlink($tempfile);
        }
 
-       my $comh_filename = ($opt_com_header or "$outputdir/com_$basename.h");
-       if (defined($opt_com_header)) {
-               require Parse::Pidl::Samba4::COM::Header;
-               my $res = Parse::Pidl::Samba4::COM::Header::Parse($pidl,"$outputdir/ndr_$basename.h");
-               if ($res) {
-                       FileSave($comh_filename, $res);
-               }
-       }
-
-       if (defined($opt_dcom_proxy)) {
-               require Parse::Pidl::Samba4::COM::Proxy;
-               my $res = Parse::Pidl::Samba4::COM::Proxy::Parse($pidl,$comh_filename);
-               if ($res) {
-                       my ($client) = ($opt_dcom_proxy or "$outputdir/$basename\_p.c");
-                       FileSave($client, $res);
-               }
-       }
-
        if ($opt_warn_compat) {
                require Parse::Pidl::Compat;
                Parse::Pidl::Compat::Check($pidl);
        }
 
-       $pidl = Parse::Pidl::ODL::ODL2IDL($pidl);
-
        if (defined($opt_ws_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_parser) or defined($opt_samba3_server) or 
-               defined($opt_swig) or defined($opt_samba3_ndr_client) or
-               defined($opt_samba3_ndr_server)) {
+           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);
        }
@@ -643,7 +657,7 @@ 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";
@@ -669,44 +683,32 @@ sub process_file($)
 
        if (defined($opt_ejs)) {
                require Parse::Pidl::Samba4::EJS;
-               my ($hdr,$prsr) = 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);
        }
 
+       if (defined($opt_python)) {
+               require Parse::Pidl::Samba4::Python;
+               my $generator = new Parse::Pidl::Samba4::Python(); 
+               my ($hdr,$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)) {
                require Parse::Pidl::Samba4::NDR::Server;
-               my $dcom = "";
-
-               foreach (@{$pidl}) {
-                       next if ($_->{TYPE} ne "INTERFACE");
-
-                       if (Parse::Pidl::Util::has_property($_, "object")) {
-                               require Parse::Pidl::Samba4::COM::Stub;
-                               $dcom .= Parse::Pidl::Samba4::COM::Stub::ParseInterface($_);
-                       }
-               }
 
                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,$parser) = Parse::Pidl::Samba4::NDR::Parser::Parse($ndr, $gen_header, $h_filename);
-
+               my $generator = new Parse::Pidl::Samba4::NDR::Parser();
+               my ($header,$parser) = $generator->Parse($ndr, $gen_header, $h_filename);
 
                FileSave($parser_fname, $parser);
                FileSave($h_filename, $header);
@@ -721,7 +723,8 @@ $dcom
          my $cnffile = $idl_file;
          $cnffile =~ s/\.idl$/\.cnf/;
 
-         my ($dp, $dh) = Parse::Pidl::Wireshark::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);
        }
@@ -731,11 +734,18 @@ $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);
        }
 
+       if (defined($opt_typelib)) {
+               my $typelib = ($opt_typelib or "$outputdir/$basename.tlb");
+               require Parse::Pidl::Typelist;
+               FileSave($typelib, Parse::Pidl::Typelist::GenerateTypeLib());
+       }
+
        if ($opt_template) {
                require Parse::Pidl::Samba4::Template;
                print Parse::Pidl::Samba4::Template::Parse($pidl);
@@ -745,7 +755,8 @@ $dcom
                my $client = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c");
                my $header = $client; $header =~ s/\.c$/\.h/;
                require Parse::Pidl::Samba3::ClientNDR;
-               my ($c_code,$h_code) = Parse::Pidl::Samba3::ClientNDR::Parse($ndr, $header, $h_filename);
+               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);
        }