]> git.saurik.com Git - wxWidgets.git/blame - wxPython/docs/bin/simplify.py
Fix to wxChar* access.
[wxWidgets.git] / wxPython / docs / bin / simplify.py
CommitLineData
685d8985
RD
1#!/usr/bin/python
2#---------------------------------------------------------------------------
3#
4# Like simplify.xsl but using Python so a few non-standard conversions can
5# also be done. (Currently it is still about the same as simplify.xsl...)
6#
7#---------------------------------------------------------------------------
8
9import sys
10import os
11import libxml2
12
13
14DEST="docs/xml/wxPython-metadata.xml"
15SRC="docs/xml-raw"
16
17
6f401080
RD
18classMap = {
19 'wxString' : 'String',
20 'void' : '',
21 }
22
685d8985
RD
23
24def getModuleNames():
25 """
26 Get the list of extension modules from setup.py
27 """
28 import setup
29 names = [e.name[1:] for e in setup.wxpExtensions]
30 return names
31
32
33
34def getAttr(node, name):
35 """
36 Get a value by name from the <attribute> elements in the SWIG XML output
37 """
38 path = "./attributelist/attribute[@name='%s']/@value" % name
39 n = node.xpathEval2(path)
40 if len(n):
41 return n[0].content
42 else:
43 return None
44
45
6f401080
RD
46def fixType(typeStr):
47 """
48 Fixup type string, dropping the swig pointer and other flags
49 """
50 pos = typeStr.rfind('.')
51 if pos != -1:
52 typeStr = typeStr[pos+1:]
53 return classMap.get(typeStr, typeStr)
685d8985
RD
54
55
56def processModule(newDocNode, modulename):
57 """
58 Start processing a new XML file, create a module element and then
59 find the include elements
60 """
61 filename = os.path.join(SRC, "%s_swig.xml" % modulename)
62 print filename
63
64 doc = libxml2.parseFile(filename)
65 topNode = doc.getRootElement()
66
67 # make a module element
68 name = getAttr(topNode, "module")
69 assert name == modulename # sanity check
70
71 moduleNode = libxml2.newNode("module")
72 moduleNode.setProp("name", name)
73 newDocNode.addChild(moduleNode)
74
75 node = topNode.children
76 while node is not None:
77 if node.name == "include":
0dd25e81 78 processInclude(moduleNode, node)
685d8985
RD
79 node = node.next
80
81 doc.freeDoc()
82
83
84
0dd25e81 85def processInclude(moduleNode, includeNode):
685d8985
RD
86 """
87 Almost everything we are interested in is inside an <include>,
88 which may also be nested.
89 """
90
91 # check first for imports
92 for node in includeNode.xpathEval2("import"):
93 try:
94 modNode = node.xpathEval2("module")[0]
95 name = getAttr(modNode, "name")
96 impNode = libxml2.newNode("import")
97 impNode.setProp("name", name)
98 moduleNode.addChild(impNode)
99 except IndexError:
100 pass
101
102 # then look through the child nodes for other things we need
103 node = includeNode.children
104 while node is not None:
105 if node.name == "insert":
0dd25e81 106 processInsert(moduleNode, node)
685d8985
RD
107
108 elif node.name == "class":
0dd25e81 109 processClass(moduleNode, node)
685d8985
RD
110
111 elif node.name == "cdecl" and getAttr(node, "view") == "globalfunctionHandler":
112 func = libxml2.newNode("method")
113 func.setProp("name", getAttr(node, "sym_name"))
114 func.setProp("oldname", getAttr(node, "name"))
6f401080 115 func.setProp("type", fixType(getAttr(node, "type")))
685d8985
RD
116 doCheckOverloaded(func, node)
117 doDocStrings(func, node)
118 doParamList(func, node)
119 moduleNode.addChild(func)
120
121
122 elif node.name == "include":
0dd25e81 123 processInclude(moduleNode, node)
685d8985
RD
124
125 node = node.next
126
127
128
0dd25e81 129def processInsert(parentNode, insertNode):
685d8985
RD
130 """
131 Check for pythoncode
132 """
133 if getAttr(insertNode, "section") == "python":
134 code = getAttr(insertNode, "code")
135 node = libxml2.newNode("pythoncode")
136 node.addChild(libxml2.newText(code))
137 parentNode.addChild(node)
138
139
140
0dd25e81 141def processClass(parentNode, classNode):
685d8985
RD
142 """
143 Handle classes, constructors, methods, etc.
144 """
145 # make class element
146 klass = libxml2.newNode("class")
6f401080
RD
147 name = getAttr(classNode, "sym_name")
148 oldname = getAttr(classNode, "name")
149 classMap[oldname] = name
150 klass.setProp("name", name)
151 klass.setProp("oldname", oldname)
685d8985
RD
152 klass.setProp("module", getAttr(classNode, "module"))
153 doDocStrings(klass, classNode)
154 parentNode.addChild(klass)
155
156 # check for baseclass(es)
157 for node in classNode.xpathEval2("attributelist/baselist/base"):
158 baseclass = libxml2.newNode("baseclass")
6f401080
RD
159 basename = node.prop("name")
160 baseclass.setProp("name", classMap.get(basename, basename))
685d8985
RD
161 klass.addChild(baseclass)
162
163 # check for constructors/destructors
164 for type in ["constructor", "destructor"]:
165 for node in classNode.xpathEval2("%s | extend/%s" % (type, type)):
166 func = libxml2.newNode(type)
167 func.setProp("name", getAttr(node, "sym_name"))
168 if parentNode.name != "destructor":
169 doCheckOverloaded(func, node)
170 doDocStrings(func, node)
171 doParamList(func, node)
172 klass.addChild(func)
173
174 # check for cdecl's. In class scope we are interested in methods,
175 # static methods, or properties
176 for node in classNode.xpathEval2("cdecl | extend/cdecl"):
177 view = getAttr(node, "view")
178 if view == "memberfunctionHandler":
179 func = libxml2.newNode("method")
180 func.setProp("name", getAttr(node, "sym_name"))
6f401080 181 func.setProp("type", fixType(getAttr(node, "type")))
685d8985
RD
182 doCheckOverloaded(func, node)
183 doDocStrings(func, node)
184 doParamList(func, node)
185 klass.addChild(func)
186
187 elif view == "staticmemberfunctionHandler":
188 func = libxml2.newNode("staticmethod")
189 func.setProp("name", getAttr(node, "sym_name"))
6f401080 190 func.setProp("type", fixType(getAttr(node, "type")))
685d8985
RD
191 doCheckOverloaded(func, node)
192 doDocStrings(func, node)
193 doParamList(func, node)
194 klass.addChild(func)
195
196 elif view == "variableHandler":
197 prop = libxml2.newNode("property")
198 prop.setProp("name", getAttr(node, "sym_name"))
6f401080 199 prop.setProp("type", fixType(getAttr(node, "type")))
685d8985
RD
200 if getAttr(node, "feature_immutable"):
201 prop.setProp("readonly", "yes")
202 else:
203 prop.setProp("readonly", "no")
204 doDocStrings(prop, node)
205 klass.addChild(prop)
206
207
208
209def doParamList(parentNode, srcNode):
210 """
211 Convert the parameter list
212 """
213 params = srcNode.xpathEval2("attributelist/parmlist/parm")
214 if params:
215 plist = libxml2.newNode("paramlist")
216 for p in params:
217 pnode = libxml2.newNode("param")
6f401080
RD
218 pnode.setProp("name", getAttr(p, "name"))
219 pnode.setProp("type", fixType(getAttr(p, "type")))
685d8985
RD
220 pnode.setProp("default", getAttr(p, "value"))
221 plist.addChild(pnode)
222 parentNode.addChild(plist)
223
224
225
226def doCheckOverloaded(parentNode, srcNode):
227 """
228 Set an attribute indicating if the srcNode is tagged as being overloaded
229 """
230 if srcNode.xpathEval2("./attributelist/attribute[@name='sym_overloaded']"):
231 parentNode.setProp("overloaded", "yes")
232 else:
233 parentNode.setProp("overloaded", "no")
234
235
236
237def doDocStrings(parentNode, srcNode):
238 """
239 Check for the various possible docstring attributes, and attach
240 coresponding child nodes if found.
241 """
242 def makeDocElement(name, content):
243 node = libxml2.newNode(name)
244 node.addChild(libxml2.newText(content))
245 return node
246
247 autodoc = getAttr(srcNode, "python_autodoc")
248 docstr = getAttr(srcNode, "feature_docstring")
685d8985
RD
249 if autodoc:
250 parentNode.addChild(makeDocElement("autodoc", autodoc))
251 if docstr:
252 parentNode.addChild(makeDocElement("docstring", docstr))
685d8985
RD
253
254
255
256
257
258def main():
259 if not os.path.exists(SRC):
260 print "Unable to find %s, please run this script from the root wxPython directory." % SRC
261 sys.exit(1)
262
263 newDoc = libxml2.newDoc("1.0")
264 newTopNode = libxml2.newNode("wxPython-metadata")
265 newDoc.addChild(newTopNode)
266
267 for m in getModuleNames():
268 processModule(newTopNode, m)
269
270 newDoc.saveFormatFile(DEST, True)
6f401080 271 print "Wrote simplified metadata to", DEST
685d8985
RD
272
273#---------------------------------------------------------------------------
274
275if __name__ == "__main__":
276 main()