from __future__ import print_function
import os
import textwrap
import xml.etree.ElementTree as ET
def join_all_element_text(el, sep=""):
bits = []
for txt in el.itertext():
bits.append(txt)
return sep.join(bits)
def remove_empty_header_or_footer_lines(lines):
while lines and not lines[0].strip():
lines = lines[1:]
while lines and not lines[-1].strip():
lines = lines[:-1]
return lines
class text_context_t:
def __init__(self):
self.tokens = [] # pending to be textwrap'd
self.lines = [] # already textwrap'd
def add_token_nostrip(self, token):
if token:
self.tokens.append(token)
def add_token(self, token):
if token:
return self.add_token_nostrip(token.strip())
def add_line(self, line):
self.lines.append(line)
def wrap_flush(self):
if self.tokens:
lines = textwrap.wrap("".join(self.tokens))
self.lines.extend(lines)
self.tokens = []
def _get_text_with_refs1(ctx, node):
process_children = True
if node.tag == "simplesect" and node.attrib.get("kind") == "return":
return
if node.tag == "parameterlist":
return
if node.tag == "ref":
ctx.add_token_nostrip(" '%s' " % node.text)
elif node.tag == "lsquo":
ctx.add_token_nostrip(" `")
elif node.tag == "rsquo":
ctx.add_token_nostrip("' ")
elif node.tag == "sp":
ctx.add_token_nostrip(" ")
elif node.tag == "computeroutput":
for child in node:
tmp = text_context_t()
_get_text_with_refs1(tmp, child)
ctx.add_token_nostrip("".join(tmp.tokens))
txt = (node.text or "").strip()
if txt:
ctx.add_token_nostrip(" '%s' " % txt)
elif node.tag == "programlisting":
ctx.wrap_flush()
ctx.add_line("")
for child in node:
if child.tag == "codeline":
tmp = text_context_t()
_get_text_with_refs1(tmp, child)
code_line = "".join(tmp.tokens)
ctx.add_line(code_line)
ctx.add_line("")
process_children = False
else:
ctx.add_token(node.text)
ctx.add_token(node.tail)
if process_children:
for child in node:
_get_text_with_refs1(ctx, child)
def get_element_description(el, child_tag):
out = []
for child in el.findall("./%s" % child_tag):
ctx = text_context_t()
_get_text_with_refs1(ctx, child)
ctx.wrap_flush()
if ctx.lines:
out.extend(ctx.lines)
out = remove_empty_header_or_footer_lines(out)
if out:
out0 = out[0]
if out0.startswith("ui:"):
out0 = out0[3:]
if out0.startswith("cb:"):
out0 = out0[3:]
out0 = out0.lstrip()
out[0] = out0
return out
def load_xml_for_module(xml_dir_path, module_name, or_dummy=True):
xml_tree = ET.Element("dummy") if or_dummy else None
for sfx in ["_8hpp", "_8h"]:
xml_path = os.path.join(xml_dir_path, "%s%s.xml" % (module_name, sfx))
if os.path.isfile(xml_path):
with open(xml_path) as fin:
xml_tree = ET.fromstring(fin.read())
return xml_tree
def load_xml_for_udt(xml_dir_path, xml_tree, udt_name):
for ic in xml_tree.findall("./compounddef/innerclass"):
if ic.text == udt_name:
refid = ic.attrib.get("refid")
xml_path = os.path.join(xml_dir_path, "%s.xml" % refid)
with open(xml_path) as fin:
udt_xml_tree = ET.fromstring(fin.read())
return refid, udt_xml_tree
return None, None
def get_toplevel_functions(xml_tree, name=None):
path = "./compounddef/sectiondef[@kind='%s']/memberdef[@kind='function']"
if name:
path = "%s/[name='%s']" % (path, name)
all_nodes = []
for section_kind in ["func", "user-defined"]:
nodes = xml_tree.findall(path % section_kind)
all_nodes.extend(map(lambda n: n, nodes))
return all_nodes
def get_udt_methods(xml_tree, refid, name=None):
path = "./compounddef[@id='%s']/sectiondef[@kind='public-func']/memberdef[@kind='function']" % (
refid,)
if name:
path = "%s/[name='%s']" % (path, name)
return xml_tree.findall(path)
def get_single_child_element_text_contents(el, child_element_tag):
nodes = el.findall("./%s" % child_element_tag)
nnodes = len(nodes)
if nnodes == 0:
return None
text = nodes[0].text
if nnodes > 1:
print("Warning: more than 1 child element with tag '%s' found; picking first" % (child_element_tag,))
return text
def for_each_param(memberdef_node, callback):
#
#
#
# idp_modname
#
#
# (const char *) processor module name
#
#
#
assert(memberdef_node.tag == "memberdef" and memberdef_node.attrib.get("kind") == "function")
plist = memberdef_node.find("./detaileddescription/para/parameterlist[@kind='param']")
def get_direct_text(n, tag):
c = n.find("./%s" % tag)
if c is not None:
return " ".join(c.itertext()).strip()
for param in memberdef_node.findall("./param"):
name, ptyp, desc = None, None, None
name = get_direct_text(param, "declname")
ptyp = get_direct_text(param, "type")
if name and plist is not None:
sdk_doc_param_name = name.replace("NONNULL_", "")
for plist_item in plist.findall("parameteritem"):
if plist_item.find("./parameternamelist/[parametername='%s']" % sdk_doc_param_name) is not None:
pdesc_node = plist_item.find("./parameterdescription")
if pdesc_node is not None:
desc = " ".join(pdesc_node.itertext()).strip()
callback(name, ptyp, desc)
def for_each_retval(detaileddescription_node, callback):
#
#
#
# >0
#
#
# ok, generated the definition text
#
#
#
plist = detaileddescription_node.find("./para/parameterlist[@kind='retval']")
if plist is not None:
for parameteritem_el in plist.findall("parameteritem"):
parameternamelist_el = parameteritem_el.find("parameternamelist")
if parameternamelist_el is not None:
parametername_els = parameternamelist_el.findall("parametername")
if parametername_els:
parametername_el = parametername_els[0]
retval_value = parametername_el.text
retval_desc_els = parameteritem_el.findall("parameterdescription")
if retval_desc_els:
retval_desc = " ".join(retval_desc_els[0].itertext()).strip()
else:
retval_desc = None
callback(retval_value, retval_desc)