~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to pidl/pidl

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w
 
2
 
 
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-2007
 
8
# released under the GNU GPL
 
9
 
 
10
=pod
 
11
 
 
12
=head1 NAME
 
13
 
 
14
pidl - An IDL compiler written in Perl
 
15
 
 
16
=head1 SYNOPSIS
 
17
 
 
18
pidl --help
 
19
 
 
20
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]...
 
21
 
 
22
=head1 DESCRIPTION
 
23
 
 
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".
 
27
 
 
28
pidl can generate stubs for DCE/RPC server code, DCE/RPC 
 
29
client code and Wireshark dissectors for DCE/RPC traffic.
 
30
 
 
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. 
 
38
 
 
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.
 
43
 
 
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).
 
47
 
 
48
=head1 OPTIONS
 
49
 
 
50
=over 4
 
51
 
 
52
=item I<--help>
 
53
 
 
54
Show list of available options.
 
55
 
 
56
=item I<--version>
 
57
 
 
58
Show pidl version
 
59
                
 
60
=item I<--outputdir OUTNAME>
 
61
 
 
62
Write output files to the specified directory.  Defaults to the current 
 
63
directory.
 
64
 
 
65
=item I<--includedir DIR>
 
66
 
 
67
Add DIR to the search path used by the preprocessor. This option can be 
 
68
specified multiple times.
 
69
                
 
70
=item I<--parse-idl-tree>
 
71
 
 
72
Read internal tree structure from input files rather 
 
73
than assuming they contain IDL.
 
74
 
 
75
=item I<--dump-idl>
 
76
 
 
77
Generate a new IDL file. File will be named OUTNAME.idl.
 
78
 
 
79
=item I<--header>
 
80
 
 
81
Generate a C header file for the specified interface. Filename defaults to OUTNAME.h.
 
82
 
 
83
=item I<--ndr-parser>
 
84
 
 
85
Generate a C file and C header containing NDR parsers. The filename for 
 
86
the parser defaults to ndr_OUTNAME.c. The header filename will be the 
 
87
parser filename with the extension changed from .c to .h.
 
88
 
 
89
=item I<--tdr-parser>
 
90
 
 
91
Generate a C file and C header containing TDR parsers. The filename for 
 
92
the parser defaults to tdr_OUTNAME.c. The header filename will be the 
 
93
parser filename with the extension changed from .c to .h.
 
94
 
 
95
=item I<--typelib>
 
96
 
 
97
Write type information to the specified file.
 
98
 
 
99
=item I<--server>
 
100
 
 
101
Generate boilerplate for the RPC server that implements 
 
102
the interface. Filename defaults to ndr_OUTNAME_s.c.
 
103
 
 
104
=item I<--template>
 
105
 
 
106
Generate stubs for a RPC server that implements the interface. Output will 
 
107
be written to stdout.
 
108
 
 
109
=item I<--ws-parser>
 
110
 
 
111
Generate an Wireshark dissector (in C) and header file. The dissector filename
 
112
defaults to packet-dcerpc-OUTNAME.c while the header filename defaults to 
 
113
packet-dcerpc-OUTNAME.h.
 
114
        
 
115
Pidl will read additional data from an Wireshark conformance file if present. 
 
116
Such a file should have the same location as the IDL file but with the 
 
117
extension I<cnf> rather than I<idl>. See L<Parse::Pidl::Wireshark::Conformance>
 
118
for details on the format of this file.
 
119
 
 
120
=item I<--diff>
 
121
 
 
122
Parse an IDL file,  generate a new IDL file based on the internal data 
 
123
structures and see if there are any differences with the original IDL file. 
 
124
Useful for debugging pidl.
 
125
 
 
126
=item I<--dump-idl-tree>
 
127
 
 
128
Tell pidl to dump the internal tree representation of an IDL 
 
129
file the to disk. Useful for debugging pidl.
 
130
 
 
131
=item I<--dump-ndr-tree>
 
132
 
 
133
Tell pidl to dump the internal NDR information tree it generated 
 
