]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distrib/build_renamers.py
03f043a8d60e8b86ce2536fece78a6ffc3ebd816
2 #---------------------------------------------------------------------------
4 Usage: build_renamers.py filename.i
6 Run SWIG on file.i using the XML language module and then scan the XML
7 file produced and generate the %rename directives needed to implement
8 the new wx namespace. The rename directives are output in a file
9 named _filename_rename.i in the same dir as filename.i.
11 Also output a reverse 'renamer' Python module located in
12 wxPython/filename.py (relative the the current dir) to make a
13 backwards compatibility interface for the old wxPython packages.
16 import sys
, os
, tempfile
, pprint
18 from distutils
.spawn
import spawn
22 #---------------------------------------------------------------------------
26 wxPythonDir
= "wxPython"
27 swig_cmd
= "/opt/swig/bin/swig"
29 swig_cmd
= 'e:/projects/SWIG-cvs/swig.exe'
43 renamerTemplateStart
= """\
44 // A bunch of %%rename directives generated by %s
45 // in order to remove the wx prefix from all global scope names.
51 renamerTemplateEnd
= """
55 wxPythonTemplateStart
= """\
56 ## This file reverse renames symbols in the wx package to give
57 ## them their wx prefix again, for backwards compatibility.
61 # This silly stuff here is so the wxPython.wx module doesn't conflict
62 # with the wx package. We need to import modules from the wx package
63 # here, then we'll put the wxPython.wx entry back in sys.modules.
66 if sys.modules.has_key('wxPython.wx'):
67 _wx = sys.modules['wxPython.wx']
68 del sys.modules['wxPython.wx']
72 sys.modules['wxPython.wx'] = _wx
76 # Now assign all the reverse-renamed names:
79 wxPythonTemplateEnd
= """
85 #---------------------------------------------------------------------------
93 # check location (there should be a wxPython subdir)
94 if not os
.path
.exists(wxPythonDir
) or not os
.path
.isdir(wxPythonDir
):
96 print "You should only run this script from the main wxPython source dir.\n"
101 sourcePath
, sourceBase
= os
.path
.split(source
)
102 sourceBase
= os
.path
.splitext(sourceBase
)[0]
104 tempfile
.tempdir
= sourcePath
105 xmlDest
= tempfile
.mktemp('.xml')
106 swigDest
= os
.path
.join(sourcePath
, "_"+sourceBase
+"_rename.i")
107 pyDest
= os
.path
.join(wxPythonDir
, sourceBase
+ '.py')
109 #print "source: ", source
110 #print "xmlDest: ", xmlDest
111 #print "swigDest: ", swigDest
112 #print "pyDest: ", pyDest
114 cmd
= [ swig_cmd
] + swig_args
+ args
[1:] + ['-I'+sourcePath
, '-o', xmlDest
, source
]
118 swigDestTemp
= tempfile
.mktemp('.tmp')
119 swigFile
= open(swigDestTemp
, "w")
120 swigFile
.write(renamerTemplateStart
% sys
.argv
[0])
122 pyFile
= open(pyDest
, "w")
123 pyFile
.write(wxPythonTemplateStart
% (sys
.argv
[0], sourceBase
))
125 print "Parsing and building renamers",
129 ## print "using libxml2..."
130 ## ctxt = libxml2.createPushParser(ContentHandler(source, sourceBase, swigFile, pyFile),
132 ## for line in file(xmlDest):
134 ## ctxt.parseChunck('', 0, 1)
136 ## ctxt.parseChunk(line, len(line), 0)
138 ## except ImportError:
139 print "using xml.sax..."
140 xml
.sax
.parse(xmlDest
, ContentHandler(source
, sourceBase
, swigFile
, pyFile
))
143 checkOtherNames(pyFile
, sourceBase
,
144 os
.path
.join(sourcePath
, '_'+sourceBase
+'_reverse.txt'))
145 pyFile
.write(wxPythonTemplateEnd
)
148 swigFile
.write(renamerTemplateEnd
)
151 # Compare the file just created with the existing one and
152 # blow away the old one if they are different.
153 if open(swigDest
).read() != open(swigDestTemp
).read():
155 os
.rename(swigDestTemp
, swigDest
)
157 print swigDest
+ " not changed."
158 os
.unlink(swigDestTemp
)
164 #---------------------------------------------------------------------------
166 def checkOtherNames(pyFile
, moduleName
, filename
):
167 if os
.path
.exists(filename
):
169 for line
in file(filename
):
170 if line
.endswith('\n'):
172 if line
and not line
.startswith('#'):
173 if line
.endswith('*'):
174 prefixes
.append(line
[:-1])
175 elif line
.find('=') != -1:
176 pyFile
.write("%s\n" % line
)
179 if line
.startswith('wx') or line
.startswith('WX') or line
.startswith('EVT'):
181 pyFile
.write("%s = wx.%s.%s\n" % (wxname
, moduleName
, line
))
185 "\n\nd = globals()\nfor k, v in wx.%s.__dict__.iteritems():"
190 pyFile
.write("\n if ")
193 pyFile
.write("\n elif ")
194 pyFile
.write("k.startswith('%s'):\n d[k] = v" % p
)
195 pyFile
.write("\ndel d, k, v\n\n")
198 #---------------------------------------------------------------------------
200 interestingTypes
= [ 'class', 'cdecl', 'enumitem', 'constructor', 'constant' ]
201 interestingAttrs
= [ 'name', 'sym_name', 'decl', 'feature_immutable', 'module',
206 def __init__(self
, tagtype
):
207 self
.tagtype
= tagtype
212 self
.immutable
= None
220 def write(self
, moduleName
, swigFile
, pyFile
):
226 #if self.name.find('DefaultPosition') != -1:
227 # pprint.pprint(self.__dict__)
229 if self
.tagtype
in ['cdecl', 'constant']:
230 if self
.storage
== 'typedef':
233 # top level functions
234 elif self
.level
== 0 and self
.decl
!= "":
237 # top level global vars
238 elif self
.level
== 0 and self
.immutable
== '1':
242 elif self
.storage
== 'static':
244 pprint
.pprint(self
.__dict
__)
246 self
.name
= self
.klass
+ '_' + self
.name
247 self
.sym_name
= self
.sym_klass
+ '_' + self
.sym_name
248 # only output the reverse renamer in this case
249 doRename
= revOnly
= True
253 if doRename
and self
.name
!= self
.sym_name
:
254 #print "%-25s %-25s" % (self.name, self.sym_name)
255 self
.name
= self
.sym_name
259 elif self
.tagtype
== 'class' and self
.module
== moduleName
:
262 if self
.sym_name
!= self
.klass
:
264 self
.name
= self
.sym_name
267 elif self
.tagtype
== 'constructor':
268 #print "%-25s %-25s" % (self.name, self.sym_name)
269 if self
.sym_name
!= self
.klass
:
271 self
.name
= self
.sym_name
275 elif self
.tagtype
== 'enumitem' and self
.level
== 0:
280 #print "%-25s %-25s" % (self.name, self.sym_name)
281 old
= new
= self
.name
282 if old
.startswith('wx') and not old
.startswith('wxEVT_'):
283 # remove all wx prefixes except wxEVT_ and write a %rename directive for it
286 swigFile
.write("%%rename(%s) %35s;\n" % (new
, old
))
288 # Write assignments to import into the old wxPython namespace
289 if addWX
and not old
.startswith('wx'):
291 pyFile
.write("%s = wx.%s.%s\n" % (old
, moduleName
, new
))
293 pyFile
.write("%sPtr = wx.%s.%sPtr\n" % (old
, moduleName
, new
))
298 # text = "%07d %d %10s %-35s %s\n" % (
299 # self.startLine, self.level, self.tagtype, self.name, self.decl)
300 # #rejects.write(text)
304 #---------------------------------------------------------------------------
306 class ContentHandler(xml
.sax
.ContentHandler
):
307 def __init__(self
, source
, sourceBase
, swigFile
, pyFile
):
308 xml
.sax
.ContentHandler
.__init
__(self
)
310 self
.sourceBase
= sourceBase
311 self
.swigFile
= swigFile
316 self
.sym_klass
= None
319 def setDocumentLocator(self
, locator
):
320 self
.locator
= locator
324 def startElement(self
, name
, attrs
):
325 if name
in interestingTypes
:
326 # start of a new element that we are interested in
328 ce
.startLine
= self
.locator
.getLineNumber()
329 ce
.level
= len(self
.elements
)
330 if name
== 'constructor':
331 ce
.klass
= self
.elements
[0].name
333 ce
.klass
= self
.klass
334 ce
.sym_klass
= self
.sym_klass
335 self
.elements
.insert(0, ce
)
338 elif len(self
.elements
) and name
== 'attribute' and attrs
['name'] in interestingAttrs
:
339 attrName
= attrs
['name']
340 attrVal
= attrs
['value']
341 if attrName
.startswith('feature_'):
342 attrName
= attrName
.replace('feature_', '')
343 ce
= self
.elements
[0]
344 if getattr(ce
, attrName
) is None:
345 setattr(ce
, attrName
, attrVal
)
346 if ce
.tagtype
== 'class' and attrName
== 'name' and self
.klass
is None:
348 if ce
.tagtype
== 'class' and attrName
== 'sym_name' and self
.sym_klass
is None:
349 self
.sym_klass
= attrVal
352 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'name':
353 ## # save the elements name
354 ## ce = self.elements[0]
355 ## if ce.name is None:
356 ## ce.name = attrs['value']
357 ## ce.nameLine = self.locator.getLineNumber()
359 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'sym_name':
360 ## # save the elements name
361 ## ce = self.elements[0]
362 ## if ce.sym_name is None:
363 ## ce.sym_name = attrs['value']
365 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'decl':
366 ## # save the elements decl
367 ## ce = self.elements[0]
368 ## ce.decl = attrs['value']
370 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'feature_immutable':
371 ## # save the elements decl
372 ## ce = self.elements[0]
373 ## ce.immutable = int(attrs['value'])
375 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'module':
376 ## # save the elements decl
377 ## ce = self.elements[0]
378 ## ce.module = attrs['value']
380 elif name
== 'import':
383 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'storage':
384 ## # save the elements decl
385 ## ce = self.elements[0]
386 ## ce.storage = attrs['value']
388 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'type':
389 ## # save the elements decl
390 ## ce = self.elements[0]
391 ## ce.type = attrs['value']
394 def endElement(self
, name
):
395 if name
in interestingTypes
:
396 # end of an element that we are interested in
397 ce
= self
.elements
.pop(0)
399 if self
.imports
== 0:
400 # only write for items that are in this file, not imported
401 ce
.write(self
.sourceBase
, self
.swigFile
, self
.pyFile
)
408 self
.sym_klass
= None
411 #---------------------------------------------------------------------------
413 if __name__
== "__main__":