]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distrib/build_renamers.py
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
):
225 #if self.name.find('DefaultPosition') != -1:
226 # pprint.pprint(self.__dict__)
228 if self
.tagtype
in ['cdecl', 'constant']:
229 if self
.storage
== 'typedef':
232 # top level functions
233 elif self
.level
== 0 and self
.decl
!= "":
236 # top level global vars
237 elif self
.level
== 0 and self
.immutable
== '1':
241 elif self
.storage
== 'static':
243 pprint
.pprint(self
.__dict
__)
245 self
.name
= self
.klass
+ '_' + self
.name
246 self
.sym_name
= self
.sym_klass
+ '_' + self
.sym_name
247 # only output the reverse renamer in this case
248 doRename
= revOnly
= True
252 if doRename
and self
.name
!= self
.sym_name
:
253 #print "%-25s %-25s" % (self.name, self.sym_name)
254 self
.name
= self
.sym_name
258 elif self
.tagtype
== 'class' and self
.module
== moduleName
:
260 if self
.sym_name
!= self
.klass
:
262 self
.name
= self
.sym_name
265 elif self
.tagtype
== 'constructor':
266 #print "%-25s %-25s" % (self.name, self.sym_name)
267 if self
.sym_name
!= self
.klass
:
269 self
.name
= self
.sym_name
273 elif self
.tagtype
== 'enumitem' and self
.level
== 0:
278 #print "%-25s %-25s" % (self.name, self.sym_name)
279 old
= new
= self
.name
280 if old
.startswith('wx') and not old
.startswith('wxEVT_'):
281 # remove all wx prefixes except wxEVT_ and write a %rename directive for it
284 swigFile
.write("%%rename(%s) %35s;\n" % (new
, old
))
286 # Write assignments to import into the old wxPython namespace
287 if addWX
and not old
.startswith('wx'):
289 pyFile
.write("%s = wx.%s.%s\n" % (old
, moduleName
, new
))
293 # text = "%07d %d %10s %-35s %s\n" % (
294 # self.startLine, self.level, self.tagtype, self.name, self.decl)
295 # #rejects.write(text)
299 #---------------------------------------------------------------------------
301 class ContentHandler(xml
.sax
.ContentHandler
):
302 def __init__(self
, source
, sourceBase
, swigFile
, pyFile
):
303 xml
.sax
.ContentHandler
.__init
__(self
)
305 self
.sourceBase
= sourceBase
306 self
.swigFile
= swigFile
311 self
.sym_klass
= None
314 def setDocumentLocator(self
, locator
):
315 self
.locator
= locator
319 def startElement(self
, name
, attrs
):
320 if name
in interestingTypes
:
321 # start of a new element that we are interested in
323 ce
.startLine
= self
.locator
.getLineNumber()
324 ce
.level
= len(self
.elements
)
325 if name
== 'constructor':
326 ce
.klass
= self
.elements
[0].name
328 ce
.klass
= self
.klass
329 ce
.sym_klass
= self
.sym_klass
330 self
.elements
.insert(0, ce
)
333 elif len(self
.elements
) and name
== 'attribute' and attrs
['name'] in interestingAttrs
:
334 attrName
= attrs
['name']
335 attrVal
= attrs
['value']
336 if attrName
.startswith('feature_'):
337 attrName
= attrName
.replace('feature_', '')
338 ce
= self
.elements
[0]
339 if getattr(ce
, attrName
) is None:
340 setattr(ce
, attrName
, attrVal
)
341 if ce
.tagtype
== 'class' and attrName
== 'name' and self
.klass
is None:
343 if ce
.tagtype
== 'class' and attrName
== 'sym_name' and self
.sym_klass
is None:
344 self
.sym_klass
= attrVal
347 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'name':
348 ## # save the elements name
349 ## ce = self.elements[0]
350 ## if ce.name is None:
351 ## ce.name = attrs['value']
352 ## ce.nameLine = self.locator.getLineNumber()
354 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'sym_name':
355 ## # save the elements name
356 ## ce = self.elements[0]
357 ## if ce.sym_name is None:
358 ## ce.sym_name = attrs['value']
360 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'decl':
361 ## # save the elements decl
362 ## ce = self.elements[0]
363 ## ce.decl = attrs['value']
365 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'feature_immutable':
366 ## # save the elements decl
367 ## ce = self.elements[0]
368 ## ce.immutable = int(attrs['value'])
370 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'module':
371 ## # save the elements decl
372 ## ce = self.elements[0]
373 ## ce.module = attrs['value']
375 elif name
== 'import':
378 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'storage':
379 ## # save the elements decl
380 ## ce = self.elements[0]
381 ## ce.storage = attrs['value']
383 ## elif len(self.elements) and name == 'attribute' and attrs['name'] == 'type':
384 ## # save the elements decl
385 ## ce = self.elements[0]
386 ## ce.type = attrs['value']
389 def endElement(self
, name
):
390 if name
in interestingTypes
:
391 # end of an element that we are interested in
392 ce
= self
.elements
.pop(0)
394 if self
.imports
== 0:
395 # only write for items that are in this file, not imported
396 ce
.write(self
.sourceBase
, self
.swigFile
, self
.pyFile
)
403 self
.sym_klass
= None
406 #---------------------------------------------------------------------------
408 if __name__
== "__main__":