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)
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
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"
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"