134
from the IDL file to disk.  Useful for debugging pidl.
 
135
 
 
136
=item I<--samba3-ndr-client>
 
137
 
 
138
Generate client calls for Samba3, to be placed in rpc_client/. Instead of 
 
139
calling out to the code in Samba3's rpc_parse/, this will call out to 
 
140
Samba4's NDR code instead.
 
141
 
 
142
=item I<--samba3-ndr-server>
 
143
 
 
144
Generate server calls for Samba3, to be placed in rpc_server/. Instead of 
 
145
calling out to the code in Samba3's rpc_parse/, this will call out to 
 
146
Samba4's NDR code instead.
 
147
 
 
148
=back
 
149
 
 
150
=head1 IDL SYNTAX
 
151
 
 
152
IDL files are always preprocessed using the C preprocessor.
 
153
 
 
154
Pretty much everything in an interface (the interface itself, functions, 
 
155
parameters) can have attributes (or properties whatever name you give them). 
 
156
Attributes always prepend the element they apply to and are surrounded 
 
157
by square brackets ([]). Multiple attributes are separated by comma's; 
 
158
arguments to attributes are specified between parentheses. 
 
159
 
 
160
See the section COMPATIBILITY for the list of attributes that 
 
161
pidl supports.
 
162
 
 
163
C-style comments can be used.
 
164
        
 
165
=head2 CONFORMANT ARRAYS
 
166
 
 
167
A conformant array is one with that ends in [*] or []. The strange
 
168
things about conformant arrays are that they can only appear as the last 
 
169
element of a structure (unless there is a pointer to the conformant array, 
 
170
of course) and the array size appears before the structure itself on the wire. 
 
171
 
 
172
So, in this example:
 
173
 
 
174
        typedef struct {
 
175
                long abc;
 
176
                long count;     
 
177
                long foo;
 
178
                [size_is(count)] long s[*];
 
179
        } Struct1;
 
180
 
 
181
it appears like this:
 
182
 
 
183
        [size_is] [abc] [count] [foo] [s...]
 
184
 
 
185
the first [size_is] field is the allocation size of the array, and
 
186
occurs before the array elements and even before the structure
 
187
alignment.
 
188
 
 
189
Note that size_is() can refer to a constant, but that doesn't change
 
190
the wire representation. It does not make the array a fixed array.
 
191
 
 
192
midl.exe would write the above array as the following C header:
 
193
 
 
194
   typedef struct {
 
195
                long abc;
 
196
                long count;     
 
197
                long foo;
 
198
                long s[1];
 
199
        } Struct1;
 
200
 
 
201
pidl takes a different approach, and writes it like this:
 
202
 
 
203
    typedef struct {
 
204
                long abc;
 
205
                long count;     
 
206
                long foo;
 
207
                long *s;
 
208
        } Struct1;
 
209
 
 
210
=head2 VARYING ARRAYS
 
211
 
 
212
A varying array looks like this:
 
213
 
 
214
        typedef struct {
 
215
                long abc;
 
216
                long count;     
 
217
                long foo;
 
218
                [size_is(count)] long *s;
 
219
        } Struct1;
 
220
 
 
221
This will look like this on the wire:
 
222
 
 
223
        [abc] [count] [foo] [PTR_s]    [count] [s...]
 
224
 
 
225
=head2 FIXED ARRAYS
 
226
 
 
227
A fixed array looks like this:
 
228
 
 
229
    typedef struct {
 
230
            long s[10];
 
231
    } Struct1;
 
232
 
 
233
The NDR representation looks just like 10 separate long
 
234
declarations. The array size is not encoded on the wire.
 
235
 
 
236
pidl also supports "inline" arrays, which are not part of the IDL/NDR
 
237
standard. These are declared like this:
 
238
 
 
239
    typedef struct {
 
240
            uint32 foo;
 
241
            uint32 count;
 
242
            uint32 bar;
 
243
            long s[count];
 
244
    } Struct1;
 
245
 
 
246
This appears like this:
 
247
 
 
248
        [foo] [count] [bar] [s...]
 
