Ejemplo n.º 1
0
def headerToClass(headerfile, options):
    if options.verbose:
        print "Processing '%s'" % headerfile
    classfile = headerfile.replace(".h", ".hkclass")
    master = headerToDom.headerToDom(headerfile)
    if options.verbose:
        print "Found:", ", ".join([c.name for c in master.file._class])

    if os.path.exists(classfile):
        edited = hkcToDom.hkcToDom(classfile)
        rejects = mergeBind.mergeBind(master.file, edited.file, master.name)
        if len(rejects):
            rejfile = "%s.rej" % classfile
            open(rejfile, "a").write("\n".join(rejects) + "\n")
            print "%s:1:Conflicts found" % headerfile

    pch_file = options.pch_file
    cppfile = master.file.destinationFilename(
        master.origfilename, "Class%s.cpp" % options.version_suffix)
    if master.file.overridedestination:
        pch_file = hkcToDom.Document(cppfile).pchfile
    try:
        cpptext = domToClass.domToClass(master,
                                        collectAll=False,
                                        pchfile=pch_file)
    except:
        print "Error in: " + headerfile
        raise
    try:
        writeIfDifferent(cpptext, cppfile, options.force_output)
    except IOError:
        print "Error in: %(headerfile)s\n\nDestination class file path is wrong:\n%(cppfile)s.\n" % locals(
        )
        raise
    if options.dump_xml:
        xmltext = bindingToXml.bindingToXml("document", master)
        try:
            xmlfile = genPathToFile(
                headerfile.replace(".h",
                                   "Class%s.xml" % options.version_suffix),
                destSpecifier)
            writeIfDifferent(xmltext, xmlfile, options.force_output)
        except IOError:
            print "Error in: %(headerfile)s\n\nDestination class file path is wrong:\n%(xmlfile)s.\n" % locals(
            )
            raise
    if options.cvsignore:
        removeFromCvsignore(headerfile)
        addToCvsignore(cppfile)
        addToCvsignore(classfile)
Ejemplo n.º 2
0
    def parseString(self, txt):
        document = hkcToDom.Document(self.current_filename)
        document.file = hkcToDom.File()
        
        for key, value in util.extract_tkbms(txt).items():
            setattr(document.file,key,value)

        txt = self.re_classAlign.sub(r"\1", txt) # HK_CLASSALIGN(class,8) -> class
        def do_align(match):
            return "%s; //+align(%s)\n" % (match.group(2), match.group(1) or match.group(3))
        txt = self.re_align.sub(do_align, txt) # HK_ALIGN(int foo,8); -> int foo; //+align(8)
        txt = re.sub("(?m)^\s*$\n","",txt) # delete blank lines
        def docstring_join(match):
            s,e = match.span()
            lines = match.string[s:e].split("\n")[:-1]
            lines = ( l[l.index("///")+3:].strip() for l in lines )
            return '//@hk.DocString("%s")\n' % " ".join(lines)
        # txt = self.re_docsComment.sub(docstring_join, txt) # join adjacent docstring lines
        txt = self.re_commentAttribute.sub(r"\001ATT\1\002;", txt) # save attributes, use unused char delimeters
        txt = self.re_cComment.sub("", txt) # remove c comments
        txt = self.re_cppComment.sub("", txt) # c++ comments too
        txt = txt.replace("\\\n", " ") # do preproc line joining
        txt = self.re_preproc.sub("", txt) # remove preprocessor
        txt = self.re_whitespace.sub(" ", txt) # and all whitespace
        def do_hkp_macros(match):
            substmacros = { "HCL_SHAPE_VIRTUAL": " virtual ",
                            "HKP_SHAPE_VIRTUAL": " virtual ",
                            "HKP_SHAPE_VIRTUAL_CONST": " const ",
                            "HKP_SHAPE_VIRTUAL_THIS" : " "
                        }
            return substmacros[match.group(1)]
        txt = self.re_refPtr.sub(r"\1*", txt) # hkRefPtr<T> -> T*
        txt = self.re_substmacros.sub(do_hkp_macros, txt) # substitude HKP_SHAPE_VIRTUAL, HKP_SHAPE_VIRTUAL_CONST and HKP_SHAPE_VIRTUAL_THIS macros
        txt = self.re_junkymacros.sub(r"\2 ", txt) # remove HK_CPU_PTR(\2), HK_PAD_ON_SPU(\2) and HK_THREAD_LOCAL(\2) macros

        while 1:
            item, match = self.globalMatcher.run(txt)
            if match == None:
                break

            newtxt = None
            if item == self.re_overideDestination:
                document.file.overridedestination = match.group(1)
                
            elif item == self.re_templateStart:
                newtxt, junk = self.parseTemplate(match, txt)

            elif item == self.re_hashInclude:
                self.debug("INCLUDE %s"% match.group("path"))
                document.file.includeheaders += "#include <%s>\n" % match.group("path")

            elif item == self.re_classStart:
                newtxt, klass = self.parseClass(match, txt, None)
                if klass:
                    document.file._class.append(klass)
            elif item == self.re_enumStart:
                newtxt, enum = self.parseEnum(match, txt)
                if enum:
                    document.file.enum.append(enum)
            elif item == self.re_unionStart:
                newtxt, union = self.parseUnion(match, txt)
            elif item == self.re_namespaceStart:
                newtxt, junk = self.parseNamespace(match, txt)
            elif item == self.re_taggedUnionStart:
                newtxt, union = self.parseTaggedUnion(match, txt)
                if union:
                    document.file.taggedunion.append(union)
            elif item == self.re_externCstart:
                newtxt, junk = self.parseExternC(match, txt)
            elif item == self.re_typedef:
                pass
            elif item == self.re_externVariable:
                pass
            elif item == self.re_functionDefinition:
                newtxt, junk = self.parseFunction(match, txt)
            elif item == self.re_attributesPlaceholder:
                pass # ignore attributes on e.g typedef or global
            elif item == self.re_spuriousSemicolon:
                pass
            else:
                print "NO_ACTION", match.group(), item
                print "***", txt

            oldTxtLength = len(txt)
            if newtxt:
                txt = newtxt
            else:
                txt = txt[match.span()[1]:]
            if len(txt) >= oldTxtLength:
                raise ("*** Breaking from infinite loop ***\n" \
                    "While parsing '%s'\n" \
                    "'%s'" % (self.current_filename, txt) )
        return document
