Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Parser/IDL/omni.py
    1| # $Id: omni.py,v 1.36 2003/01/20 06:43:02 chalky Exp $
    2| #
    3| # This file is a part of Synopsis.
    4| # Copyright (C) 2000, 2001 Stefan Seefeld
    5| #
    6| # Synopsis is free software; you can redistribute it and/or modify it
    7| # under the terms of the GNU General Public License as published by
    8| # the Free Software Foundation; either version 2 of the License, or
    9| # (at your option) any later version.
   10| #
   11| # This program is distributed in the hope that it will be useful,
   12| # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14| # General Public License for more details.
   15| #
   16| # You should have received a copy of the GNU General Public License
   17| # along with this program; if not, write to the Free Software
   18| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   19| # 02111-1307, USA.
   20| #
   21| # $Log: omni.py,v $
   22| # Revision 1.36  2003/01/20 06:43:02  chalky
   23| # Refactored comment processing. Added AST.CommentTag. Linker now determines
   24| # comment summary and extracts tags. Increased AST version number.
   25| #
   26| # Revision 1.35  2003/01/16 17:14:10  chalky
   27| # Increase AST version number. SourceFiles store full filename. Executor/Project
   28| # uses it to check timestamp for all included files when deciding whether to
   29| # reparse input files.
   30| #
   31| # Revision 1.34  2002/12/12 17:25:35  chalky
   32| # Implemented Include support for C++ parser. A few other minor fixes.
   33| #
   34| # Revision 1.33  2002/12/10 07:27:47  chalky
   35| # Fixed for new AST structure (SourceFiles)
   36| #
   37| # Revision 1.32  2002/12/09 04:01:03  chalky
   38| # Added multiple file support to parsers, changed AST datastructure to handle
   39| # new information, added a demo to demo/C++. AST Declarations now have a
   40| # reference to a SourceFile (which includes a filename) instead of a filename.
   41| #
   42| # Revision 1.31  2002/11/03 12:43:33  chalky
   43| # Fix procedure for finding omnicpp to use the PATH variable
   44| #
   45| # Revision 1.30  2001/07/19 05:10:39  chalky
   46| # Use filenames stored in AST object
   47| #
   48| # Revision 1.29  2001/07/19 04:03:18  chalky
   49| # New .syn file format.
   50| #
   51| # Revision 1.28  2001/06/13 13:02:36  chalky
   52| # A couple of fixes for new realname() stuff
   53| #
   54| # Revision 1.27  2001/06/13 01:55:11  stefan
   55| # modify the realName member to contain only the unscoped name. This has the nice effect that pruning the scope will affect the name and realname at once, since the realName() method computes the scoped name tuple on-the-fly
   56| #
   57| # Revision 1.26  2001/05/25 13:45:49  stefan
   58| # fix problem with getopt error reporting
   59| #
   60| # Revision 1.25  2001/04/03 23:03:53  chalky
   61| # IDL parser now uses config objects. Changed IDL demo accordingly.
   62| #
   63| # Revision 1.24  2001/02/12 04:08:09  chalky
   64| # Added config options to HTML and Linker. Config demo has doxy and synopsis styles.
   65| #
   66| # Revision 1.23  2001/01/31 06:51:24  stefan
   67| # add support for '-v' to all modules; modified toc lookup to use additional url as prefix
   68| #
   69| # Revision 1.22  2001/01/29 20:22:00  stefan
   70| # fixed getopt bug
   71| #
   72| # Revision 1.21  2001/01/28 02:23:49  chalky
   73| # Added -b basename
   74| #
   75| # Revision 1.20  2001/01/26 17:25:19  stefan
   76| # represent array sizes as strings, not ints (to be elaborated...)
   77| #
   78| # Revision 1.19  2001/01/25 18:27:47  stefan
   79| # added Type.Array type and removed AST.Declarator. Adjusted the IDL parser to that.
   80| #
   81| # Revision 1.18  2001/01/22 19:54:41  stefan
   82| # better support for help message
   83| #
   84| # Revision 1.17  2001/01/22 17:06:15  stefan
   85| # added copyright notice, and switched on logging
   86| #
   87| 
   88| from omniidl import idlast, idltype, idlvisitor, idlutil
   89| import _omniidl
   90| import sys, getopt, os, os.path, string, types
   91| from Synopsis.Core import Type, AST, Util
   92| 
   93| verbose = 0
   94| 
   95| # A dummy function that doesn't modify filename. use -b to change it
   96| def strip(filename): return filename
   97| 
   98| def strip_filename(filename):
   99|     "This is aliased as strip if -b used and basename set"
  100|     if len(basename) > len(filename): return filename
  101|     if filename[:len(basename)] == basename:
  102|         return filename[len(basename):]
  103|     return filename
  104| 
  105| class TypeTranslator (idlvisitor.TypeVisitor):
  106|     """maps idltype objects to Synopsis.Type objects in a Type.Dictionary"""
  107|     def __init__(self, types):
  108|         self.types = types
  109|         self.__result = None
  110|         self.__basetypes = {
  111|             idltype.tk_void:       "void",
  112|             idltype.tk_short:      "short",
  113|             idltype.tk_long:       "long",
  114|             idltype.tk_ushort:     "unsigned short",
  115|             idltype.tk_ulong:      "unsigned long",
  116|             idltype.tk_float:      "float",
  117|             idltype.tk_double:     "double",
  118|             idltype.tk_boolean:    "boolean",
  119|             idltype.tk_char:       "char",
  120|             idltype.tk_octet:      "octet",
  121|             idltype.tk_any:        "any",
  122|             idltype.tk_TypeCode:   "CORBA::TypeCode",
  123|             idltype.tk_Principal:  "CORBA::Principal",
  124|             idltype.tk_longlong:   "long long",
  125|             idltype.tk_ulonglong:  "unsigned long long",
  126|             idltype.tk_longdouble: "long double",
  127|             idltype.tk_wchar:      "wchar"
  128|             }
  129| 
  130|     def internalize(self, idltype):
  131|         idltype.accept(self)
  132|         return self.__result
  133| 
  134|     def add(self, name, type):
  135|         self.types[name] = type
  136|     def get(self, name):
  137|         return self.types[name]
  138| 
  139|     def visitBaseType(self, idltype):
  140|         type = Type.Base("IDL", (self.__basetypes[idltype.kind()],))
  141|         self.types[type.name()] = type
  142|         self.__result = type.name()
  143| 
  144|     def visitStringType(self, idltype):
  145|         if not self.types.has_key(["string"]):
  146|             self.types[["string"]] = Type.Base("IDL", ("string",))
  147|         self.__result = ["string"]
  148|         #if idltype.bound() == 0:
  149|         #    self.__result_type = "string"
  150|         #else:
  151|         #    self.__result_type = "string<" + str(type.bound()) + ">"
  152| 
  153|     def visitWStringType(self, idltype):
  154|         if not self.types.has_key(["wstring"]):
  155|             self.types[["wstring"]] = Type.Base("IDL", ("wstring",))
  156|         self.__result = ["wstring"]
  157|         #if type.bound() == 0:
  158|         #    self.__result_type = "wstring"
  159|         #else:
  160|         #    self.__result_type = "wstring<" + str(type.bound()) + ">"
  161| 
  162|     def visitSequenceType(self, idltype):
  163|         if not self.types.has_key(["sequence"]):
  164|             self.types[["sequence"]] = Type.Base("IDL", ("sequence",))
  165|         idltype.seqType().accept(self)
  166|         ptype = self.types[self.__result]
  167|         #if type.bound() == 0:
  168|         #    self.__result_type = "sequence<" + self.__result_type + ">"
  169|         #else:
  170|         #    self.__result_type = "sequence<" + self.__result_type + ", " +\
  171|         #                         str(type.bound()) + ">"
  172|         type = Type.Parametrized("IDL", self.types[["sequence"]], [ptype])
  173|         name  = ["sequence<" + Util.ccolonName(ptype.name()) + ">"]
  174|         self.types[name] = type
  175|         self.__result = name
  176|         
  177|     def visitDeclaredType(self, idltype):
  178|         self.__result = idltype.decl().scopedName()
  179| 
  180| class ASTTranslator (idlvisitor.AstVisitor):
  181|     def __init__(self, declarations, types, mainfile_only):
  182|         self.declarations = declarations
  183|         self.__mainfile_only = mainfile_only
  184|         self.__types = types
  185|         self.__scope = []
  186|         self.__operation = None
  187|         self.__enum = None
  188|         
  189|     def scope(self): return self.__scope[-1].name()
  190|     def addDeclaration(self, declaration): self.__scope[-1].declarations().append(declaration)
  191|     def addType(self, name, type):
  192|         if self.__types.types.has_key(name):
  193|             if isinstance(self.__types.get(name), Type.Unknown):
  194|                self.__types.add(name, type)
  195|          else:
  196|         pass
  197|           return
  198|         self.__types.add(name, type)
  199|     def getType(self, name): return self.__types.get(name)
  200|     def visitAST(self, node):
  201|         self.__scope.append(AST.Scope(sourcefile, 0, "IDL", "file", []))
  202|         # add an 'Object' Type to the Type Dictionary. Don't declare it in the AST since
  203|         # there is no corresponding declaration
  204|         object = AST.Class(sourcefile, 0, "IDL", "interface", ["CORBA", "Object"])
  205|         self.addType(["CORBA", "Object"], Type.Declared("IDL", ["CORBA", "Object"], object))
  206|         for n in node.declarations():
  207|             n.accept(self)
  208|         for d in self.__scope[-1].declarations():
  209|             self.declarations.append(d)
  210| 
  211|     def visitModule(self, node):
  212|         #if self.__mainfile_only and not node.mainFile(): return
  213|         name = list(self.scope()) + [node.identifier()]
  214|         module = AST.Module(sourcefile, node.line(), "IDL", "module", name)
  215|         self.addDeclaration(module)
  216|         self.__scope.append(module)
  217|         self.addType(name, Type.Declared("IDL", name, module))
  218|         if not self.__mainfile_only or node.mainFile(): 
  219|             for c in node.comments():
  220|                module.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  221|         for n in node.definitions():
  222|             n.accept(self)
  223|         self.__scope.pop()
  224|         
  225|     def visitInterface(self, node):
  226|         name = list(self.scope()) + [node.identifier()]
  227|         clas = AST.Class(sourcefile, node.line(), "IDL", "interface", name)
  228|         self.addDeclaration(clas)
  229|         self.__scope.append(clas)
  230|         self.addType(name, Type.Declared("IDL", name, clas))
  231|         if not self.__mainfile_only or node.mainFile(): 
  232|             for c in node.comments():
  233|                clas.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  234|         for i in node.inherits():
  235|             parent = self.getType(i.scopedName())
  236|             clas.parents().append(AST.Inheritance("", parent, []))
  237|         for c in node.contents(): c.accept(self)
  238|         self.__scope.pop()
  239|         
  240|     def visitForward(self, node):
  241|         #if self.__mainfile_only and not node.mainFile(): return
  242|         name = list(self.scope())
  243|         name.append(node.identifier())
  244|         forward = AST.Forward(sourcefile, node.line(), "IDL", "interface", name)
  245|         self.addDeclaration(forward)
  246|         self.addType(name, Type.Unknown("IDL", name))
  247|         
  248|     def visitConst(self, node):
  249|         if self.__mainfile_only and not node.mainFile(): return
  250|         name = list(self.scope())
  251|         name.append(node.identifier())
  252|         type = self.__types.internalize(node.constType())
  253|         if node.constType().kind() == idltype.tk_enum:
  254|             value = "::" + idlutil.ccolonName(node.value().scopedName())
  255|         else:
  256|             value = str(node.value())
  257|         const = AST.Const(sourcefile, node.line(), "IDL", "const",
  258|                           self.getType(type), name, value)
  259|         self.addDeclaration(const)
  260|         for c in node.comments():
  261|             const.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  262|         
  263|     def visitTypedef(self, node):
  264|         #if self.__mainfile_only and not node.mainFile(): return
  265|         # if this is an inline constructed type, it is a 'Declared' type
  266|         # and we need to visit the declaration first
  267|         if node.constrType():
  268|             node.memberType().decl().accept(self)
  269|         type = self.__types.internalize(node.aliasType())
  270|         comments = []
  271|         for c in node.comments():
  272|             comments.append(AST.Comment(c.text(), strip(c.file()), c.line()))
  273|         for d in node.declarators():
  274|             # reinit the type for this declarator, as each declarator of
  275|             # a single typedef declaration can have a different type. *sigh*
  276|             dtype = type
  277|             if d.sizes():
  278|                 array = Type.Array("IDL", self.getType(type), map(lambda s:str(s), d.sizes()))
  279|                 dtype = map(None, type[:-1])
  280|                 dtype.append(type[-1] + string.join(map(lambda s:"["+ str(s) +"]", d.sizes()),''))
  281|                 self.addType(dtype, array)
  282|             dname = list(self.scope())
  283|             dname.append(d.identifier())
  284|             typedef = AST.Typedef(sourcefile, node.line(), "IDL", "typedef", dname, self.getType(dtype), node.constrType())
  285|             typedef.comments().extend(comments)
  286|             for c in d.comments():
  287|                 typedef.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  288|             self.addType(typedef.name(), Type.Declared("IDL", typedef.name(), typedef))
  289|             self.addDeclaration(typedef)
  290| 
  291|     def visitMember(self, node):
  292|         if self.__mainfile_only and not node.mainFile(): return
  293|         # if this is an inline constructed type, it is a 'Declared' type
  294|         # and we need to visit the declaration first
  295|         if node.constrType():
  296|             node.memberType().decl().accept(self)
  297|         type = self.__types.internalize(node.memberType())
  298|         comments = []
  299|         for c in node.comments():
  300|             comments.append(AST.Comment(c.text(), strip(c.file()), c.line()))
  301|         for d in node.declarators():
  302|             # reinit the type for this declarator, as each declarator of
  303|             # a single typedef declaration can have a different type. *sigh*
  304|             dtype = type
  305|             if d.sizes():
  306|                 array = Type.Array("IDL", self.getType(type), map(lambda s:str(s), node.sizes()))
  307|                 dtype = type[:-1]
  308|                 dtype.append(type[-1] + string.join(map(lambda s:"["+s+"]", d.sizes()),''))
  309|                 self.addType(dtype, array)
  310|             dname = list(self.scope())
  311|             dname.append(d.identifier())
  312|             member = AST.Variable(sourcefile, node.line(), "IDL", "variable", dname, self.getType(dtype), node.constrType())
  313|             member.comments().extend(comments)
  314|             for c in d.comments():
  315|                 member.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  316|             self.addType(member.name(), Type.Declared("IDL", member.name(), member))
  317|             self.addDeclaration(member)
  318| 
  319|     def visitStruct(self, node):
  320|         name = list(self.scope()) + [node.identifier()]
  321|         if self.__mainfile_only and not node.mainFile():
  322|             forward = AST.Forward(sourcefile, node.line(), "IDL", "struct", name)
  323|             self.addDeclaration(forward)
  324|             self.addType(name, Type.Declared("IDL", name, forward))
  325|           return
  326|         struct = AST.Class(sourcefile, node.line(), "IDL", "struct", name)
  327|         self.addDeclaration(struct)
  328|         self.addType(name, Type.Declared("IDL", name, struct))
  329|         for c in node.comments():
  330|             struct.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  331|         self.__scope.append(struct)
  332|         for member in node.members(): member.accept(self)
  333|         self.__scope.pop()
  334|         
  335|     def visitException(self, node):
  336|         name = list(self.scope()) + [node.identifier()]
  337|         if self.__mainfile_only and not node.mainFile():
  338|             forward = AST.Forward(sourcefile, node.line(), "IDL", "exception", name)
  339|             self.addDeclaration(forward)
  340|             self.addType(name, Type.Declared("IDL", name, forward))
  341|           return
  342|         exc = AST.Class(sourcefile, node.line(), "IDL", "exception", name)
  343|         self.addDeclaration(exc)
  344|         self.addType(name, Type.Declared("IDL", name, exc))
  345|         self.__scope.append(exc)
  346|         for c in node.comments():
  347|             exc.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  348|         for member in node.members(): member.accept(self)
  349|         self.__scope.pop()
  350|     
  351|     #    def visitCaseLabel(self, node):    return
  352|     def visitUnionCase(self, node):
  353|         if self.__mainfile_only and not node.mainFile(): return
  354|         # if this is an inline constructed type, it is a 'Declared' type
  355|         # and we need to visit the declaration first
  356|         if node.constrType():
  357|             node.caseType().decl().accept(self)
  358|         type = self.__types.internalize(node.caseType())
  359|         declarator = node.declarator()
  360|         if declarator.sizes():
  361|             array = Type.Array("IDL", self.getType(type), map(lambda s:str(s), declarator.sizes()))
  362|             type = type[:-1]
  363|             type.append(type[-1] + string.join(map(lambda s:"["+s+"]",node.sizes()),''))
  364|             self.addType(type, array)
  365|         name = list(self.scope())
  366|         name.append(node.declarator().identifier())
  367|         self.__scope[-1].declarations().append(
  368|             AST.Operation(sourcefile, node.line(), "IDL", "case",
  369|                         [], self.getType(type), name, name[-1]))
  370|     def visitUnion(self, node):
  371|         name = list(self.scope()) + [node.identifier()]
  372|         if self.__mainfile_only and not node.mainFile():
  373|             forward = AST.Forward(sourcefile, node.line(), "IDL", "union", name)
  374|             self.addDeclaration(forward)
  375|             self.addType(name, Type.Declared("IDL", name, forward))
  376|           return
  377|         clas = AST.Class(sourcefile, node.line(), "IDL", "union", name)
  378|         self.addDeclaration(clas)
  379|         self.__scope.append(clas)
  380|         self.addType(name, Type.Declared("IDL", name, clas))
  381|         for c in node.comments():
  382|             clas.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  383|         for c in node.cases(): c.accept(self)
  384|         self.__scope.pop()
  385|         
  386|     def visitEnumerator(self, node):
  387|         if self.__mainfile_only and not node.mainFile(): return
  388|         name = list(self.scope())
  389|         name.append(node.identifier())
  390|         enum = AST.Enumerator(sourcefile, node.line(), "IDL", name, "")
  391|         self.addType(name, Type.Declared("IDL", name, enum))
  392|         self.__enum.enumerators().append(enum)
  393| 
  394|     def visitEnum(self, node):
  395|         name = list(self.scope()) + [node.identifier()]
  396|         if self.__mainfile_only and not node.mainFile():
  397|             forward = AST.Forward(sourcefile, node.line(), "IDL", "enum", name)
  398|             self.addDeclaration(forward)
  399|             self.addType(name, Type.Declared("IDL", name, forward))
  400|           return
  401|         self.__enum = AST.Enum(sourcefile, node.line(), "IDL", name, [])
  402|         self.addDeclaration(self.__enum)
  403|         self.addType(name, Type.Declared("IDL", name, self.__enum))
  404|         for c in node.comments():
  405|             self.__enum.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  406|         for enumerator in node.enumerators(): enumerator.accept(self)
  407|         self.__enum = None
  408|         
  409|     def visitAttribute(self, node):
  410|         scopename = list(self.scope())
  411|         if self.__mainfile_only and not node.mainFile(): return
  412|         # Add real Operation objects
  413|         pre = []
  414|         if node.readonly(): pre.append("readonly")
  415|         type = self.__types.internalize(node.attrType())
  416|         comments = []
  417|         for c in node.comments():
  418|             comments.append(AST.Comment(c.text(), strip(c.file()), c.line()))
  419|         for id in node.identifiers():
  420|             name = scopename + [id]
  421|             attr = AST.Operation(sourcefile, node.line(), "IDL", "attribute",
  422|                               pre, self.getType(type), name, name[-1])
  423|             attr.comments().extend(comments)
  424|             self.addDeclaration(attr)
  425| 
  426|     def visitParameter(self, node):
  427|         operation = self.__operation
  428|         pre = []
  429|         if node.direction() == 0: pre.append("in")
  430|         elif node.direction() == 1: pre.append("out")
  431|         else: pre.append("inout")
  432|         post = []
  433|         name = self.__types.internalize(node.paramType())
  434|         operation.parameters().append(AST.Parameter(pre, self.getType(name), post, node.identifier()))
  435|     
  436|     def visitOperation(self, node):
  437|         pre = []
  438|         if node.oneway(): pre.append("oneway")
  439|         returnType = self.__types.internalize(node.returnType())
  440|         name = list(self.scope())
  441|         name.append(node.identifier())
  442|         self.__operation = AST.Operation(sourcefile, node.line(), "IDL", "operation", pre, self.getType(returnType), name, name[-1])
  443|         for c in node.comments():
  444|             self.__operation.comments().append(AST.Comment(c.text(), strip(c.file()), c.line()))
  445|         for p in node.parameters(): p.accept(self)
  446|         for e in node.raises():
  447|             exception = self.getType(e.scopedName())
  448|             self.__operation.exceptions().append(exception)
  449|             
  450|         self.addDeclaration(self.__operation)
  451|         self.__operation = None
  452|         
  453| #    def visitNative(self, node):       return
  454| #    def visitStateMember(self, node):  return
  455| #    def visitFactory(self, node):      return
  456| #    def visitValueForward(self, node): return
  457| #    def visitValueBox(self, node):     return
  458| #    def visitValueAbs(self, node):     return
  459| #    def visitValue(self, node):        return
  460| 
  461| def usage():
  462|     print \
  463| """
  464|   -I<path>                             Specify include path to be used by the preprocessor
  465|   -m                                   Unly keep declarations from the main file
  466|   -k                                   Comments after declarations are kept for the back-ends
  467|   -K                                   Comments before declarations are kept for the back-ends
  468|   -b <basename>                        Strip the basename from all filenames"""
  469| 
  470| def __parseArgs(args, config_obj):
  471|     global preprocessor_args, mainfile_only, basename, strip, verbose
  472| 
  473|     preprocessor_args = []
  474|     mainfile_only = 0
  475|     basename = ""
  476| 
  477|     # Try config object first
  478|     if hasattr(config_obj, 'keep_comments') and config_obj.keep_comments:
  479|         preprocessor_args.append("-C")
  480|         _omniidl.keepComments(1)
  481|     if hasattr(config_obj, 'main_file') and config_obj.main_file:
  482|         mainfile_only = 1
  483|     if hasattr(config_obj, 'verbose') and config_obj.verbose:
  484|         verbose = 1
  485|     if hasattr(config_obj, 'basename') and config_obj.basename:
  486|         basename = config_obj.basename
  487|         strip = strip_filename
  488|     if hasattr(config_obj, 'include_path') and config_obj.include_path:
  489|         paths = config_obj.include_path
  490|         if type(paths) != types.ListType:
  491|             sys.stderr.write("Config include_path must be a list of strings")
  492|             sys.exit(1)
  493|         for path in paths:
  494|             if type(path) != types.StringType:
  495|                sys.stderr.write("Config include_path must be a list of strings")
  496|                sys.exit(1)
  497|             preprocessor_args.append("-I" + path)
  498|         
  499|     
  500|     # Parse args
  501|     try:
  502|         opts,remainder = Util.getopt_spec(args, "I:b:mkKv")
  503|     except getopt.error, e:
  504|         sys.stderr.write("Error in arguments: " + str(e) + "\n")
  505|         sys.exit(1)
  506| 
  507|     for opt in opts:
  508|         o,a = opt
  509| 
  510|         if o == "-I":
  511|             preprocessor_args.append("-I" + a)
  512|         if o == "-m":
  513|             mainfile_only = 1
  514|         elif o == "-k":
  515|             preprocessor_args.append("-C")
  516|             _omniidl.keepComments(0)
  517|         elif o == "-K":
  518|             preprocessor_args.append("-C")
  519|             _omniidl.keepComments(1)
  520|         elif o == "-b":
  521|             basename = a
  522|             strip = strip_filename
  523|         elif o == "-v": verbose = 1
  524| 
  525| def parse(file, extra_files, args, config_obj):
  526|     global preprocessor_args, mainfile_only, sourcefile
  527|     __parseArgs(args, config_obj)
  528|     path = string.split(os.getenv('PATH'), os.pathsep)
  529|     # Add Synopsis' bindir
  530|     path.insert(0, os.path.dirname(sys.argv[0]))
  531|     if hasattr(_omniidl, "__file__"):
  532|         # Add path to omniidl module
  533|         dirname = os.path.dirname(_omniidl.__file__)
  534|         path.insert(0, dirname)
  535|         # If, eg, /usr/lib/pythonX.X/site-packages, add /usr/lib
  536|         dirnames = string.split(dirname, os.sep)
  537|         if len(dirnames) > 2 and dirnames[-1] == 'site-packages' \
  538|                and dirnames[-2][:6] == 'python':
  539|             path.insert(0, string.join(dirnames[:-2], os.sep))
  540|         
  541|     preprocessor = None
  542|     for directory in path:
  543|         preprocessor = os.path.join(directory, "omnicpp")
  544|         if os.access(preprocessor, os.R_OK | os.X_OK):
  545|          break
  546|         preprocessor = None
  547|     if not preprocessor:
  548|         # Try ordinary cpp
  549|         print "Error: unable to find omnicpp in path:"
  550|         print string.join(path, os.pathsep)
  551|         sys.exit(1)
  552|     preprocessor_cmd  = preprocessor + " -lang-c++ -undef -D__OMNIIDL__=" + _omniidl.version
  553|     preprocessor_cmd = preprocessor_cmd + " " + string.join(preprocessor_args, " ") + " " + file
  554|     fd = os.popen(preprocessor_cmd, "r")
  555| 
  556|     _omniidl.noForwardWarning()
  557|     tree = _omniidl.compile(fd)
  558|     if tree == None:
  559|         sys.stderr.write("omni: Error parsing " + file + "\n")
  560|         sys.exit(1)
  561| 
  562|     sourcefile = AST.SourceFile(strip(file), file, "IDL")
  563|     sourcefile.set_is_main(1)
  564|     ast = AST.AST()
  565|     ast.files()[sourcefile.filename()] = sourcefile
  566|     type_trans = TypeTranslator(ast.types())
  567|     ast_trans = ASTTranslator(ast.declarations(), type_trans, mainfile_only)
  568|     tree.accept(ast_trans)
  569|     sourcefile.declarations()[:] = ast.declarations()
  570|     return ast