249
 
 
250
Fixed arrays are an extension added to support some of the strange
 
251
embedded structures in security descriptors and spoolss. 
 
252
 
 
253
This section is by no means complete. See the OpenGroup and MSDN 
 
254
        documentation for additional information.
 
255
 
 
256
=head1 COMPATIBILITY WITH MIDL
 
257
 
 
258
=head2 Missing features in pidl
 
259
 
 
260
The following MIDL features are not (yet) implemented in pidl 
 
261
or are implemented with an incompatible interface:
 
262
 
 
263
=over
 
264
 
 
265
=item *
 
266
 
 
267
Asynchronous communication
 
268
 
 
269
=item * 
 
270
 
 
271
Typelibs (.tlb files)
 
272
 
 
273
=item *
 
274
 
 
275
Datagram support (ncadg_*)
 
276
 
 
277
=back
 
278
 
 
279
=head2 Supported attributes and statements
 
280
 
 
281
in, out, ref, length_is, switch_is, size_is, uuid, case, default, string, 
 
282
unique, ptr, pointer_default, v1_enum, object, helpstring, range, local, 
 
283
call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as, 
 
284
transmit_as, import, include, cpp_quote.
 
285
 
 
286
=head2 PIDL Specific properties
 
287
 
 
288
=over 4
 
289
 
 
290
=item public
 
291
 
 
292
The [public] property on a structure or union is a pidl extension that
 
293
forces the generated pull/push functions to be non-static. This allows
 
294
you to declare types that can be used between modules. If you don't
 
295
specify [public] then pull/push functions for other than top-level
 
296
functions are declared static.
 
297
                                
 
298
=item noprint
 
299
 
 
300
The [noprint] property is a pidl extension that allows you to specify
 
301
that pidl should not generate a ndr_print_*() function for that
 
302
structure or union. This is used when you wish to define your own
 
303
print function that prints a structure in a nicer manner. A good
 
304
example is the use of [noprint] on dom_sid, which allows the
 
305
pretty-printing of SIDs.
 
306
 
 
307
=item value
 
308
 
 
309
The [value(expression)] property is a pidl extension that allows you
 
310
to specify the value of a field when it is put on the wire. This
 
311
allows fields that always have a well-known value to be automatically
 
312
filled in, thus making the API more programmer friendly. The
 
313
expression can be any C expression.
 
314
 
 
315
=item relative
 
316
 
 
317
The [relative] property can be supplied on a pointer. When it is used
 
318
it declares the pointer as a spoolss style "relative" pointer, which
 
319
means it appears on the wire as an offset within the current
 
320
encapsulating structure. This is not part of normal IDL/NDR, but it is
 
321
a very useful extension as it avoids the manual encoding of many
 
322
complex structures.
 
323
 
 
324
=item subcontext(length)
 
325
 
 
326
Specifies that a size of I<length>
 
327
bytes should be read, followed by a blob of that size, 
 
328
which will be parsed as NDR.
 
329
 
 
330
subcontext() is deprecated now, and should not be used in new code. 
 
331
Instead, use represent_as() or transmit_as().
 
332
 
 
333
=item flag
 
334
 
 
335
Specify boolean options, mostly used for 
 
336
low-level NDR options. Several options 
 
337
can be specified using the | character.
 
338
Note that flags are inherited by substructures!
 
339
 
 
340
=item nodiscriminant
 
341
 
 
342
The [nodiscriminant] property on a union means that the usual uint16
 
343
discriminent field at the start of the union on the wire is
 
344
omitted. This is not normally allowed in IDL/NDR, but is used for some
 
345
spoolss structures.
 
346
 
 
347
=item charset(name)
 
348
 
 
349
Specify that the array or string uses the specified 
 
350
charset. If this attribute is specified, pidl will 
 
351
take care of converting the character data from this format 
 
352
to the host format. Commonly used values are UCS2, DOS and UTF8.
 
353
 
 
354
=back
 
355
 
 
356
=head2 Unsupported MIDL properties or statements
 
