-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathosi_doxygen_xml.py
112 lines (90 loc) · 3.59 KB
/
osi_doxygen_xml.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
"""
This module carry the XML version of Doxygen documentation to parse the rules
into it.
"""
import os
import glob
import ruamel.yaml as yaml
import defusedxml.ElementTree as ET
from doxygen import ConfigParser
from doxygen import Generator
class OSIDoxygenXML:
"""
This class creates XML from \*.proto Files Documentation of OSI and can parse the rules from it.
"""
def __init__(self):
dir_path = os.path.dirname(os.path.realpath(__file__))
osivalidator_path = os.path.dirname(dir_path)
self.osi_path = os.path.join(osivalidator_path, "open-simulation-interface")
self.osi_doc_path = os.path.join(self.osi_path, "doc")
proto2cpp_path = os.path.join(osivalidator_path, "proto2cpp")
self.proto2cpp_file_path = os.path.join(proto2cpp_path, "proto2cpp.py")
def generate_osi_doxygen_xml(self):
"""
Generate the Doxygen XML documentation in the OSI path
"""
configuration = f"""
PROJECT_NAME = osi-validation
INPUT = {self.osi_path}
OUTPUT_DIRECTORY = {self.osi_doc_path}
EXTENSION_MAPPING = proto=C++
FILE_PATTERNS = *.proto
INPUT_FILTER = "python {self.proto2cpp_file_path}"
GENERATE_XML = YES
GENERATE_HTML = YES
MAX_DOT_GRAPH_DEPTH = 2
RECURSIVE = YES
GENERATE_LATEX = NO
XML_PROGRAMLISTING = NO
ALIASES = rules="<pre class=\"rules\">"
ALIASES += endrules="</pre>"
"""
doxyfile_path = os.path.join(self.osi_path, "Doxyfile_validation")
doxyfile = open(doxyfile_path, "w")
doxyfile.write(configuration)
doxyfile.close()
config_parser = ConfigParser()
config_parser.load_configuration(doxyfile_path)
doxy_builder = Generator(doxyfile_path)
doxy_builder.build(clean=False, generate_zip=False)
def get_files(self):
"""
Return the path of the fields in OSI
"""
return glob.glob(os.path.join(self.osi_path, "doc", "xml", "*.xml"))
def parse_rules(self):
"""
Parse the Doxygen XML documentation to get the rules
"""
xml_files = self.get_files()
rules = list()
for xml_file in xml_files:
tree = ET.parse(xml_file)
memberdefs = tree.findall(
"./compounddef/sectiondef/memberdef[@kind='variable']"
)
for memberdef in memberdefs:
attr_path = memberdef.findtext("definition").split()[-1].split("::")
if attr_path[0] != "osi3":
continue
attr_path.pop(0)
attr_rule = memberdef.findtext(
"./detaileddescription//preformatted[last()]"
)
if not attr_rule:
continue
rules_lines = attr_rule.split("\n")
for line_no, line in enumerate(rules_lines):
if line.find(":") == -1 and line:
rules_lines[line_no] += ":"
attr_rule = "\n".join(rules_lines)
try:
dict_rules = yaml.safe_load(attr_rule)
except (yaml.parser.ParserError, yaml.parser.ScannerError) as error:
print(attr_path, attr_rule, error)
else:
rules.append((attr_path, dict_rules))
return rules
if __name__ == "__main__":
osidx = OSIDoxygenXML()
osidx.generate_osi_doxygen_xml()