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