357
 
 
358
aggregatable, appobject, async_uuid, bindable, control, 
 
359
defaultbind, defaultcollelem, defaultvalue, defaultvtable, dispinterface, 
 
360
displaybind, dual, entry, first_is, helpcontext, helpfile, helpstringcontext, 
 
361
helpstringdll, hidden, idl_module, idl_quote, id, immediatebind, importlib, 
 
362
includelib, last_is, lcid, licensed, max_is, module, 
 
363
ms_union, no_injected_text, nonbrowsable, noncreatable, nonextensible, odl, 
 
364
oleautomation, optional, pragma, propget, propputref, propput, readonly, 
 
365
requestedit, restricted, retval, source, uidefault, 
 
366
usesgetlasterror, vararg, vi_progid, wire_marshal. 
 
367
 
 
368
=head1 EXAMPLES
 
369
 
 
370
        # Generating an Wireshark parser
 
371
        $ ./pidl --ws-parser -- atsvc.idl
 
372
        
 
373
        # Generating a TDR parser and header
 
374
        $ ./pidl --tdr-parser --header -- regf.idl
 
375
 
 
376
        # Generating a Samba3 client and server
 
377
        $ ./pidl --samba3-ndr-client --samba3-ndr-server -- dfs.idl
 
378
 
 
379
        # Generating a Samba4 NDR parser, client and server
 
380
        $ ./pidl --ndr-parser --ndr-client --ndr-server -- samr.idl
 
381
 
 
382
=head1 SEE ALSO
 
383
 
 
384
L<http://msdn.microsoft.com/library/en-us/rpc/rpc/field_attributes.asp>,
 
385
L<http://wiki.wireshark.org/DCE/RPC>, 
 
386
L<http://www.samba.org/>,
 
387
L<yapp(1)>
 
388
 
 
389
=head1 LICENSE
 
390
 
 
391
pidl is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>.
 
392
 
 
393
=head1 AUTHOR
 
394
 
 
395
pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim Potter and Jelmer 
 
396
Vernooij. The current maintainer is Jelmer Vernooij.
 
397
 
 
398
This manpage was written by Jelmer Vernooij, partially based on the original 
 
399
pidl README by Andrew Tridgell. 
 
400
        
 
401
=cut
 
402
 
 
403
 
 
404
use strict;
 
405
use FindBin qw($RealBin $Script);
 
406
use lib "$RealBin/lib";
 
407
use lib "$RealBin/../share/perl5";
 
408
use Getopt::Long;
 
409
use File::Basename;
 
410
use Parse::Pidl qw ( $VERSION );
 
411
use Parse::Pidl::Util;
 
412
use Parse::Pidl::ODL;
 
413
 
 
414
#####################################################################
 
415
# save a data structure into a file
 
416
sub SaveStructure($$)
 
417
{
 
418
        my($filename,$v) = @_;
 
419
        FileSave($filename, Parse::Pidl::Util::MyDumper($v));
 
420
}
 
421
 
 
422
#####################################################################
 
423
# load a data structure from a file (as saved with SaveStructure)
 
424
sub LoadStructure($)
 
425
{
 
426
        my $f = shift;
 
427
        my $contents = FileLoad($f);
 
428
        defined $contents || return undef;
 
429
        return eval "$contents";
 
430
}
 
431
 
 
432
#####################################################################
 
433
# read a file into a string
 
434
sub FileLoad($)
 
435
{
 
436
    my($filename) = shift;
 
437
    local(*INPUTFILE);
 
438
    open(INPUTFILE, $filename) || return undef;
 
439
    my($saved_delim) = $/;
 
440
    undef $/;
 
441
    my($data) = <INPUTFILE>;
 
442
    close(INPUTFILE);
 
443
    $/ = $saved_delim;
 
444
    return $data;
 
445
}
 
446
 
 
447
#####################################################################
 
448
# write a string into a file
 
449
sub FileSave($$)
 
