Files
2025-03-13 16:17:53 +01:00

154 lines
5.1 KiB
Python

import os
import sys
import xml.etree.ElementTree as ET
import doxygen_utils
mydir, _ = os.path.split(__file__)
genhooks_dir = os.path.join(mydir, "genhooks")
if genhooks_dir not in sys.path:
sys.path.append(genhooks_dir)
import recipe_index
def get_hooks_enum_information(class_name):
for _, recipes in recipe_index.hooks.items():
for recipe in recipes:
if recipe.class_name == class_name:
return recipe
def _parse_param_type(desc):
if desc.startswith("("):
import re
m = re.match(r"\(([^\)]*)\)\s*(.*)", desc)
if m:
ptype = m.group(1)
return ptype.lstrip(":").replace(" ::", " "), m.group(2)
return None, None
def _parse_return_type(desc):
default = None
import re
m = re.match(r".*\(default=([^\)]*)\).*", desc)
if m:
default = m.group(1)
if desc.startswith("void"):
return "void", None, default
else:
ptype, notype_pdesc = _parse_param_type(desc)
if ptype is None and notype_pdesc is None:
notype_pdesc = desc
return ptype, notype_pdesc, default
def _parse_enumerator(enumval_el, name, enum_name, hooks_info):
# Return type
ret_el = enumval_el.find(".//simplesect[@kind='return']")
rtype = None
rdefault = None
rexpr = None
recipe_data = hooks_info.recipe_module.recipe.get(name, {})
if "ignore" in recipe_data and recipe_data["ignore"]:
return
brief = doxygen_utils.get_element_description(enumval_el, "briefdescription")
detailed = doxygen_utils.get_element_description(enumval_el, "detaileddescription")
notype_rdesc = None
retvals = []
return_data = recipe_data["return"] if (recipe_data and "return" in recipe_data) else {}
if "type" in return_data:
rtype = return_data["type"]
elif ret_el is not None:
rdesc = doxygen_utils.join_all_element_text(ret_el)
rtype, notype_rdesc, rdefault = _parse_return_type(rdesc)
detaileddescription_el = enumval_el.find("detaileddescription")
if detaileddescription_el is not None:
def collect_retval(value, desc):
retvals.append((value, desc))
doxygen_utils.for_each_retval(detaileddescription_el, collect_retval)
if rtype is None:
rtype = hooks_info.recipe_module.default_rtype
if rtype != "void" and rdefault is None:
rdefault = 0
if "default" in return_data:
rdefault = return_data["default"]
if "retexpr" in return_data:
rexpr = return_data["retexpr"]
params = [{
"name" : "<return>",
"type" : rtype,
"default" : rdefault,
"retexpr" : rexpr,
"desc" : notype_rdesc or None,
"values" : retvals or None,
}]
# arguments
plist_el = enumval_el.find(".//parameterlist[@kind='param']")
if plist_el is not None:
for pitem_el in plist_el.findall("./parameteritem"):
pname = pitem_el.find(".//parametername").text
if pname != "none" and pname != "...":
pdesc = doxygen_utils.join_all_element_text(pitem_el.find(".//parameterdescription/para"))
ptype, notype_pdesc = _parse_param_type(pdesc)
if ptype is None:
print("Couldn't parse parameter description: \"%s\". Dropping notification \"%s\" altogether" % (pdesc, name))
return
params.append({
"name" : pname,
"type" : ptype,
"desc" : notype_pdesc,
})
# added parameters
if "add_params" in recipe_data:
params.extend(recipe_data["add_params"])
return {
"brief" : brief,
"detailed" : detailed,
"name" : name,
"params" : params,
"enum_name" : enum_name,
}
def get_hooks_enumerators(xml_dir, class_name):
hooks_info = get_hooks_enum_information(class_name)
tree = ET.parse(os.path.join(xml_dir, hooks_info.toplevel_xml_fname))
enum_el = tree.find(".//memberdef[@kind='enum']/[name='%s']" % hooks_info.enum_name)
enumerators = []
for enumval_el in enum_el.findall("./enumvalue"):
discarded = False
orig_name = enumval_el.find("./name").text
name = orig_name
for pfx in hooks_info.discard_prefixes:
if name.startswith(pfx):
discarded = True
break
if not discarded and hooks_info.discard_doc:
JT = doxygen_utils.join_all_element_text
discarded = JT(enumval_el.find("./detaileddescription")).strip().startswith(hooks_info.discard_doc) or \
JT(enumval_el.find("./briefdescription")).strip().startswith(hooks_info.discard_doc)
if not discarded:
for pfx in hooks_info.strip_prefixes:
if name.startswith(pfx):
name = name[len(pfx):]
break
if not name.startswith("OBSOLETE"):
e = _parse_enumerator(enumval_el, name, orig_name, hooks_info)
if e:
enumerators.append(e)
return enumerators