2000-12-14 07:09:29 +03:00
#!/usr/bin/perl -w
###################################################
2004-05-09 11:10:12 +04:00
# package to parse IDL files and generate code for
2000-12-14 07:09:29 +03:00
# rpc functions in Samba
2003-11-28 03:48:05 +03:00
# Copyright tridge@samba.org 2000-2003
2000-12-14 07:09:29 +03:00
# released under the GNU GPL
use strict ;
2003-11-06 15:29:23 +03:00
2003-11-20 08:39:54 +03:00
use FindBin qw( $RealBin ) ;
use lib "$RealBin" ;
2003-11-22 04:40:24 +03:00
use lib "$RealBin/lib" ;
2000-12-14 07:09:29 +03:00
use Getopt::Long ;
2003-11-23 06:42:20 +03:00
use File::Basename ;
2003-11-20 07:36:09 +03:00
use idl ;
2000-12-14 07:09:29 +03:00
use dump ;
2005-03-06 15:33:44 +03:00
use ndr_client ;
2005-02-21 17:30:49 +03:00
use ndr_header ;
use ndr ;
2003-12-14 16:22:12 +03:00
use server ;
2005-02-21 17:30:49 +03:00
use dcom_proxy ;
use dcom_stub ;
use com_header ;
2005-02-21 04:16:47 +03:00
use odl ;
2001-11-25 02:35:58 +03:00
use eparser ;
2003-11-22 15:25:20 +03:00
use validator ;
2005-02-21 00:45:51 +03:00
use typelist ;
2000-12-14 07:09:29 +03:00
use util ;
2003-12-15 13:55:10 +03:00
use template ;
2004-09-08 15:54:01 +04:00
use swig ;
2000-12-14 07:09:29 +03:00
my ( $ opt_help ) = 0 ;
my ( $ opt_parse ) = 0 ;
my ( $ opt_dump ) = 0 ;
my ( $ opt_diff ) = 0 ;
2000-12-14 07:41:45 +03:00
my ( $ opt_header ) = 0 ;
2003-12-15 13:55:10 +03:00
my ( $ opt_template ) = 0 ;
2004-11-18 23:53:23 +03:00
my ( $ opt_client ) = 0 ;
2003-12-14 16:22:12 +03:00
my ( $ opt_server ) = 0 ;
2000-12-15 02:53:19 +03:00
my ( $ opt_parser ) = 0 ;
2001-11-25 02:35:58 +03:00
my ( $ opt_eparser ) = 0 ;
2003-11-08 16:24:14 +03:00
my ( $ opt_keep ) = 0 ;
2004-09-08 15:54:01 +04:00
my ( $ opt_swig ) = 0 ;
2005-02-21 17:30:49 +03:00
my ( $ opt_dcom_proxy ) = 0 ;
my ( $ opt_com_header ) = 0 ;
2005-02-21 04:16:47 +03:00
my ( $ opt_odl ) = 0 ;
2003-11-08 16:24:14 +03:00
my ( $ opt_output ) ;
2000-12-14 07:09:29 +03:00
2003-12-07 16:38:07 +03:00
my $ idl_parser = new idl ;
2000-12-14 07:09:29 +03:00
#####################################################################
# parse an IDL file returning a structure containing all the data
sub IdlParse ($)
{
2003-12-07 16:38:07 +03:00
my $ filename = shift ;
my $ idl = $ idl_parser - > parse_idl ( $ filename ) ;
2000-12-14 07:09:29 +03:00
util:: CleanData ( $ idl ) ;
return $ idl ;
}
#########################################
# display help text
sub ShowHelp ()
{
print "
2005-02-21 17:30:49 +03:00
perl IDL parser and code generator
Copyright ( C ) tridge \ @ samba . org
Usage: pidl . pl [ options ] <idlfile>
Options:
- - help this help page
- - output OUTNAME put output in OUTNAME . *
- - parse parse a idl file to a . pidl file
- - dump dump a pidl file back to idl
2005-03-06 15:33:44 +03:00
- - header create a C NDR header file
2005-02-21 17:30:49 +03:00
- - parser create a C NDR parser
2005-03-06 15:33:44 +03:00
- - client create a C NDR client
2005-02-21 17:30:49 +03:00
- - server create server boilerplate
- - template print a template for a pipe
- - eparser create an ethereal parser
- - swig create swig wrapper file
- - diff run diff on the idl and dumped output
- - keep keep the . pidl file
- - odl accept ODL input
- - dcom - proxy create DCOM proxy ( implies - - odl )
- - com - header create header for COM interfaces ( implies - - odl )
\ n " ;
2000-12-14 07:09:29 +03:00
exit ( 0 ) ;
}
# main program
GetOptions (
'help|h|?' = > \ $ opt_help ,
2003-11-08 16:24:14 +03:00
'output=s' = > \ $ opt_output ,
2000-12-14 07:09:29 +03:00
'parse' = > \ $ opt_parse ,
'dump' = > \ $ opt_dump ,
2000-12-14 07:41:45 +03:00
'header' = > \ $ opt_header ,
2003-12-14 16:22:12 +03:00
'server' = > \ $ opt_server ,
2003-12-15 13:55:10 +03:00
'template' = > \ $ opt_template ,
2000-12-15 02:53:19 +03:00
'parser' = > \ $ opt_parser ,
2004-11-18 23:53:23 +03:00
'client' = > \ $ opt_client ,
2001-11-25 02:35:58 +03:00
'eparser' = > \ $ opt_eparser ,
2003-11-08 16:24:14 +03:00
'diff' = > \ $ opt_diff ,
2005-02-21 04:16:47 +03:00
'odl' = > \ $ opt_odl ,
2004-09-08 15:54:01 +04:00
'keep' = > \ $ opt_keep ,
2005-02-21 17:30:49 +03:00
'swig' = > \ $ opt_swig ,
'dcom-proxy' = > \ $ opt_dcom_proxy ,
'com-header' = > \ $ opt_com_header
2000-12-14 07:09:29 +03:00
) ;
2000-12-14 07:41:45 +03:00
if ( $ opt_help ) {
ShowHelp ( ) ;
exit ( 0 ) ;
}
2003-11-23 06:42:20 +03:00
sub process_file ($)
{
my $ idl_file = shift ;
my $ output ;
2003-12-08 02:47:35 +03:00
my $ pidl ;
2003-11-23 06:42:20 +03:00
my $ basename = basename ( $ idl_file , ".idl" ) ;
if ( ! defined ( $ opt_output ) ) {
$ output = $ idl_file ;
} else {
$ output = $ opt_output . $ basename ;
}
2003-12-14 16:22:12 +03:00
my ( $ pidl_file ) = util:: ChangeExtension ( $ output , ".pidl" ) ;
2003-11-23 06:42:20 +03:00
2003-12-07 16:39:45 +03:00
print "Compiling $idl_file\n" ;
2003-11-23 06:42:20 +03:00
if ( $ opt_parse ) {
2003-12-08 02:47:35 +03:00
$ pidl = IdlParse ( $ idl_file ) ;
2004-10-02 10:32:53 +04:00
defined @$ pidl || die "Failed to parse $idl_file" ;
2005-03-06 20:02:14 +03:00
typelist:: LoadIdl ( $ pidl ) ;
2004-09-28 05:11:40 +04:00
IdlValidator:: Validate ( $ pidl ) ;
2003-12-08 02:47:35 +03:00
if ( $ opt_keep && ! util:: SaveStructure ( $ pidl_file , $ pidl ) ) {
die "Failed to save $pidl_file\n" ;
2004-05-09 11:10:12 +04:00
}
2003-12-08 02:47:35 +03:00
} else {
$ pidl = util:: LoadStructure ( $ pidl_file ) ;
2004-04-26 06:05:48 +04:00
defined $ pidl || die "Failed to load $pidl_file - maybe you need --parse\n" ;
2003-11-23 06:42:20 +03:00
}
2004-04-26 06:05:48 +04:00
2003-11-23 06:42:20 +03:00
if ( $ opt_dump ) {
2003-12-08 02:47:35 +03:00
print IdlDump:: Dump ( $ pidl ) ;
2003-11-23 06:42:20 +03:00
}
2004-05-09 11:10:12 +04:00
2005-02-21 17:30:49 +03:00
if ( $ opt_diff ) {
my ( $ tempfile ) = util:: ChangeExtension ( $ output , ".tmp" ) ;
util:: FileSave ( $ tempfile , IdlDump:: Dump ( $ pidl ) ) ;
system ( "diff -wu $idl_file $tempfile" ) ;
unlink ( $ tempfile ) ;
}
if ( $ opt_com_header ) {
my $ res = COMHeader:: Parse ( $ pidl ) ;
if ( $ res ) {
my $ h_filename = dirname ( $ output ) . "/com_$basename.h" ;
util:: FileSave ( $ h_filename ,
"#include \"librpc/gen_ndr/ndr_orpc.h\"\n" .
"#include \"librpc/gen_ndr/ndr_$basename.h\"\n" .
$ res ) ;
}
$ opt_odl = 1 ;
}
if ( $ opt_dcom_proxy ) {
my $ res = DCOMProxy:: Parse ( $ pidl ) ;
if ( $ res ) {
my ( $ client ) = util:: ChangeExtension ( $ output , "_p.c" ) ;
util:: FileSave ( $ client ,
"#include \"includes.h\"\n" .
"#include \"librpc/gen_ndr/com_$basename.h\"\n" .
"#include \"lib/dcom/common/orpc.h\"\n" . $ res ) ;
}
$ opt_odl = 1 ;
}
2005-02-21 04:16:47 +03:00
if ( $ opt_odl ) {
2005-02-21 17:30:49 +03:00
$ pidl = ODL:: ODL2IDL ( $ pidl ) ;
2005-02-21 04:16:47 +03:00
}
2003-11-23 06:42:20 +03:00
if ( $ opt_header ) {
2003-12-14 16:22:12 +03:00
my ( $ header ) = util:: ChangeExtension ( $ output , ".h" ) ;
2005-02-21 17:30:49 +03:00
util:: FileSave ( $ header , NdrHeader:: Parse ( $ pidl ) ) ;
2005-01-08 01:27:18 +03:00
if ( $ opt_eparser ) {
my ( $ eparserhdr ) = dirname ( $ output ) . "/packet-dcerpc-$basename.h" ;
IdlEParser:: RewriteHeader ( $ pidl , $ header , $ eparserhdr ) ;
}
2005-01-29 04:39:50 +03:00
if ( $ opt_swig ) {
my ( $ filename ) = $ output ;
$ filename =~ s/\/ndr_/\// ;
$ filename = util:: ChangeExtension ( $ filename , ".i" ) ;
IdlSwig:: RewriteHeader ( $ pidl , $ header , $ filename ) ;
}
2003-11-23 06:42:20 +03:00
}
2003-12-14 16:22:12 +03:00
2004-11-18 23:53:23 +03:00
if ( $ opt_client ) {
my ( $ client ) = util:: ChangeExtension ( $ output , "_c.c" ) ;
my $ res = "" ;
my $ h_filename = util:: ChangeExtension ( $ output , ".h" ) ;
$ res . = "#include \"includes.h\"\n" ;
$ res . = "#include \"$h_filename\"\n\n" ;
foreach my $ x ( @ { $ pidl } ) {
2005-03-06 15:33:44 +03:00
$ res . = NdrClient:: ParseInterface ( $ x ) ;
2004-11-18 23:53:23 +03:00
}
util:: FileSave ( $ client , $ res ) ;
}
2003-12-14 16:22:12 +03:00
if ( $ opt_server ) {
2004-11-19 23:21:13 +03:00
my $ h_filename = util:: ChangeExtension ( $ output , ".h" ) ;
my $ plain = "" ;
my $ dcom = "" ;
2004-11-12 03:48:24 +03:00
foreach my $ x ( @ { $ pidl } ) {
next if ( $ x - > { TYPE } ne "INTERFACE" ) ;
if ( util:: has_property ( $ x , "object" ) ) {
2005-02-21 17:30:49 +03:00
$ dcom . = DCOMStub:: ParseInterface ( $ x ) ;
2004-11-12 03:48:24 +03:00
} else {
2004-11-19 23:21:13 +03:00
$ plain . = IdlServer:: ParseInterface ( $ x ) ;
2004-11-12 03:48:24 +03:00
}
}
2004-11-19 23:21:13 +03:00
if ( $ plain ne "" ) {
util:: FileSave ( util:: ChangeExtension ( $ output , "_s.c" ) , $ plain ) ;
}
if ( $ dcom ne "" ) {
$ dcom = "
#include \"includes.h\"
#include \"$h_filename\"
#include \"rpc_server/dcerpc_server.h\"
#include \"rpc_server/common/common.h\"
$ dcom
" ;
util:: FileSave ( util:: ChangeExtension ( $ output , "_d.c" ) , $ dcom ) ;
}
2003-12-14 16:22:12 +03:00
}
2004-05-09 11:10:12 +04:00
2003-11-23 06:42:20 +03:00
if ( $ opt_parser ) {
2003-12-14 16:22:12 +03:00
my ( $ parser ) = util:: ChangeExtension ( $ output , ".c" ) ;
2005-02-11 02:34:59 +03:00
util:: FileSave ( $ parser , NdrParser:: Parse ( $ pidl , $ parser ) ) ;
2005-01-08 01:27:18 +03:00
if ( $ opt_eparser ) {
my ( $ eparser ) = dirname ( $ output ) . "/packet-dcerpc-$basename.c" ;
IdlEParser:: RewriteC ( $ pidl , $ parser , $ eparser ) ;
}
2004-09-08 15:54:01 +04:00
}
2003-12-15 13:55:10 +03:00
if ( $ opt_template ) {
print IdlTemplate:: Parse ( $ pidl ) ;
}
2003-11-09 11:28:47 +03:00
}
2003-11-08 16:24:14 +03:00
2003-11-23 06:42:20 +03:00
foreach my $ filename ( @ ARGV ) {
process_file ( $ filename ) ;
2003-11-08 16:24:14 +03:00
}