450
{
 
451
    my($filename) = shift;
 
452
    my($v) = shift;
 
453
    local(*FILE);
 
454
    open(FILE, ">$filename") || die "can't open $filename";    
 
455
    print FILE $v;
 
456
    close(FILE);
 
457
}
 
458
 
 
459
my(@opt_incdirs) = (); 
 
460
my($opt_help) = 0;
 
461
my($opt_version) = 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_diff) = 0;
 
467
my($opt_header);
 
468
my($opt_samba3_header);
 
469
my($opt_samba3_parser);
 
470
my($opt_samba3_server);
 
471
my($opt_samba3_ndr_client);
 
472
my($opt_samba3_ndr_server);
 
473
my($opt_template) = 0;
 
474
my($opt_client);
 
475
my($opt_typelib);
 
476
my($opt_server);
 
477
my($opt_ndr_parser);
 
478
my($opt_tdr_parser);
 
479
my($opt_ws_parser);
 
480
my($opt_python);
 
481
my($opt_quiet) = 0;
 
482
my($opt_outputdir) = '.';
 
483
my($opt_verbose) = 0;
 
484
my($opt_warn_compat) = 0;
 
485
my($opt_dcom_proxy);
 
486
my($opt_com_header);
 
487
 
 
488
#########################################
 
489
# display help text
 
490
sub ShowHelp()
 
491
{
 
492
print "perl IDL parser and code generator\n";
 
493
ShowVersion();
 
494
print"
 
495
Copyright (C) Andrew Tridgell <tridge\@samba.org>
 
496
Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
 
497
 
 
498
Usage: $Script [options] [--] <idlfile> [<idlfile>...]
 
499
 
 
500
Generic Options:
 
501
 --help                  this help page
 
502
 --version               show pidl version
 
503
 --outputdir=OUTDIR      put output in OUTDIR/ [.]
 
504
 --warn-compat           warn about incompatibility with other compilers
 
505
 --quiet                 be quiet
 
506
 --verbose               be verbose
 
507
 --includedir DIR        search DIR for included files
 
508
 
 
509
Debugging:
 
510
 --dump-idl-tree[=FILE]  dump internal representation to file [BASENAME.pidl]
 
511
 --parse-idl-tree        read internal representation instead of IDL
 
512
 --dump-ndr-tree[=FILE]  dump internal NDR data tree to file [BASENAME.ndr]
 
513
 --dump-idl              regenerate IDL file
 
514
 --diff                  run diff on original IDL and dumped output
 
515
 --typelib               print type information
 
516
 
 
517
Samba 4 output:
 
518
 --header[=OUTFILE]      create generic header file [BASENAME.h]
 
519
 --ndr-parser[=OUTFILE]  create a C NDR parser [ndr_BASENAME.c]
 
520
 --client[=OUTFILE]      create a C NDR client [ndr_BASENAME_c.c]
 
521
 --tdr-parser[=OUTFILE]  create a C TDR parser [tdr_BASENAME.c]
 
522
 --python[=OUTFILE]      create python wrapper file [py_BASENAME.c]
 
523
 --server[=OUTFILE]      create server boilerplate [ndr_BASENAME_s.c]
 
524
 --template              print a template for a pipe
 
525
 --dcom-proxy[=OUTFILE]  create DCOM proxy [ndr_BASENAME_p.c]
 
526
 --com-header[=OUTFILE]  create header for COM [com_BASENAME.h]
 
527
 
 
528
Samba 3 output:
 
529
 --samba3-ndr-client[=OUTF] create client calls for Samba3 
 
530
                            using Samba4's NDR code [cli_BASENAME.c]
 
531
 --samba3-ndr-server[=OUTF] create server call wrapper for Samba3 
 
532
                            using Samba4's NDR code [srv_BASENAME.c]
 
533
 
 
534
Wireshark parsers:
 
535
 --ws-parser[=OUTFILE]  create Wireshark parser and header
 
536
\n";
 
537
    exit(0);
 
538
}
 
539
 
 
540
#########################################
 
541
# Display version
 
542
sub ShowVersion()
 
543
{
 
544
    print "perl IDL version $VERSION\n";
 
545
}
 
