X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/423af76e39d975fff4e0030460e3aba795030b54..4f09729dfb63907ee07fc9395ff47f6411eb7469:/wxPython/distrib/build_renamers.py diff --git a/wxPython/distrib/build_renamers.py b/wxPython/distrib/build_renamers.py index 03f043a8d6..e99acb3a8f 100755 --- a/wxPython/distrib/build_renamers.py +++ b/wxPython/distrib/build_renamers.py @@ -1,12 +1,12 @@ #!/usr/bin/env python #--------------------------------------------------------------------------- """ -Usage: build_renamers.py filename.i +Usage: build_renamers.py destdir modulename filename.xml -Run SWIG on file.i using the XML language module and then scan the XML -file produced and generate the %rename directives needed to implement -the new wx namespace. The rename directives are output in a file -named _filename_rename.i in the same dir as filename.i. +Scans the XML file produced by SWIG (see setup.py) and generate the +%rename directives needed to implement the new wx namespace. The +rename directives are output in a file named _modulename_rename.i in +the destdir given. Also output a reverse 'renamer' Python module located in wxPython/filename.py (relative the the current dir) to make a @@ -14,37 +14,25 @@ backwards compatibility interface for the old wxPython packages. """ import sys, os, tempfile, pprint -import xml.sax +import xml.sax from distutils.spawn import spawn - - -#--------------------------------------------------------------------------- - -DO_UNLINK = True +try: + import libxml2 + USE_LIBXML2 = True +except ImportError: + USE_LIBXML2 = False wxPythonDir = "wxPython" -swig_cmd = "/opt/swig/bin/swig" -if os.name == 'nt': - swig_cmd = 'e:/projects/SWIG-cvs/swig.exe' -swig_args = ['-c++', - '-Wall', - '-nodefault', - - '-xml', - '-xmllite', - - '-I./src', - '-noruntime' - ] +#--------------------------------------------------------------------------- renamerTemplateStart = """\ // A bunch of %%rename directives generated by %s // in order to remove the wx prefix from all global scope names. -#ifndef SWIGXML +#ifndef BUILDING_RENAMERS """ @@ -86,7 +74,7 @@ wxPythonTemplateEnd = """ def main(args): # check args - if len(args) < 1: + if len(args) < 3: print __doc__ sys.exit(1) @@ -97,69 +85,149 @@ def main(args): sys.exit(1) - source = args[0] - sourcePath, sourceBase = os.path.split(source) - sourceBase = os.path.splitext(sourceBase)[0] - - tempfile.tempdir = sourcePath - xmlDest = tempfile.mktemp('.xml') - swigDest = os.path.join(sourcePath, "_"+sourceBase+"_rename.i") - pyDest = os.path.join(wxPythonDir, sourceBase + '.py') - - #print "source: ", source - #print "xmlDest: ", xmlDest - #print "swigDest: ", swigDest - #print "pyDest: ", pyDest - - cmd = [ swig_cmd ] + swig_args + args[1:] + ['-I'+sourcePath, '-o', xmlDest, source] - print ' '.join(cmd) - spawn(cmd) + destdir = args[0] + modname = args[1] + xmlfile = args[2] + + swigDest = os.path.join(destdir, "_"+modname+"_rename.i") + pyDest = os.path.join(wxPythonDir, modname + '.py') swigDestTemp = tempfile.mktemp('.tmp') swigFile = open(swigDestTemp, "w") swigFile.write(renamerTemplateStart % sys.argv[0]) - pyFile = open(pyDest, "w") - pyFile.write(wxPythonTemplateStart % (sys.argv[0], sourceBase)) - - print "Parsing and building renamers", + pyDestTemp = tempfile.mktemp('.tmp') + pyFile = open(pyDestTemp, "w") + pyFile.write(wxPythonTemplateStart % (sys.argv[0], modname)) + try: -## try: -## import libxml2 -## print "using libxml2..." -## ctxt = libxml2.createPushParser(ContentHandler(source, sourceBase, swigFile, pyFile), -## '', 0, xmlDest) -## for line in file(xmlDest): -## if not line: -## ctxt.parseChunck('', 0, 1) -## break -## ctxt.parseChunk(line, len(line), 0) - -## except ImportError: - print "using xml.sax..." - xml.sax.parse(xmlDest, ContentHandler(source, sourceBase, swigFile, pyFile)) + print "Parsing and building renamers", + if USE_LIBXML2: + processXML(xmlfile, modname, swigFile, pyFile) + else: + print "using xml.sax..." + xml.sax.parse(xmlfile, ContentHandler(modname, swigFile, pyFile)) finally: - checkOtherNames(pyFile, sourceBase, - os.path.join(sourcePath, '_'+sourceBase+'_reverse.txt')) + + checkOtherNames(pyFile, modname, + os.path.join(destdir, '_'+modname+'_reverse.txt')) pyFile.write(wxPythonTemplateEnd) pyFile.close() swigFile.write(renamerTemplateEnd) swigFile.close() - # Compare the file just created with the existing one and + # Compare the files just created with the existing one and # blow away the old one if they are different. - if open(swigDest).read() != open(swigDestTemp).read(): - os.unlink(swigDest) - os.rename(swigDestTemp, swigDest) - else: - print swigDest + " not changed." - os.unlink(swigDestTemp) + for dest, temp in [(swigDest, swigDestTemp), + (pyDest, pyDestTemp)]: + if not os.path.exists(dest): + os.rename(temp, dest) + elif open(dest).read() != open(temp).read(): + os.unlink(dest) + os.rename(temp, dest) + else: + print dest + " not changed." + os.unlink(temp) + +#--------------------------------------------------------------------------- + + +def GetAttr(node, name): + path = "./attributelist/attribute[@name='%s']/@value" % name + n = node.xpathEval2(path) + if len(n): + return n[0].content + else: + return None + + +def processXML(xmlfile, modname, swigFile, pyFile): + import libxml2 + print "using libxml2..." + + topnode = libxml2.parseFile(xmlfile).children + + # remove any import nodes as we don't need to do renamers for symbols found therein + imports = topnode.xpathEval2("*/import") + for n in imports: + n.unlinkNode() + n.freeNode() + + # do a depth first iteration over what's left + for node in topnode: + doRename = False + doPtr = False + addWX = False + revOnly = False - if DO_UNLINK: - os.unlink(xmlDest) + if node.name == "class": + lastClassName = name = GetAttr(node, "name") + lastClassSymName = sym_name = GetAttr(node, "sym_name") + doRename = True + doPtr = True + if sym_name != name: + name = sym_name + addWX = True + + # renamed constructors + elif node.name == "constructor": + name = GetAttr(node, "name") + sym_name = GetAttr(node, "sym_name") + if sym_name != name: + name = sym_name + addWX = True + doRename = True + + # only enumitems at the top level + elif node.name == "enumitem" and node.parent.parent.name == "include": + name = GetAttr(node, "name") + sym_name = GetAttr(node, "sym_name") + doRename = True + + + elif node.name in ["cdecl", "constant"]: + name = GetAttr(node, "name") + sym_name = GetAttr(node, "sym_name") + toplevel = node.parent.name == "include" + + # top-level functions + if toplevel and GetAttr(node, "view") == "globalfunctionHandler": + doRename = True + + # top-level global vars + elif toplevel and GetAttr(node, "feature_immutable") == "1": + doRename = True + + # static methods + elif GetAttr(node, "view") == "staticmemberfunctionHandler": + name = lastClassName + '_' + name + sym_name = lastClassSymName + '_' + sym_name + # only output the reverse renamer in this case + doRename = revOnly = True + + if doRename and name != sym_name: + name = sym_name + addWX = True + + + if doRename and name: + old = new = name + if old.startswith('wx') and not old.startswith('wxEVT_'): + # remove all wx prefixes except wxEVT_ and write a %rename directive for it + new = old[2:] + if not revOnly: + swigFile.write("%%rename(%s) %35s;\n" % (new, old)) + + # Write assignments to import into the old wxPython namespace + if addWX and not old.startswith('wx'): + old = 'wx'+old + pyFile.write("%s = wx.%s.%s\n" % (old, modname, new)) + if doPtr: + pyFile.write("%sPtr = wx.%s.%sPtr\n" % (old, modname, new)) + #--------------------------------------------------------------------------- @@ -304,10 +372,9 @@ class Element: #--------------------------------------------------------------------------- class ContentHandler(xml.sax.ContentHandler): - def __init__(self, source, sourceBase, swigFile, pyFile): + def __init__(self, modname, swigFile, pyFile): xml.sax.ContentHandler.__init__(self) - self.source = source - self.sourceBase = sourceBase + self.modname = modname self.swigFile = swigFile self.pyFile = pyFile self.elements = [] @@ -398,7 +465,7 @@ class ContentHandler(xml.sax.ContentHandler): if self.imports == 0: # only write for items that are in this file, not imported - ce.write(self.sourceBase, self.swigFile, self.pyFile) + ce.write(self.modname, self.swigFile, self.pyFile) if name == 'import': self.imports -= 1