Ejemplo n.º 3
0
def processDir(where, options):
    if options.output:
        fileNamePrefix = options.output
    else:
        fileNamePrefix = ""
    managedClassesHeaderFile = fileNamePrefix+"Classes.h"
    managedClassesImplFile = fileNamePrefix+"Classes.cpp"
    managedClassesHeader = domToManagedClass.FormatedSourceCode()
    managedClassesImpl = domToManagedClass.FormatedSourceCode()

    customLines = []
    genManagedHeaderStart( customLines, (options.manifest=="2") )
    domToManagedClass.genFileHeadlines( managedClassesHeader, customLines=customLines )
    if options.manifest=="2":
        ### custom manifest file, so include header for the Havok wrappers
        managedClassesHeader.append("#include <HavokAssembly/hkHavokManagedClasses.h>")
    
    domToManagedClass.genFileHeadlines(managedClassesImpl)
    managedClassesImpl.append("#include <HavokAssembly/%s>" % getName(managedClassesHeaderFile))
    
    nfile = 0
    def get_reflected_files(where, lst):
        for f in lst:
            full = os.path.join(where,f)
            if f.endswith(".h"):
                content = open(full).read()
                tkbms = util.extract_tkbms(content)
                valid_tkbms = lambda x : (not tkbms.has_key(x) or tkbms[x] != "NONE")
                if valid_tkbms("platform") and valid_tkbms("product") and util.hasReflectionDeclaration(content):
                    yield full
            elif f.endswith(".hkclass") and not os.path.exists(full.replace(".hkclass",".h")):
                yield full

    reflected_files = []
    excludeDirs = []
    if options.exclude:
        excludeDirs = options.exclude
    for dirname, subdirs, files in os.walk(where):
        files.sort()
        subdirs.sort()
        #print dirname
        if "CVS" in subdirs:
            subdirs.remove("CVS")
        if "UnitTest" in subdirs:
            subdirs.remove("UnitTest")
        if dirname in excludeDirs:
            del subdirs[:]
        else:
            reflected_files.extend( get_reflected_files(dirname,files) )

    fatDom = hkcToDom.Document(fileNamePrefix)
    fatDom.file = hkcToDom.File()
    fatDom.file.product = ""
    fatDom.file.platform = ".NET"
    fatDom.file.visibility = "PUBLIC"
    fatDom.file.includeheaders = ""

    def updatePath(filepath):
        updatedPath = filepath.replace("\\","/")
        if options.manifest=="2":
            updatedPath = "/".join( [ p for p in updatedPath.replace(where.replace("\\","/"),"").split("/") if p ] )
        return updatedPath

    def mergeDomDocs(domDocTo, domDocFrom):
        # merge
        domDocTo.file.mergeWith(domDocFrom.file)
        domDocTo.file.includeheaders += "#include <%s>\n" % updatePath(domDocFrom.localfilename)

    for reflected in reflected_files:
        nfile += 1
        if reflected.endswith(".h"):
            dom = headerToDom.headerToDom(reflected)
            if os.path.exists( reflected+"kclass" ):
                override = hkcToDom.hkcToDom( reflected+"kclass" )
                mergeBind.mergeBind(dom.file, override.file, dom.name)
        elif reflected.endswith(".hkclass"):
            dom = hkcToDom.hkcToDom( reflected )
        else:
            assert 0
        ### collect all doms info
        mergeDomDocs(fatDom, dom)

    if len(fatDom.file.includeheaders):
        headerfiles = [x for x in fatDom.file.includeheaders.split("\n") if not x.endswith(".inl>")]
        if options.manifest!="2":
            headerfiles.sort()
        cleanList = [""]
        for line in headerfiles:
            if line != cleanList[-1]:
                cleanList.append(line)
        headerfiles = "\n".join(cleanList[1:])
        managedClassesHeader.append("\n//\n// All reflected class headers\n//")
        managedClassesHeader.append("#pragma unmanaged")
        managedClassesHeader.append(headerfiles)
        managedClassesHeader.append("#pragma managed")

    managedClassDecl, managedClassDef = domToManagedClass.domToManagedClass(fatDom, collectAll=True)
    
    managedClassesHeader.append("\n".join(managedClassDecl.replace("\t","").split("/n")))
    managedClassesImpl.append("\n".join(managedClassDef.replace("\t","").split("/n")))

    genManagedHeaderEnd( managedClassesHeader, (options.manifest=="2") )
    
    updatedClassesHeaderContent = "\n".join(managedClassesHeader.lines)
    updatedClassesImplContent = "\n".join(managedClassesImpl.lines)
    if options.output:
        ### we open two files for output
        writeIfDifferent(updatedClassesHeaderContent, managedClassesHeaderFile, False)
        writeIfDifferent(updatedClassesImplContent, managedClassesImplFile, False)
    else:
        print >>sys.stdout, updatedClassesHeaderContent
        print >>sys.stdout, updatedClassesImplContent

    if not options.quiet:
        print >>sys.stderr, "DONE", where, nfile, "files processed"
