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" : "", "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