#!/usr/bin/env python ############################################################################# # Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999 # All Rights Reserved. # # The software contained on this media is the property of the DSTC Pty # Ltd. Use of this software is strictly in accordance with the # license agreement in the accompanying LICENSE.HTML file. If your # distribution of this software does not contain a LICENSE.HTML file # then you have no rights to use this software in any manner and # should contact DSTC at the address below to determine an appropriate # licensing arrangement. # # DSTC Pty Ltd # Level 7, GP South # Staff House Road, # University of Queensland # St Lucia, 4072 # Australia # Tel: +61 7 3365 4310 # Fax: +61 7 3365 4311 # Email: enquiries@dstc.edu.au # # This software is being provided "AS IS" without warranty of any # kind. In no event shall DSTC Pty Ltd be liable for damage of any # kind arising out of or in connection with the use or performance of # this software. # # Project: Fnorb # File: $Source: /cvsroot/fnorb/fnorb/script/fnidl.py,v $ # Version: @(#)$RCSfile: fnidl.py,v $ $Revision: 1.8 $ # ############################################################################# """ IDL compiler for Fnorb! """ # Standard/built-in modules. import commands, os, string, sys # Fnorb modules. from Fnorb.orb import CORBA, Util from Fnorb.parser import IDLParser from Fnorb.compiler import IDLCompiler import Fnorb.parser.cpp import Fnorb.script.cpp # Interface Repository modules. from Fnorb.cos.interface_repository import IntRepImpl # Default options. DEFAULT_DIRECTORY = '.' DEFAULT_PACKAGE = Util.PackageName() DEFAULT_GLOBALS = '_GlobalIDL' DEFAULT_EXT_CPP = 1 def usage(): print """Usage: fnidl [OPTION] [FILE.idl]... Compile FILEs to Python. If no FILE is given, read IDL from stdin. --directory=DIR Output files into DIRECTORY (default '.'). --package=PACKAGE Output classes into PACKAGE (default no package) --globals=GLOBALS Output global non-modules to GLOBALS (default _GlobalIDL). --external-cpp Use the preprocessor of the system C compiler (default). --internal-cpp Use the built-in pure-python C preprocessor. -CPP-OPTION Pass options to preprocessor (-D, -I). """ raise SystemExit def main(argv): """ Do it! """ # Default options. directory = DEFAULT_DIRECTORY package = DEFAULT_PACKAGE globals = DEFAULT_GLOBALS ext_cpp = DEFAULT_EXT_CPP # We separate arguments for the pre-processor from IDL files. cpp_flags = [] idl_files = [] for arg in argv[1:]: # Help if arg == '--help' or arg == '-h': usage() # Output directory option. if arg.startswith('--directory='): directory = string.split(arg, '=')[1] # Package option. elif arg.startswith('--package='): package = Util.PackageName(string.split(arg, '=')[1]) # Global IDL package option. elif arg.startswith('--globals='): globals = string.split(arg, '=')[1] # Use external cpp? elif arg == '--external-cpp': ext_cpp = 1 # Use external cpp? elif arg == '--internal-cpp': ext_cpp = 0 # Define elif arg.startswith("-"): cpp_flags.append(arg) # IDL files. elif arg[-4:] == '.idl': idl_files.append(arg) # Ignore anything else (including the spurious last argument '\n' on # Windoows 95 ;^). else: pass # Create the compilation context. context = IDLCompiler.Context(directory, package, globals) # If no files were specified on the command line, then parse from stdin! if len(idl_files) == 0: result = main_interactive(context) elif ext_cpp: result = main_batch_external_cpp(context, cpp_flags, idl_files) else: result = main_batch(context, cpp_flags, idl_files) return result def main_interactive(context): """ Parse IDL from stdin! """ # Create the parser. parser = IDLParser.IDLParser() # Create an instance of the 'Repository' implementation class. ifr = IntRepImpl.RepositoryImpl() # Do the parsing! print 'Enter IDL (Ctrl-D to finish)...\n' (result, contents) = parser.parse(ifr, 'stdin', sys.stdin) # If the parsing succeeded. if result == 0: if len(contents) > 0: # Create an IDLCompiler to do the work! idl_compiler = IDLCompiler.IDLCompiler() # Generate code for the objects returned by the parser. idl_compiler.compile(context, contents) return result def main_batch(context, cpp_flags, idl_files): """ Parse IDL from files! """ # Create the parser. parser = IDLParser.IDLParser() # Parse each file. for idl_file in idl_files: # Setup the preprocessor preprocessor = Fnorb.parser.cpp.process_command_line(cpp_flags + [idl_file]) # Create an instance of the 'Repository' implementation class. ifr = IntRepImpl.RepositoryImpl() # Do the parsing! (result, contents) = parser.parse_tokenized(ifr, idl_file, preprocessor) # If the parsing succeeded. if result == 0: if len(contents) > 0: # Create an IDLCompiler to do the work! idl_compiler = IDLCompiler.IDLCompiler() # Generate code for the objects returned by the parser. idl_compiler.compile(context, contents) # If a parsing error occured then bail out. else: break return result def main_batch_external_cpp(context, cpp_flags, idl_files): """ Parse IDL from files! """ # Create the parser. parser = IDLParser.IDLParser() # Parse each file. for idl_file in idl_files: # Format the command to run the C/C++ pre-processor. cmd = Fnorb.script.cpp.COMMAND % (string.join(cpp_flags), idl_file) # Run the pre-processor and use its output as the lexer's input stream. yyin = os.popen(cmd, 'r') # Create an instance of the 'Repository' implementation class. ifr = IntRepImpl.RepositoryImpl() # Do the parsing! (result, contents) = parser.parse(ifr, idl_file, yyin) # If the parsing succeeded. if result == 0: if len(contents) > 0: # Create an IDLCompiler to do the work! idl_compiler = IDLCompiler.IDLCompiler() # Generate code for the objects returned by the parser. idl_compiler.compile(context, contents) # If a parsing error occured then bail out. else: break # Close the pipe. status = yyin.close() if status: raise RuntimeError('<%s> failed with popen status %i' % (cmd, status)) return result ############################################################################# if __name__ == '__main__': # Do it! sys.exit(main(sys.argv)) #############################################################################