mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
154 lines
5.1 KiB
Python
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
|
|
|