546
 
 
547
# main program
 
548
my $result = GetOptions (
 
549
            'help|h|?' => \$opt_help, 
 
550
            'version' => \$opt_version,
 
551
            'outputdir=s' => \$opt_outputdir,
 
552
            'dump-idl' => \$opt_dump_idl,
 
553
                'dump-idl-tree:s' => \$opt_dump_idl_tree,
 
554
                'parse-idl-tree' => \$opt_parse_idl_tree,
 
555
                'dump-ndr-tree:s' => \$opt_dump_ndr_tree,
 
556
                'samba3-ndr-client:s' => \$opt_samba3_ndr_client,
 
557
                'samba3-ndr-server:s' => \$opt_samba3_ndr_server,
 
558
                'header:s' => \$opt_header,
 
559
            'server:s' => \$opt_server,
 
560
                'typelib:s' => \$opt_typelib,
 
561
            'tdr-parser:s' => \$opt_tdr_parser,
 
562
            'template' => \$opt_template,
 
563
            'ndr-parser:s' => \$opt_ndr_parser,
 
564
            'client:s' => \$opt_client,
 
565
            'ws-parser:s' => \$opt_ws_parser,
 
566
                'python' => \$opt_python,
 
567
            'diff' => \$opt_diff,
 
568
        'dcom-proxy:s' => \$opt_dcom_proxy,
 
569
                'com-header:s' => \$opt_com_header,
 
570
            'quiet' => \$opt_quiet,
 
571
                'verbose' => \$opt_verbose,
 
572
            'warn-compat' => \$opt_warn_compat,
 
573
                'includedir=s@' => \@opt_incdirs
 
574
            );
 
575
 
 
576
if (not $result) {
 
577
        exit(1);
 
578
}
 
579
 
 
580
if ($opt_help) {
 
581
    ShowHelp();
 
582
    exit(0);
 
583
}
 
584
 
 
585
if ($opt_version) {
 
586
    ShowVersion();
 
587
    exit(0);
 
588
}
 
589
 
 
590
sub process_file($)
 