Ejemplo n.º 4
0
def processDir(where, options):
    nfile = 0
    cpplist = []

    def get_reflected_files(where, lst):
        for f in lst:
            full = os.path.join(where, f)
            if f.endswith(".h"):
                content = open(full).read()
                tkbms = util.extract_tkbms(content)
                valid_tkbms = lambda x: (not tkbms.has_key(x) or tkbms[x] !=
                                         "NONE")
                if valid_tkbms("platform") and valid_tkbms(
                        "product") and util.hasReflectionDeclaration(content):
                    yield full
            elif f.endswith(".hkclass") and not os.path.exists(
                    full.replace(".hkclass", ".h")):
                yield full

    reflected_files = []
    for dirname, subdirs, files in os.walk(where):
        files.sort()
        subdirs.sort()
        reflected_files.extend(get_reflected_files(dirname, files))

    manifest = hkcToDom.Document("Manifest")
    manifest.file = hkcToDom.File()
    manifest.file.visibility = "PUBLIC"
    for reflected in reflected_files:
        nfile += 1
        if reflected.endswith(".h"):
            dom = headerToDom.headerToDom(reflected)
            if os.path.exists(reflected + "kclass"):
                override = hkcToDom.hkcToDom(reflected + "kclass")
                mergeBind.mergeBind(dom.file, override.file, dom.name)
        elif reflected.endswith(".hkclass"):
            dom = hkcToDom.hkcToDom(reflected)
        else:
            assert 0
        manifest.file.mergeWith(dom.file)
    cpplist.append(domToClass.domToClass(manifest, collectAll=True))

    if options.output:
        outfile = open(options.output, "w")
    else:
        outfile = None
    cpptxt = "\n".join(cpplist)
    symbols = [s for s in re.findall(r"^hkClass\s+([^\(]+)\s*\($(?m)", cpptxt)]
    symbols.sort()
    cpptxt = re.sub("\s*//.*(?m)", "", cpptxt)
    cpptxt = re.sub("^extern\s+hkClass\s+.*(?m)", "", cpptxt)
    cpptxt = re.sub("\n\s*\n", "\n", cpptxt)
    namespace = "hkHavok%sClasses" % options.version_suffix.replace("_", "")
    versionNumString = ".".join(
        [s for s in options.version_suffix.replace("_", "")[:3]])
    versionStage = options.version_suffix.replace("_", "")[3:]
    if versionStage is not "":
        versionNumString = "-".join([versionNumString, versionStage])
    listname = "Classes"
    print >> outfile, _tkbms % ("ALL", "ALL", "PUBLIC", namespace,
                                versionNumString, int(options.class_version))
    print >> outfile, "\n".join(
        ["\textern hkClass %s;" % s.replace("(", ";") for s in symbols])
    print >> outfile, cpptxt.replace("\n", "\n\t")[:-1]
    print >> outfile, "\tstatic hkClass* const %s[] =\n\t{\n%s\n\t\tHK_NULL\n\t}; " % (
        listname, "\n".join(["\t\t&%s," % s for s in symbols]))
    print >> outfile, "\tconst hkStaticClassNameRegistry hkHavokDefaultClassRegistry\n\t(\n\t\tClasses,\n\t\tClassVersion,\n\t\tVersionString\n\t);"
    print >> outfile, "".join(["\n} // namespace ", namespace, "\n"])
    if not options.quiet:
        print >> sys.stderr, "DONE", where, nfile, "files processed"