]> git.saurik.com Git - wxWidgets.git/blob - docs/doxygen/scripts/doxymlparser.py
Added wxPropertyGrid::WasValueChangedInEvent(), added code to avoid showing colour...
[wxWidgets.git] / docs / doxygen / scripts / doxymlparser.py
1 """
2 Name: doxymlparser.py
3 Author: Kevin Ollivier
4 License: wxWidgets License
5 """
6
7 __description__ = """
8 Takes the output of Doxygen XML and parses it to retrieve metadata about the classes and methods.
9
10 To create the Doxygen XML files, from the wxWidgets/docs/doxygen directory, do:
11
12 ./regen.sh xml
13
14 To see the results from parsing a particular class, do:
15
16 python doxymlparser.py --report out/xml/classwx_<whatever>.xml
17 """
18
19 #!/usr/bin/env python
20 import optparse
21 import os
22 import string
23
24 import sys
25 import types
26
27 from common import *
28 from xml.dom import minidom
29
30 option_dict = {
31 "report" : (False, "Print out the classes and methods found by this script."),
32 "verbose" : (False, "Provide status updates and other information."),
33 }
34
35 parser = optparse.OptionParser(usage="usage: %prog [options] <doxyml files to parse>\n" + __description__, version="%prog 1.0")
36
37 for opt in option_dict:
38 default = option_dict[opt][0]
39
40 action = "store"
41 if type(default) == types.BooleanType:
42 action = "store_true"
43 parser.add_option("--" + opt, default=default, action=action, dest=opt, help=option_dict[opt][1])
44
45 options, arguments = parser.parse_args()
46
47 class ClassDefinition:
48 def __init__(self):
49 self.name = ""
50 self.constructors = []
51 self.destructors = []
52 self.methods = []
53 self.brief_description = ""
54 self.detailed_description = ""
55 self.includes = []
56 self.bases = []
57 self.enums = {}
58
59 def __str__(self):
60 str_repr = """
61 Class: %s
62 Bases: %s
63 Includes: %s
64 Brief Description:
65 %s
66
67 Detailed Description:
68 %s
69 """ % (self.name, string.join(self.bases, ", "), self.includes, self.brief_description, self.detailed_description)
70 str_repr += "Methods:\n"
71
72 for method in self.methods:
73 str_repr += str(method)
74
75 return str_repr
76
77 class MethodDefinition:
78 def __init__(self):
79 self.name = ""
80 self.return_type = ""
81 self.argsstring = ""
82 self.definition = ""
83 self.params = []
84 self.brief_description = ""
85 self.detailed_description = ""
86
87 def __str__(self):
88 str_repr = """
89 Method: %s
90 Return Type: %s
91 Params: %r
92 Prototype: %s
93 Brief Description:
94 %s
95
96 Detailed Description:
97 %s
98 """ % (self.name, self.return_type, self.params, self.definition + self.argsstring, self.brief_description, self.detailed_description)
99 return str_repr
100
101 def getTextValue(node, recursive=False):
102 text = ""
103 for child in node.childNodes:
104 if child.nodeType == child.ELEMENT_NODE and child.nodeName == "ref":
105 text += getTextValue(child)
106 if child.nodeType == child.TEXT_NODE:
107 # Add a space to ensure we have a space between qualifiers and parameter names
108 text += child.nodeValue.strip() + " "
109
110 return text.strip()
111
112 def doxyMLToText(node):
113 return text
114
115 class DoxyMLParser:
116 def __init__(self):
117 self.classes = []
118
119 def find_class(self, name):
120 for aclass in self.classes:
121 if aclass.name == name:
122 return aclass
123
124 return None
125
126 def get_enums_and_functions(self, filename, aclass):
127 file_path = os.path.dirname(filename)
128 enum_filename = os.path.join(file_path, aclass.name[2:] + "_8h.xml")
129 if os.path.exists(enum_filename):
130 root = minidom.parse(enum_filename).documentElement
131 for method in root.getElementsByTagName("memberdef"):
132 if method.getAttribute("kind") == "enum":
133 self.parse_enum(aclass, method, root)
134
135 def is_derived_from_base(self, aclass, abase):
136 base = get_first_value(aclass.bases)
137 while base and base != "":
138
139 if base == abase:
140 return True
141
142 parentclass = self.find_class(base)
143
144 if parentclass:
145 base = get_first_value(parentclass.bases)
146 else:
147 base = None
148
149 return False
150
151 def parse(self, filename):
152 self.xmldoc = minidom.parse(filename).documentElement
153 for node in self.xmldoc.getElementsByTagName("compounddef"):
154 new_class = self.parse_class(node)
155 self.classes.append(new_class)
156 self.get_enums_and_functions(filename, new_class)
157
158 def parse_class(self, class_node):
159 new_class = ClassDefinition()
160 new_class.name = getTextValue(class_node.getElementsByTagName("compoundname")[0])
161 for node in class_node.childNodes:
162 if node.nodeName == "basecompoundref":
163 new_class.bases.append(getTextValue(node))
164 elif node.nodeName == "briefdescription":
165 # let the post-processor determ
166 new_class.brief_description = node.toxml()
167 elif node.nodeName == "detaileddescription":
168 new_class.detailed_description = node.toxml()
169 elif node.nodeName == "includes":
170 new_class.includes.append(getTextValue(node))
171
172 self.parse_methods(new_class, class_node)
173
174 return new_class
175
176 def parse_enum(self, new_class, enum, root):
177 enum_name = ""
178 enum_values = []
179
180 for node in enum.childNodes:
181 if node.nodeName == "name":
182 enum_name = getTextValue(node)
183 elif node.nodeName == "enumvalue":
184 enum_values.append(getTextValue(node.getElementsByTagName("name")[0]))
185
186 new_class.enums[enum_name] = enum_values
187
188 def parse_methods(self, new_class, root):
189 for method in root.getElementsByTagName("memberdef"):
190 new_method = MethodDefinition()
191 for node in method.childNodes:
192 if node.nodeName == "name":
193 new_method.name = getTextValue(node)
194 elif node.nodeName == "type":
195 new_method.return_type = getTextValue(node)
196 elif node.nodeName == "definition":
197 new_method.definition = getTextValue(node)
198 elif node.nodeName == "argsstring":
199 new_method.argsstring = getTextValue(node)
200 elif node.nodeName == "param":
201 param = {}
202 for child in node.childNodes:
203 if child.nodeType == child.ELEMENT_NODE:
204 param[child.nodeName] = getTextValue(child)
205 new_method.params.append(param)
206
207 if options.verbose:
208 print "Adding %s" % (new_method.name + new_method.argsstring)
209
210 if new_method.name == new_class.name:
211 new_class.constructors.append(new_method)
212 elif new_method.name == "~" + new_class.name:
213 new_class.destructors.append(new_method)
214 else:
215 new_class.methods.append(new_method)
216
217 if __name__ == "__main__":
218 if len(arguments) < 1:
219 parser.print_usage()
220 sys.exit(1)
221
222 doxyparse = DoxyMLParser()
223 for arg in arguments:
224 doxyparse.parse(arg)
225
226 if options.report:
227 for aclass in doxyparse.classes:
228 print str(aclass)
229