591
{
 
592
        my $idl_file = shift;
 
593
        my $outputdir = $opt_outputdir;
 
594
        my $pidl;
 
595
        my $ndr;
 
596
 
 
597
        my $basename = basename($idl_file, ".idl");
 
598
 
 
599
        unless ($opt_quiet) { print "Compiling $idl_file\n"; }
 
600
 
 
601
        if ($opt_parse_idl_tree) {
 
602
                $pidl = LoadStructure($idl_file);
 
603
                defined $pidl || die "Failed to load $idl_file";
 
604
        } else {
 
605
                require Parse::Pidl::IDL;
 
606
 
 
607
                $pidl = Parse::Pidl::IDL::parse_file($idl_file, \@opt_incdirs);
 
608
                defined @$pidl || die "Failed to parse $idl_file";
 
609
        }
 
610
 
 
611
        require Parse::Pidl::Typelist;
 
612
        Parse::Pidl::Typelist::LoadIdl($pidl, $basename);
 
613
 
 
614
        if (defined($opt_dump_idl_tree)) {
 
615
                my($pidl_file) = ($opt_dump_idl_tree or "$outputdir/$basename.pidl");
 
616
                SaveStructure($pidl_file, $pidl) or die "Failed to save $pidl_file\n";
 
617
        }
 
618
 
 
619
        if ($opt_dump_idl) {
 
620
                require Parse::Pidl::Dump;
 
621
                print Parse::Pidl::Dump($pidl);
 
622
        }
 
623
 
 
624
        if ($opt_diff) {
 
625
                my($tempfile) = "$outputdir/$basename.tmp";
 
626
                FileSave($tempfile, IdlDump::Dump($pidl));
 
627
                system("diff -wu $idl_file $tempfile");
 
628
                unlink($tempfile);
 
629
        }
 
630
 
 
631
        my $comh_filename = ($opt_com_header or "$outputdir/com_$basename.h");
 
632
        if (defined($opt_com_header)) {
 
633
                require Parse::Pidl::Samba4::COM::Header;
 
634
                my $res = Parse::Pidl::Samba4::COM::Header::Parse($pidl,"$outputdir/ndr_$basename.h");
 
635
                if ($res) {
 
636
                        FileSave($comh_filename, $res);
 
637
                }
 
638
        }
 
639
 
 
640
        if (defined($opt_dcom_proxy)) {
 
641
                require Parse::Pidl::Samba4::COM::Proxy;
 
642
                my $res = Parse::Pidl::Samba4::COM::Proxy::Parse($pidl,$comh_filename);
 
643
                if ($res) {
 
644
                        my ($client) = ($opt_dcom_proxy or "$outputdir/$basename\_p.c");
 
645
                        FileSave($client, $res);
 
646
                }
 
647
        }
 
648
 
 
649
        if ($opt_warn_compat) {
 
650
                require Parse::Pidl::Compat;
 
651
                Parse::Pidl::Compat::Check($pidl);
 
652
        }
 
653
 
 
654
        $pidl = Parse::Pidl::ODL::ODL2IDL($pidl, dirname($idl_file), \@opt_incdirs);
 
655
 
 
656
        if (defined($opt_ws_parser) or 
 
657
            defined($opt_client) or
 
658
            defined($opt_server) or 
 
659
            defined($opt_header) or
 
660
            defined($opt_ndr_parser) or
 
661
            defined($opt_python) or 
 
662
            defined($opt_dump_ndr_tree) or
 
663
            defined($opt_samba3_header) or 
 
664
            defined($opt_samba3_parser) or 
 
665
            defined($opt_samba3_server) or 
 
666
            defined($opt_samba3_ndr_client) or
 
667
            defined($opt_samba3_ndr_server)) {
 
668
                require Parse::Pidl::NDR;
 
669
                $ndr = Parse::Pidl::NDR::Parse($pidl);
 
670
        }
 
671
 
 
672
        if (defined($opt_dump_ndr_tree)) {
 
673
                my($ndr_file) = ($opt_dump_ndr_tree or "$outputdir/$basename.ndr");
 
674
                SaveStructure($ndr_file, $ndr) or die "Failed to save $ndr_file\n";
 
675
        }
 
676
 
 
677
        my $gen_header = ($opt_header or "$outputdir/$basename.h");
 
678
        if (defined($opt_header)) {
 
679
                require Parse::Pidl::Samba4::Header;
 
680
                FileSave($gen_header, Parse::Pidl::Samba4::Header::Parse($ndr));
 
681
        }
 
682
 
 
683
        my $h_filename = "$outputdir/ndr_$basename.h";
 
684
        if (defined($opt_client)) {
 
685
                require Parse::Pidl::Samba4::NDR::Client;
 
686
                my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c");
 
687
                my ($c_header) = $c_client;
 
688
                $c_header =~ s/\.c$/.h/;
 
689
 
 
690
                my ($srcd,$hdrd) = Parse::Pidl::Samba4::NDR::Client::Parse(
 
691
                        $ndr,$gen_header,$h_filename,$c_header);
 
692
 
 
693
                FileSave($c_client, $srcd);
 
694
                FileSave($c_header, $hdrd);
 
695
        }
 
696
 
 
697
        if (defined($opt_python)) {
 
698
                require Parse::Pidl::Samba4::Python;
 
699
                my $generator = new Parse::Pidl::Samba4::Python(); 
 
700
                my ($prsr) = $generator->Parse($basename, $ndr, 
 
701
                                        "$outputdir/ndr_$basename\_c.h", $h_filename);
 
702
                FileSave("$outputdir/py_$basename.c", $prsr);
 
703
        }
 
704
 
 
705
        if (defined($opt_server)) {
 
706
                require Parse::Pidl::Samba4::NDR::Server;
 
707
 
 
708
                FileSave(($opt_server or "$outputdir/ndr_$basename\_s.c"), Parse::Pidl::Samba4::NDR::Server::Parse($ndr,$h_filename));
 
709
        }
 
710
 
 
711
        if (defined($opt_ndr_parser)) {
 
712
                my $parser_fname = ($opt_ndr_parser or "$outputdir/ndr_$basename.c");
 
713
                require Parse::Pidl::Samba4::NDR::Parser;
 
714
                my $generator = new Parse::Pidl::Samba4::NDR::Parser();
 
715
                my ($header,$parser) = $generator->Parse($ndr, $gen_header, $h_filename);
 
716
 
 
717
                FileSave($parser_fname, $parser);
 
718
                FileSave($h_filename, $header);
 
719
 
 
720
        }
 
721
 
 
722
        if (defined($opt_ws_parser)) {
 
723
          require Parse::Pidl::Wireshark::NDR;
 
724
          my($eparser) = ($opt_ws_parser or "$outputdir/packet-dcerpc-$basename.c");
 
725
          my $eheader = $eparser;
 
726
          $eheader =~ s/\.c$/\.h/;
 
727
          my $cnffile = $idl_file;
 
728
          $cnffile =~ s/\.idl$/\.cnf/;
 
729
 
 
730
          my $generator = new Parse::Pidl::Wireshark::NDR();
 
731
          my ($dp, $dh) = $generator->Parse($ndr, $idl_file, $eheader, $cnffile);
 
732
          FileSave($eparser, $dp) if defined($dp);
 
733
          FileSave($eheader, $dh) if defined($dh);
 
734
        }
 
735
 
 
736
        if (defined($opt_tdr_parser)) {
 
737
                my $tdr_parser = ($opt_tdr_parser or "$outputdir/tdr_$basename.c");
 
738
                my $tdr_header = $tdr_parser;
 
739
                $tdr_header =~ s/\.c$/\.h/;
 
740
                require Parse::Pidl::Samba4::TDR;
 
741
                my $generator = new Parse::Pidl::Samba4::TDR();
 
742
                my ($hdr,$prsr) = $generator->Parser($pidl, $tdr_header, $gen_header);
 
743
                FileSave($tdr_parser, $prsr);
 
744
                FileSave($tdr_header, $hdr);
 
745
        }
 
746
 
 
747
        if (defined($opt_typelib)) {
 
748
                my $typelib = ($opt_typelib or "$outputdir/$basename.tlb");
 
749
                require Parse::Pidl::Typelist;
 
750
                FileSave($typelib, Parse::Pidl::Typelist::GenerateTypeLib());
 
751
        }
 
752
 
 
753
        if ($opt_template) {
 
754
                require Parse::Pidl::Samba4::Template;
 
755
                print Parse::Pidl::Samba4::Template::Parse($pidl);
 
756
        }
 
757
 
 
758
        if (defined($opt_samba3_ndr_client)) {
 
759
                my $client = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c");
 
760
                my $header = $client; $header =~ s/\.c$/\.h/;
 
761
                require Parse::Pidl::Samba3::ClientNDR;
 
762
                my $generator = new Parse::Pidl::Samba3::ClientNDR();
 
763
                my ($c_code,$h_code) = $generator->Parse($ndr, $header, $h_filename);
 
764
                FileSave($client, $c_code);
 
765
                FileSave($header, $h_code);
 
766
        }
 
767
 
 
768
        if (defined($opt_samba3_ndr_server)) {
 
769
                my $server = ($opt_samba3_ndr_server or "$outputdir/srv_$basename.c");
 
770
                my $header = $server; $header =~ s/\.c$/\.h/;
 
771
                require Parse::Pidl::Samba3::ServerNDR;
 
772
                my ($c_code,$h_code) = Parse::Pidl::Samba3::ServerNDR::Parse($ndr, $header, $h_filename);
 
773
                FileSave($server, $c_code);
 
774
                FileSave($header, $h_code);
 
775
        }
 
776
 
 
777
}
 
778
 
 
779
if (scalar(@ARGV) == 0) {
 
780
        print "$Script: no input files\n";
 
781
        exit(1);
 
782
}
 
783
 
 
784
process_file($_) foreach (@ARGV);