mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-21 12:26:11 +00:00
137 lines
4.0 KiB
Python
137 lines
4.0 KiB
Python
# -*- 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()
|