forked from rizinorg/cutter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapidoc.py
136 lines (103 loc) · 4 KB
/
apidoc.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# -*- coding: utf-8 -*-
import os
import sys
import errno
import xml.etree.ElementTree
ALLOWED_TYPES = ['class', 'interface', 'struct', 'union']
def write_file(name, text, destdir):
"""Write the output file for module/package <name>."""
fname = os.path.join(destdir, '%s.%s' % (name, 'rst'))
if not os.path.exists(os.path.dirname(fname)):
try:
os.makedirs(os.path.dirname(fname))
except OSError as exc: # Guard against race condition
if exc.errno != errno.EEXIST:
raise
try:
with open(fname, 'r') as target:
orig = target.read()
if orig == text:
return
except FileNotFoundError:
# Don't mind if it isn't there
pass
with open(fname, 'w') as target:
target.write(text)
def format_heading(level, text):
"""Create a heading of <level> [1, 2 or 3 supported]."""
underlining = ['=', '-', '~', ][level - 1] * len(text)
return '%s\n%s\n\n' % (text, underlining)
def format_directive(package_type, package, project = None):
"""Create the breathe directive and add the options."""
directive = '.. doxygen%s:: %s\n' % (package_type, package)
if project:
directive += ' :project: %s\n' % project
return directive
def create_package_file(package, package_type, package_id, package_folder, rootpath, destdir):
"""Build the text of the file and write the file."""
text = format_heading(1, '%s' % (package))
text += format_directive(package_type, package)
xmlfile = os.path.join(rootpath, package_id + '.xml')
f = xml.etree.ElementTree.parse(os.path.join(xmlfile))
write_file(os.path.join(package_folder, package_id), text, destdir)
def create_modules_toc_file(key, value, destdir):
"""Create the module's index."""
text = format_heading(1, '%s' % value)
text += '.. toctree::\n'
text += ' :glob:\n\n'
text += ' %s/*\n' % key
write_file('%slist' % key, text, destdir)
def get_compound_folder(rootpath, compound):
fxml = xml.etree.ElementTree.parse(os.path.join(rootpath, compound.get('refid')) + '.xml')
loc = fxml.getroot()[0].find('location')
dirname = os.path.basename(os.path.split(loc.get('file'))[0])
return dirname
def recurse_tree(rootpath, destdir):
"""
Look for every file in the directory tree and create the corresponding
ReST files.
"""
index = xml.etree.ElementTree.parse(os.path.join(rootpath, 'index.xml'))
for compound in index.getroot():
if compound.get('kind') not in ALLOWED_TYPES:
continue
create_package_file(compound.findtext('name'), compound.get('kind'),
compound.get('refid'), get_compound_folder(rootpath, compound),
rootpath, destdir)
def get_folders_tree(rootpath):
tmp = []
# Retrieve the subfolders indexes
for root, _, files in os.walk(rootpath):
for xmlfile in files:
if not xmlfile.startswith('dir_'):
continue
tmp.append(xmlfile)
# Iterate on them
dirs = []
for xmlfile in tmp:
data = xml.etree.ElementTree.parse(os.path.join(rootpath, xmlfile))
if not data:
continue
for compound in data.getroot():
name = compound.findtext('compoundname')
dirs.append(name)
return dirs
def main():
rootpath = './doxygen-out/xml'
destdir = './source/api'
if not os.path.exists(destdir):
os.makedirs(destdir)
dirs = sorted(get_folders_tree(rootpath))
source_root = dirs[0]
source_dirs = dirs[1:]
out_dirs = [os.path.basename(d) for d in dirs]
# TODO Handle only one level subfolders
for key in out_dirs:
ddir = os.path.join(destdir, key)
if not os.path.exists(ddir):
os.makedirs(ddir)
create_modules_toc_file(key, key.capitalize(), destdir)
recurse_tree(rootpath, destdir)
# So program can be started with "python -m breathe.apidoc ..."
if __name__ == "__main__":
main()