r16824: Rename Ethereal -> Wireshark (patch from Joerg Mayer)
[Samba/aatanasov.git] / source / pidl / pidl
blob4d23060f6e4b36879a18de68a7ceaa90729c575f
1 #!/usr/bin/perl -w
3 ###################################################
4 # package to parse IDL files and generate code for
5 # rpc functions in Samba
6 # Copyright tridge@samba.org 2000-2003
7 # Copyright jelmer@samba.org 2005
8 # released under the GNU GPL
10 =pod
12 =head1 NAME
14 pidl - An IDL compiler written in Perl
16 =head1 SYNOPSIS
18 pidl --help
20 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] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-header[=OUTPUT]] [--samba3-parser=[OUTPUT]] [--samba3-server=[OUTPUT]] [--samba3-template[=OUTPUT]] [--samba3-client[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [<idlfile>.idl]...
22 =head1 DESCRIPTION
24 pidl is an IDL compiler written in Perl that aims to be somewhat
25 compatible with the midl compiler. IDL is short for
26 "Interface Definition Language".
28 pidl can generate stubs for DCE/RPC server code, DCE/RPC
29 client code and Wireshark dissectors for DCE/RPC traffic.
31 IDL compilers like pidl take a description
32 of an interface as their input and use it to generate C
33 (though support for other languages may be added later) code that
34 can use these interfaces, pretty print data sent
35 using these interfaces, or even generate Wireshark
36 dissectors that can parse data sent over the
37 wire by these interfaces.
39 pidl takes IDL files in the same format as is used by midl,
40 converts it to a .pidl file (which contains pidl's internal representation of the interface) and can then generate whatever output you need.
41 .pidl files should be used for debugging purposes only. Write your
42 interface definitions in .idl format.
44 The goal of pidl is to implement a IDL compiler that can be used
45 while developing the RPC subsystem in Samba (for
46 both marshalling/unmarshalling and debugging purposes).
48 =head1 OPTIONS
50 =over 4
52 =item I<--help>
54 Show list of available options.
56 =item I<--outputdir OUTNAME>
58 Write output files to the specified directory. Defaults to the current
59 directory.
61 =item I<--parse-idl-tree>
63 Read internal tree structure from input files rather
64 than assuming they contain IDL.
66 =item I<--dump-idl>
68 Generate a new IDL file. File will be named OUTNAME.idl.
70 =item I<--header>
72 Generate a C header file for the specified interface. Filename defaults to OUTNAME.h.
74 =item I<--ndr-parser>
76 Generate a C file and C header containing NDR parsers. The filename for
77 the parser defaults to ndr_OUTNAME.c. The header filename will be the
78 parser filename with the extension changed from .c to .h.
80 =item I<--tdr-parser>
82 Generate a C file and C header containing TDR parsers. The filename for
83 the parser defaults to tdr_OUTNAME.c. The header filename will be the
84 parser filename with the extension changed from .c to .h.
86 =item I<--server>
88 Generate boilerplate for the RPC server that implements
89 the interface. Filename defaults to ndr_OUTNAME_s.c.
91 =item I<--template>
93 Generate stubs for a RPC server that implements the interface. Output will
94 be written to stdout.
96 =item I<--ws-parser>
98 Generate an Wireshark dissector (in C) and header file. The dissector filename
99 defaults to packet-dcerpc-OUTNAME.c while the header filename defaults to
100 packet-dcerpc-OUTNAME.h.
102 Pidl will read additional data from an Wireshark conformance file if present.
103 Such a file should have the same location as the IDL file but with the
104 extension I<cnf> rather than I<idl>. See L<Parse::Pidl::Wireshark::Conformance>
105 for details on the format of this file.
107 =item I<--diff>
109 Parse an IDL file, generate a new IDL file based on the internal data
110 structures and see if there are any differences with the original IDL file.
111 Useful for debugging pidl.
113 =item I<--dump-idl-tree>
115 Tell pidl to dump the internal tree representation of an IDL
116 file the to disk. Useful for debugging pidl.
118 =item I<--dump-ndr-tree>
120 Tell pidl to dump the internal NDR information tree it generated
121 from the IDL file to disk. Useful for debugging pidl.
123 =item I<--samba3-header>
125 Generate Samba3-style RPC header file. Filename defaults to rpc_BASENAME.h.
127 =item I<--samba3-parser>
129 Generate parser file for Samba3, to be placed in rpc_parse/. Filename defaults
130 to parse_BASENAME.c.
132 =item I<--samba3-server>
134 Generate server file for Samba3, to be placed in rpc_server/. Filename defaults
135 to srv_BASENAME.c.
137 =item I<--samba3-template>
139 Generate template for server-side implementation in Samba3, to be placed in
140 rpc_server/. Filename defaults to srv_BASENAME_nt.c
142 =item I<--samba3-client>
144 Generate client calls for Samba 3, to be placed in rpc_client/. Filename
145 defaults to cli_BASENAME.c.
147 =item I<--samba3-ndr-client>
149 Generate client calls for Samba3, to be placed in rpc_client/. Instead of
150 calling out to the code in Samba3's rpc_parse/, this will call out to
151 Samba4's NDR code instead.
153 =back
155 =head1 IDL SYNTAX
157 IDL files are always preprocessed using the C preprocessor.
159 Pretty much everything in an interface (the interface itself, functions,
160 parameters) can have attributes (or properties whatever name you give them).
161 Attributes always prepend the element they apply to and are surrounded
162 by square brackets ([]). Multiple attributes are separated by comma's;
163 arguments to attributes are specified between parentheses.
165 See the section COMPATIBILITY for the list of attributes that
166 pidl supports.
168 C-style comments can be used.
170 =head2 CONFORMANT ARRAYS
172 A conformant array is one with that ends in [*] or []. The strange
173 things about conformant arrays are that they can only appear as the last
174 element of a structure (unless there is a pointer to the conformant array,
175 of course) and the array size appears before the structure itself on the wire.
177 So, in this example:
179 typedef struct {
180 long abc;
181 long count;
182 long foo;
183 [size_is(count)] long s[*];
184 } Struct1;
186 it appears like this:
188 [size_is] [abc] [count] [foo] [s...]
190 the first [size_is] field is the allocation size of the array, and
191 occurs before the array elements and even before the structure
192 alignment.
194 Note that size_is() can refer to a constant, but that doesn't change
195 the wire representation. It does not make the array a fixed array.
197 midl.exe would write the above array as the following C header:
199 typedef struct {
200 long abc;
201 long count;
202 long foo;
203 long s[1];
204 } Struct1;
206 pidl takes a different approach, and writes it like this:
208 typedef struct {
209 long abc;
210 long count;
211 long foo;
212 long *s;
213 } Struct1;
215 =head2 VARYING ARRAYS
217 A varying array looks like this:
219 typedef struct {
220 long abc;
221 long count;
222 long foo;
223 [size_is(count)] long *s;
224 } Struct1;
226 This will look like this on the wire:
228 [abc] [count] [foo] [PTR_s] [count] [s...]
230 =head2 FIXED ARRAYS
232 A fixed array looks like this:
234 typedef struct {
235 long s[10];
236 } Struct1;
238 The NDR representation looks just like 10 separate long
239 declarations. The array size is not encoded on the wire.
241 pidl also supports "inline" arrays, which are not part of the IDL/NDR
242 standard. These are declared like this:
244 typedef struct {
245 uint32 foo;
246 uint32 count;
247 uint32 bar;
248 long s[count];
249 } Struct1;
251 This appears like this:
253 [foo] [count] [bar] [s...]
255 Fixed arrays are an extension added to support some of the strange
256 embedded structures in security descriptors and spoolss.
258 This section is by no means complete. See the OpenGroup and MSDN
259 documentation for additional information.
261 =head1 COMPATIBILITY WITH MIDL
263 =head2 Missing features in pidl
265 The following MIDL features are not (yet) implemented in pidl
266 or are implemented with an incompatible interface:
268 =over
270 =item *
272 Asynchronous communication
274 =item *
276 Typelibs (.tlb files)
278 =item *
280 Datagram support (ncadg_*)
282 =back
284 =head2 Supported attributes
286 in, out, ref, length_is, switch_is, size_is, uuid, case, default, string,
287 unique, ptr, pointer_default, v1_enum, object, helpstring, range, local,
288 call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as,
289 transmit_as.
291 =head2 PIDL Specific properties
293 =over 4
295 =item public
297 The [public] property on a structure or union is a pidl extension that
298 forces the generated pull/push functions to be non-static. This allows
299 you to declare types that can be used between modules. If you don't
300 specify [public] then pull/push functions for other than top-level
301 functions are declared static.
303 =item noprint
305 The [noprint] property is a pidl extension that allows you to specify
306 that pidl should not generate a ndr_print_*() function for that
307 structure or union. This is used when you wish to define your own
308 print function that prints a structure in a nicer manner. A good
309 example is the use of [noprint] on dom_sid, which allows the
310 pretty-printing of SIDs.
312 =item value
314 The [value(expression)] property is a pidl extension that allows you
315 to specify the value of a field when it is put on the wire. This
316 allows fields that always have a well-known value to be automatically
317 filled in, thus making the API more programmer friendly. The
318 expression can be any C expression.
320 =item relative
322 The [relative] property can be supplied on a pointer. When it is used
323 it declares the pointer as a spoolss style "relative" pointer, which
324 means it appears on the wire as an offset within the current
325 encapsulating structure. This is not part of normal IDL/NDR, but it is
326 a very useful extension as it avoids the manual encoding of many
327 complex structures.
329 =item subcontext(length)
331 Specifies that a size of I<length>
332 bytes should be read, followed by a blob of that size,
333 which will be parsed as NDR.
335 =item flag
337 Specify boolean options, mostly used for
338 low-level NDR options. Several options
339 can be specified using the | character.
340 Note that flags are inherited by substructures!
342 =item nodiscriminant
344 The [nodiscriminant] property on a union means that the usual uint16
345 discriminent field at the start of the union on the wire is
346 omitted. This is not normally allowed in IDL/NDR, but is used for some
347 spoolss structures.
349 =item charset(name)
351 Specify that the array or string uses the specified
352 charset. If this attribute is specified, pidl will
353 take care of converting the character data from this format
354 to the host format. Commonly used values are UCS2, DOS and UTF8.
356 =back
358 =head2 Unsupported MIDL properties
360 aggregatable, appobject, async_uuid, bindable, control, cpp_quote,
361 defaultbind, defaultcollelem, defaultvalue, defaultvtable, dispinterface,
362 displaybind, dual, entry, first_is, helpcontext, helpfile, helpstringcontext,
363 helpstringdll, hidden, idl_module, idl_quote, id, immediatebind, importlib,
364 import, include, includelib, last_is, lcid, licensed, max_is, module,
365 ms_union, no_injected_text, nonbrowsable, noncreatable, nonextensible, odl,
366 oleautomation, optional, pragma, propget, propputref, propput, readonly,
367 requestedit, restricted, retval, source, uidefault,
368 usesgetlasterror, vararg, vi_progid, wire_marshal.
370 =head1 EXAMPLES
372 # Generating an Wireshark parser
373 $ ./pidl --ws-parser -- atsvc.idl
375 # Generating a TDR parser and header
376 $ ./pidl --tdr-parser --header -- regf.idl
378 # Generating a Samba3 parser, client and server
379 $ ./pidl --samba3-parser --samba3-server --samba3-client -- dfs.idl
381 # Generating a Samba4 NDR parser, client and server
382 $ ./pidl --ndr-parser --ndr-client --ndr-server -- samr.idl
384 =head1 SEE ALSO
386 L<http://msdn.microsoft.com/library/en-us/rpc/rpc/field_attributes.asp>,
387 L<http://wiki.wireshark.org/DCE/RPC>,
388 L<http://www.samba.org/>,
389 L<yapp(1)>
391 =head1 LICENSE
393 pidl is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>.
395 =head1 AUTHOR
397 pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim Potter and Jelmer
398 Vernooij. The current maintainer is Jelmer Vernooij.
400 This manpage was written by Jelmer Vernooij, partially based on the original
401 pidl README by Andrew Tridgell.
403 =cut
406 use strict;
407 use FindBin qw($RealBin);
408 use lib "$RealBin";
409 use lib "$RealBin/lib";
410 use Getopt::Long;
411 use File::Basename;
412 use Parse::Pidl;
413 use Parse::Pidl::Util;
414 use Parse::Pidl::ODL;
416 #####################################################################
417 # save a data structure into a file
418 sub SaveStructure($$)
420 my($filename,$v) = @_;
421 FileSave($filename, Parse::Pidl::Util::MyDumper($v));
424 #####################################################################
425 # load a data structure from a file (as saved with SaveStructure)
426 sub LoadStructure($)
428 my $f = shift;
429 my $contents = FileLoad($f);
430 defined $contents || return undef;
431 return eval "$contents";
434 #####################################################################
435 # read a file into a string
436 sub FileLoad($)
438 my($filename) = shift;
439 local(*INPUTFILE);
440 open(INPUTFILE, $filename) || return undef;
441 my($saved_delim) = $/;
442 undef $/;
443 my($data) = <INPUTFILE>;
444 close(INPUTFILE);
445 $/ = $saved_delim;
446 return $data;
449 #####################################################################
450 # write a string into a file
451 sub FileSave($$)
453 my($filename) = shift;
454 my($v) = shift;
455 local(*FILE);
456 open(FILE, ">$filename") || die "can't open $filename";
457 print FILE $v;
458 close(FILE);
461 my($opt_help) = 0;
462 my($opt_parse_idl_tree) = 0;
463 my($opt_dump_idl_tree);
464 my($opt_dump_ndr_tree);
465 my($opt_dump_idl) = 0;
466 my($opt_uint_enums) = 0;
467 my($opt_diff) = 0;
468 my($opt_header);
469 my($opt_samba3_header);
470 my($opt_samba3_parser);
471 my($opt_samba3_server);
472 my($opt_samba3_template);
473 my($opt_samba3_client);
474 my($opt_samba3_ndr_client);
475 my($opt_template) = 0;
476 my($opt_client);
477 my($opt_server);
478 my($opt_ndr_parser);
479 my($opt_tdr_parser);
480 my($opt_ws_parser);
481 my($opt_swig);
482 my($opt_dcom_proxy);
483 my($opt_com_header);
484 my($opt_ejs);
485 my($opt_quiet) = 0;
486 my($opt_outputdir) = '.';
487 my($opt_verbose) = 0;
488 my($opt_warn_compat) = 0;
490 #########################################
491 # display help text
492 sub ShowHelp()
494 print "perl IDL parser and code generator
495 Copyright (C) Andrew Tridgell <tridge\@samba.org>
496 Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
498 Usage: pidl [options] [--] <idlfile> [<idlfile>...]
500 Generic Options:
501 --help this help page
502 --outputdir=OUTDIR put output in OUTDIR/ [.]
503 --warn-compat warn about incompatibility with other compilers
504 --quiet be quiet
505 --verbose be verbose
507 Debugging:
508 --dump-idl-tree[=FILE] dump internal representation to file [BASENAME.pidl]
509 --parse-idl-tree read internal representation instead of IDL
510 --dump-ndr-tree[=FILE] dump internal NDR data tree to file [BASENAME.ndr]
511 --dump-idl regenerate IDL file
512 --diff run diff on original IDL and dumped output
514 Samba 4 output:
515 --header[=OUTFILE] create generic header file [BASENAME.h]
516 --uint-enums don't use C enums, instead use uint* types
517 --ndr-parser[=OUTFILE] create a C NDR parser [ndr_BASENAME.c]
518 --client[=OUTFILE] create a C NDR client [ndr_BASENAME_c.c]
519 --tdr-parser[=OUTFILE] create a C TDR parser [tdr_BASENAME.c]
520 --ejs[=OUTFILE] create ejs wrapper file [BASENAME_ejs.c]
521 --swig[=OUTFILE] create swig wrapper file [BASENAME.i]
522 --server[=OUTFILE] create server boilerplate [ndr_BASENAME_s.c]
523 --template print a template for a pipe
524 --dcom-proxy[=OUTFILE] create DCOM proxy [ndr_BASENAME_p.c]
525 --com-header[=OUTFILE] create header for COM [com_BASENAME.h]
527 Samba 3 output:
528 --samba3-header[=OUTF] create Samba3-style header [rpc_BASENAME.h]
529 --samba3-parser[=OUTF] create parser for Samba3 [parse_BASENAME.c]
530 --samba3-template[=OUTF]create template implementation [srv_BASENAME_nt.c]
531 --samba3-server[=OUTF] create server side wrappers for Samba3 [srv_BASENAME.c]
532 --samba3-client[=OUTF] create client calls for Samba3 [cli_BASENAME.c]
533 --samba3-ndr-client[=OUTF] create client calls for Samba3
534 using Samba4's NDR code [cli_BASENAME.c]
536 Wireshark parsers:
537 --ws-parser[=OUTFILE] create Wireshark parser and header
538 \n";
539 exit(0);
542 # main program
543 my $result = GetOptions (
544 'help|h|?' => \$opt_help,
545 'outputdir=s' => \$opt_outputdir,
546 'dump-idl' => \$opt_dump_idl,
547 'dump-idl-tree:s' => \$opt_dump_idl_tree,
548 'parse-idl-tree' => \$opt_parse_idl_tree,
549 'dump-ndr-tree:s' => \$opt_dump_ndr_tree,
550 'uint-enums' => \$opt_uint_enums,
551 'samba3-header:s' => \$opt_samba3_header,
552 'samba3-parser:s' => \$opt_samba3_parser,
553 'samba3-server:s' => \$opt_samba3_server,
554 'samba3-template:s' => \$opt_samba3_template,
555 'samba3-client:s' => \$opt_samba3_client,
556 'samba3-ndr-client:s' => \$opt_samba3_ndr_client,
557 'header:s' => \$opt_header,
558 'server:s' => \$opt_server,
559 'tdr-parser:s' => \$opt_tdr_parser,
560 'template' => \$opt_template,
561 'ndr-parser:s' => \$opt_ndr_parser,
562 'client:s' => \$opt_client,
563 'ws-parser:s' => \$opt_ws_parser,
564 'ejs' => \$opt_ejs,
565 'diff' => \$opt_diff,
566 'swig:s' => \$opt_swig,
567 'dcom-proxy:s' => \$opt_dcom_proxy,
568 'com-header:s' => \$opt_com_header,
569 'quiet' => \$opt_quiet,
570 'verbose' => \$opt_verbose,
571 'warn-compat' => \$opt_warn_compat
574 if (not $result) {
575 exit(1);
578 if ($opt_help) {
579 ShowHelp();
580 exit(0);
583 if ($opt_samba3_client and $opt_samba3_ndr_client) {
584 print "--samba3-client and --samba3-ndr-client can not be used together\n";
585 exit(1);
588 sub process_file($)
590 my $idl_file = shift;
591 my $outputdir = $opt_outputdir;
592 my $pidl;
593 my $ndr;
595 my $basename = basename($idl_file, ".idl");
597 unless ($opt_quiet) { print "Compiling $idl_file\n"; }
599 if ($opt_parse_idl_tree) {
600 $pidl = LoadStructure($idl_file);
601 defined $pidl || die "Failed to load $idl_file";
602 } else {
603 require Parse::Pidl::IDL;
605 $pidl = Parse::Pidl::IDL::parse_file($idl_file);
606 defined @$pidl || die "Failed to parse $idl_file";
607 require Parse::Pidl::Typelist;
608 Parse::Pidl::Typelist::LoadIdl($pidl);
611 if (defined($opt_dump_idl_tree)) {
612 my($pidl_file) = ($opt_dump_idl_tree or "$outputdir/$basename.pidl");
613 SaveStructure($pidl_file, $pidl) or die "Failed to save $pidl_file\n";
616 if ($opt_uint_enums) {
617 Parse::Pidl::Util::setUseUintEnums(1);
620 if ($opt_dump_idl) {
621 require Parse::Pidl::Dump;
622 print Parse::Pidl::Dump($pidl);
625 if ($opt_diff) {
626 my($tempfile) = "$outputdir/$basename.tmp";
627 FileSave($tempfile, IdlDump::Dump($pidl));
628 system("diff -wu $idl_file $tempfile");
629 unlink($tempfile);
633 my $comh_filename = ($opt_com_header or "$outputdir/com_$basename.h");
634 if (defined($opt_com_header)) {
635 require Parse::Pidl::Samba4::COM::Header;
636 my $res = Parse::Pidl::Samba4::COM::Header::Parse($pidl,"$outputdir/ndr_$basename.h");
637 if ($res) {
638 FileSave($comh_filename, $res);
642 if (defined($opt_dcom_proxy)) {
643 require Parse::Pidl::Samba4::COM::Proxy;
644 my $res = Parse::Pidl::Samba4::COM::Proxy::Parse($pidl,$comh_filename);
645 if ($res) {
646 my ($client) = ($opt_dcom_proxy or "$outputdir/$basename\_p.c");
647 FileSave($client, $res);
651 if ($opt_warn_compat) {
652 require Parse::Pidl::Compat;
653 Parse::Pidl::Compat::Check($pidl);
656 $pidl = Parse::Pidl::ODL::ODL2IDL($pidl);
658 if (defined($opt_ws_parser) or
659 defined($opt_client) or defined($opt_server) or
660 defined($opt_ndr_parser) or defined($opt_ejs) or
661 defined($opt_dump_ndr_tree) or defined($opt_samba3_header) or
662 defined($opt_samba3_parser) or defined($opt_samba3_server) or
663 defined($opt_samba3_template) or defined($opt_samba3_client) or
664 defined($opt_swig) or defined($opt_samba3_ndr_client)) {
665 require Parse::Pidl::NDR;
666 $ndr = Parse::Pidl::NDR::Parse($pidl);
669 if (defined($opt_dump_ndr_tree)) {
670 my($ndr_file) = ($opt_dump_ndr_tree or "$outputdir/$basename.ndr");
671 SaveStructure($ndr_file, $ndr) or die "Failed to save $ndr_file\n";
674 my $gen_header = ($opt_header or "$outputdir/$basename.h");
675 if (defined($opt_header)) {
676 require Parse::Pidl::Samba4::Header;
677 FileSave($gen_header, Parse::Pidl::Samba4::Header::Parse($pidl));
680 my $h_filename = "$outputdir/ndr_$basename.h";
681 if (defined($opt_client)) {
682 require Parse::Pidl::Samba4::NDR::Client;
683 my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c");
684 my ($c_header) = $c_client;
685 $c_header =~ s/\.c$/.h/;
687 my ($srcd,$hdrd) = Parse::Pidl::Samba4::NDR::Client::Parse(
688 $ndr,$gen_header,$h_filename,$c_header);
690 FileSave($c_client, $srcd);
691 FileSave($c_header, $hdrd);
694 if (defined($opt_swig)) {
695 require Parse::Pidl::Samba4::SWIG;
696 my($filename) = ($opt_swig or "$outputdir/$basename.i");
697 my $code = Parse::Pidl::Samba4::SWIG::Parse($ndr, $basename, "$outputdir/ndr_$basename\_c.h", $gen_header);
698 FileSave($filename, $code);
701 if (defined($opt_ejs)) {
702 require Parse::Pidl::Samba4::EJS;
703 my ($hdr,$prsr) = Parse::Pidl::Samba4::EJS::Parse($ndr, $h_filename);
704 FileSave("$outputdir/ndr_$basename\_ejs.c", $prsr);
705 FileSave("$outputdir/ndr_$basename\_ejs.h", $hdr);
708 if (defined($opt_server)) {
709 require Parse::Pidl::Samba4::NDR::Server;
710 my $dcom = "";
712 foreach (@{$pidl}) {
713 next if ($_->{TYPE} ne "INTERFACE");
715 if (Parse::Pidl::Util::has_property($_, "object")) {
716 require Parse::Pidl::Samba4::COM::Stub;
717 $dcom .= Parse::Pidl::Samba4::COM::Stub::ParseInterface($_);
721 FileSave(($opt_server or "$outputdir/ndr_$basename\_s.c"), Parse::Pidl::Samba4::NDR::Server::Parse($ndr,$h_filename));
723 if ($dcom ne "") {
724 $dcom = "
725 #include \"includes.h\"
726 #include \"$h_filename\"
727 #include \"rpc_server/dcerpc_server.h\"
728 #include \"rpc_server/common/common.h\"
730 $dcom
732 FileSave("$outputdir/$basename\_d.c", $dcom);
736 if (defined($opt_ndr_parser)) {
737 my $parser_fname = ($opt_ndr_parser or "$outputdir/ndr_$basename.c");
738 require Parse::Pidl::Samba4::NDR::Parser;
739 my ($header,$parser) = Parse::Pidl::Samba4::NDR::Parser::Parse($ndr, $gen_header, $h_filename);
742 FileSave($parser_fname, $parser);
743 FileSave($h_filename, $header);
747 if (defined($opt_ws_parser)) {
748 require Parse::Pidl::Wireshark::NDR;
749 my($eparser) = ($opt_ws_parser or "$outputdir/packet-dcerpc-$basename.c");
750 my $eheader = $eparser;
751 $eheader =~ s/\.c$/\.h/;
752 my $cnffile = $idl_file;
753 $cnffile =~ s/\.idl$/\.cnf/;
755 my ($dp, $dh) = Parse::Pidl::Wireshark::NDR::Parse($ndr, $idl_file, $eheader, $cnffile);
756 FileSave($eparser, $dp) if defined($dp);
757 FileSave($eheader, $dh) if defined($dh);
760 if (defined($opt_tdr_parser)) {
761 my $tdr_parser = ($opt_tdr_parser or "$outputdir/tdr_$basename.c");
762 my $tdr_header = $tdr_parser;
763 $tdr_header =~ s/\.c$/\.h/;
764 require Parse::Pidl::Samba4::TDR;
765 my ($hdr,$prsr) = Parse::Pidl::Samba4::TDR::Parser($pidl, $tdr_header, $gen_header);
766 FileSave($tdr_parser, $prsr);
767 FileSave($tdr_header, $hdr);
770 if ($opt_template) {
771 require Parse::Pidl::Samba4::Template;
772 print Parse::Pidl::Samba4::Template::Parse($pidl);
775 if (defined($opt_samba3_header) or defined($opt_samba3_parser) or
776 defined($opt_samba3_server) or defined($opt_samba3_client) or
777 defined($opt_samba3_ndr_client) or defined($opt_samba3_template)) {
778 require Parse::Pidl::Samba3::Types;
779 Parse::Pidl::Samba3::Types::LoadTypes($ndr);
782 if (defined($opt_samba3_header)) {
783 my $header = ($opt_samba3_header or "$outputdir/rpc_$basename.h");
784 require Parse::Pidl::Samba3::Header;
785 FileSave($header, Parse::Pidl::Samba3::Header::Parse($ndr, $basename));
788 if (defined($opt_samba3_parser)) {
789 my $header = ($opt_samba3_parser or "$outputdir/parse_$basename.c");
790 require Parse::Pidl::Samba3::Parser;
791 FileSave($header, Parse::Pidl::Samba3::Parser::Parse($ndr, $basename));
794 if (defined($opt_samba3_server)) {
795 my $header = ($opt_samba3_server or "$outputdir/srv_$basename.c");
796 require Parse::Pidl::Samba3::Server;
797 FileSave($header, Parse::Pidl::Samba3::Server::Parse($ndr, $basename));
800 if (defined($opt_samba3_template)) {
801 my $header = ($opt_samba3_template or "$outputdir/srv_$basename\_nt.c");
802 require Parse::Pidl::Samba3::Template;
803 FileSave($header, Parse::Pidl::Samba3::Template::Parse($ndr, $basename));
806 if (defined($opt_samba3_client)) {
807 my $header = ($opt_samba3_client or "$outputdir/cli_$basename.c");
808 require Parse::Pidl::Samba3::Client;
809 FileSave($header, Parse::Pidl::Samba3::Client::Parse($ndr, $basename));
812 if (defined($opt_samba3_ndr_client)) {
813 my $client = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c");
814 my $header = $client; $header =~ s/\.c$/\.h/;
815 require Parse::Pidl::Samba3::ClientNDR;
816 my ($c_code,$h_code) = Parse::Pidl::Samba3::ClientNDR::Parse($ndr, $header, $h_filename);
817 FileSave($client, $c_code);
818 FileSave($header, $h_code);
824 if (scalar(@ARGV) == 0) {
825 print "pidl: no input files\n";
826 exit(1);
829 process_file($_) foreach (@ARGV);