""" Copyright (C) 2019-2021 Intel Corporation SPDX-License-Identifier: MIT """ import re """ Extracts traits from a spec object """ class obj_traits: @staticmethod def is_function(obj): try: return True if re.match(r"function", obj['type']) else False except: return False @staticmethod def is_function_with_input_handles(obj): try: if re.match(r"function", obj['type']): for param in obj['params']: if param_traits.is_input(param) and type_traits.is_handle(param['type']): return True return False except: return False @staticmethod def is_class(obj): try: return True if re.match(r"class", obj['type']) else False except: return False @staticmethod def is_experimental(obj): try: return True if re.search("Exp[0-9]*$", obj['name']) else False except: return False @staticmethod def class_name(obj): try: return obj['class'] except: return None """ Extracts traits from a class name """ class class_traits: @staticmethod def is_global(name, tags): try: return True if name in tags else False except: return False @staticmethod def is_namespace(name, namespace, tags): try: return tags[name] == namespace except: return False @staticmethod def is_singleton(item): try: return "singleton" == item['attribute'] except: return False @staticmethod def get_handle(item, meta): try: return meta['class'][item['name']]['handle'][0] except: return "" """ Extracts traits from a type name """ class type_traits: RE_HANDLE = r"(.*)handle_t" RE_IPC = r"(.*)ipc(.*)handle_t" RE_POINTER = r"(.*\w+)\*+" RE_DESC = r"(.*)desc_t.*" RE_PROPS = r"(.*)properties_t.*" RE_FLAGS = r"(.*)flags_t" RE_COUNTERS = r"(.*)counters_t" RE_PORT_CONFIG = r"(.*)port_config_t" RE_FAN_CONFIG = r"(.*)fan_config_t" RE_RAS_CONFIG = r"(.*)ras_config_t" RE_TEMP_CONFIG = r"(.*)temp_config_t" RE_DEVICE_STATE = r"(.*)device_state_t" RE_PROCESS_STATE = r"(.*)process_state_t" RE_PCI_STATE = r"(.*)pci_state_t" RE_FABRIC_PORT_STATE = r"(.*)fabric_port_state_t" RE_FREQ_STATE = r"(.*)freq_state_t" RE_LED_STATE = r"(.*)led_state_t" RE_MEM_STATE = r"(.*)mem_state_t" RE_PSU_STATE = r"(.*)psu_state_t" RE_RAS_STATE = r"(.*)ras_state_t" RE_CAPABILITIES = r"(.*)capabilities_t" RE_PROPS_EXP = r"(.*)properties_exp_t" @staticmethod def base(name): return _remove_const_ptr(name) @classmethod def is_handle(cls, name): try: return True if re.match(cls.RE_HANDLE, name) else False except: return False @classmethod def is_ipc_handle(cls, name): try: return True if re.match(cls.RE_IPC, name) else False except: return False @staticmethod def is_class_handle(name, meta): try: name = _remove_const_ptr(name) return len(meta['handle'][name]['class']) > 0 except: return False @classmethod def is_pointer(cls, name): try: return True if re.match(cls.RE_POINTER, name) else False except: return False @classmethod def is_descriptor(cls, name): try: return True if re.match(cls.RE_DESC, name) else False except: return False @classmethod def is_properties(cls, name): try: return True if re.match(cls.RE_PROPS, name) else False except: return False @classmethod def is_counters(cls, name): try: return True if re.match(cls.RE_COUNTERS, name) else False except: return False @classmethod def is_port_config(cls, name): try: return True if re.match(cls.RE_PORT_CONFIG, name) else False except: return False @classmethod def is_fan_config(cls, name): try: return True if re.match(cls.RE_FAN_CONFIG, name) else False except: return False @classmethod def is_ras_config(cls, name): try: return True if re.match(cls.RE_RAS_CONFIG, name) else False except: return False @classmethod def is_temp_config(cls, name): try: return True if re.match(cls.RE_TEMP_CONFIG, name) else False except: return False @classmethod def is_device_state(cls, name): try: return True if re.match(cls.RE_DEVICE_STATE, name) else False except: return False @classmethod def is_process_state(cls, name): try: return True if re.match(cls.RE_PROCESS_STATE, name) else False except: return False @classmethod def is_pci_state(cls, name): try: return True if re.match(cls.RE_PCI_STATE, name) else False except: return False @classmethod def is_fabric_port_state(cls, name): try: return True if re.match(cls.RE_FABRIC_PORT_STATE, name) else False except: return False @classmethod def is_freq_state(cls, name): try: return True if re.match(cls.RE_FREQ_STATE, name) else False except: return False @classmethod def is_led_state(cls, name): try: return True if re.match(cls.RE_LED_STATE, name) else False except: return False @classmethod def is_mem_state(cls, name): try: return True if re.match(cls.RE_MEM_STATE, name) else False except: return False @classmethod def is_psu_state(cls, name): try: return True if re.match(cls.RE_PSU_STATE, name) else False except: return False @classmethod def is_ras_state(cls, name): try: return True if re.match(cls.RE_RAS_STATE, name) else False except: return False @classmethod def is_properties_exp(cls, name): try: return True if re.match(cls.RE_PROPS_EXP, name) else False except: return False @classmethod def is_capabilities(cls, name): try: return True if re.match(cls.RE_CAPABILITIES, name) else False except: return False @classmethod def is_flags(cls, name): try: return True if re.match(cls.RE_FLAGS, name) else False except: return False @staticmethod def is_known(name, meta): try: name = _remove_const_ptr(name) for group in meta: if name in meta[group]: return True return False except: return False @staticmethod def is_enum(name, meta): try: name = _remove_const_ptr(name) if name in meta['enum']: return True return False except: return False @staticmethod def is_struct(name, meta): try: name = _remove_const_ptr(name) if name in meta['struct']: return True return False except: return False @staticmethod def find_class_name(name, meta): try: name = _remove_const_ptr(name) for group in meta: if name in meta[group]: return meta[group][name]['class'] return None except: return None """ Extracts traits from a value name """ class value_traits: RE_VERSION = r"\$X_MAKE_VERSION\(\s*(\d+)\s*\,\s*(\d+)\s*\)" RE_BIT = r".*BIT\(\s*(.*)\s*\)" RE_HEX = r"0x\w+" RE_MACRO = r"(\$\w+)\(.*\)" RE_ARRAY = r"(.*)\[(.*)\]" @classmethod def is_ver(cls, name): try: return True if re.match(cls.RE_VERSION, name) else False except: return False @classmethod def get_major_ver(cls, name): try: return int(re.sub(cls.RE_VERSION, r"\1", name)) except: return 0 @classmethod def get_minor_ver(cls, name): try: return int(re.sub(cls.RE_VERSION, r"\2", name)) except: return 0 @classmethod def is_bit(cls, name): try: return True if re.match(cls.RE_BIT, name) else False except: return False @classmethod def get_bit_count(cls, name): try: return int(re.sub(cls.RE_BIT, r"\1", name)) except: return 0 @classmethod def is_hex(cls, name): try: return True if re.match(cls.RE_HEX, name) else False except: return False @classmethod def is_macro(cls, name, meta): try: name = cls.get_macro_name(name) name = cls.get_array_length(name) return True if name in meta['macro'] else False except: return False @classmethod def get_macro_name(cls, name): try: return re.sub(cls.RE_MACRO, r"\1", name) # 'NAME()' -> 'NAME' except: return name @classmethod def is_array(cls, name): try: return True if re.match(cls.RE_ARRAY, name) else False except: return False @classmethod def get_array_name(cls, name): try: return re.sub(cls.RE_ARRAY, r"\1", name) # 'name[len]' -> 'name' except: return name @classmethod def get_array_length(cls, name): try: return re.sub(cls.RE_ARRAY, r"\2", name) # 'name[len]' -> 'len' except: return name @classmethod def find_enum_name(cls, name, meta): try: name = cls.get_array_name(name) # if the value is an etor, return the name of the enum for e in meta['enum']: if name in meta['enum'][e]['etors']: return e return None except: return None """ Extracts traits from a parameter object """ class param_traits: RE_MBZ = r".*\[mbz\].*" RE_IN = r"^\[in\].*" RE_OUT = r"^\[out\].*" RE_INOUT = r"^\[in,out\].*" RE_OPTIONAL = r".*\[optional\].*" RE_RANGE = r".*\[range\((.+),\s*(.+)\)\][\S\s]*" RE_RELEASE = r".*\[release\].*" @classmethod def is_mbz(cls, item): try: return True if re.match(cls.RE_MBZ, item['desc']) else False except: return False @classmethod def is_input(cls, item): try: return True if re.match(cls.RE_IN, item['desc']) else False except: return False @classmethod def is_output(cls, item): try: return True if re.match(cls.RE_OUT, item['desc']) else False except: return False @classmethod def is_inoutput(cls, item): try: return True if re.match(cls.RE_INOUT, item['desc']) else False except: return False @classmethod def is_optional(cls, item): try: return True if re.match(cls.RE_OPTIONAL, item['desc']) else False except: return False @classmethod def is_range(cls, item): try: return True if re.match(cls.RE_RANGE, item['desc']) else False except: return False @classmethod def range_start(cls, item): try: return re.sub(cls.RE_RANGE, r"\1", item['desc']) except: return None @classmethod def range_end(cls, item): try: return re.sub(cls.RE_RANGE, r"\2", item['desc']) except: return None @classmethod def is_release(cls, item): try: return True if re.match(cls.RE_RELEASE, item['desc']) else False except: return False """ Extracts traits from a function object """ class function_traits: @staticmethod def is_static(item): try: return True if re.match(r"static", item['decl']) else False except: return False @staticmethod def is_global(item, tags): try: return True if item['class'] in tags else False except: return False """ Public: substitues each tag['key'] with tag['value'] if cpp, then remove each tag['key'] if matches namespace if comment, then insert doxygen '::' notation at beginning (for autogen links) """ def subt(namespace, tags, string, comment=False, cpp=False, remove_namespace=False): for key, value in tags.items(): if comment or not cpp: # generating c names string = re.sub(r"-%s"%re.escape(key), "-"+value, string) # hack for compile options repl = "::"+value if comment and "$OneApi" != key else value # replace tag; e.g., "$x" -> "xe" string = re.sub(re.escape(key), repl, string) string = re.sub(re.escape(key.upper()), repl.upper(), string) elif re.match(namespace, value): # generating c++ names and tag matches current namespace repl = "" # remove tags; e.g., "$x" -> "" string = re.sub(r"%s_?"%re.escape(key), repl, string) string = re.sub(r"%s_?"%re.escape(key.upper()), repl.upper(), string) elif remove_namespace: # generating c++ names and tags do _not_ match current namespace repl = "" # remove namespace; e.g. "$x" -> "" string = re.sub(r"%s_?"%re.escape(key), repl, string) string = re.sub(r"%s_?"%re.escape(key.upper()), repl.upper(), string) else: # generating c++ names and tags do _not_ match current namespace repl = value+"::" # add namespace; e.g. "$x" -> "xe::" string = re.sub(r"%s_?"%re.escape(key), repl, string) string = re.sub(r"%s_?"%re.escape(key.upper()), repl.upper(), string) return string """ Public: appends whitespace (in multiples of 4) to the end of the string, until len(string) > count """ def append_ws(string, count): while len(string) > count: count = count + 4 string = '{str: <{width}}'.format(str=string, width=count) return string """ Public: split the line of text into a list of strings, where each length of each entry is less-than count """ def split_line(line, ch_count): if not line: return [""] RE_NEWLINE = r"(.*)\n(.*)" words = line.split(" ") lines = [] word_list = [] for word in words: if re.match(RE_NEWLINE, word): prologue = re.sub(RE_NEWLINE,r"\1",word) epilogue = re.sub(RE_NEWLINE,r"\2",word) word_list.append(prologue) lines.append(" ".join(word_list)) word_list = [] if len(epilogue): word_list.append(epilogue) elif sum(map(len, word_list)) + len(word_list) + len(word) <= ch_count: word_list.append(word) else: lines.append(" ".join(word_list)) word_list = [word] if len(word_list): lines.append(" ".join(word_list)) return lines """ Private: converts string from camelCase to snake_case """ def _camel_to_snake(name): str = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) str = re.sub('([a-z0-9])([A-Z])', r'\1_\2', str).lower() return str """ Public: removes items from the list with the key and whose value do not match filter """ def filter_items(lst, key, filter): flst = [] for item in lst: if key in item: if filter == item[key]: flst.append(item) return flst """ Public: returns a list of items with key from a list of dict """ def extract_items(lst, key): klst = [] for item in lst: if key in item: klst.append(item[key]) return klst """ Public: returns a list of all objects of type in all specs """ def extract_objs(specs, value): objs = [] for s in specs: for obj in s['objects']: if re.match(value, obj['type']): objs.append(obj) return objs """ Private: removes 'const' from c++ type """ def _remove_const(name): name = name.split(" ")[-1] return name """ Private: removes '*' from c++ type """ def _remove_ptr(name, last=True): if last: name = re.sub(r"(.*)\*$", r"\1", name) # removes only last '*' else: name = re.sub(r"\*", "", name) # removes all '*' return name """ Private: removes 'const' and '*' from c++ type """ def _remove_const_ptr(name): name = _remove_ptr(_remove_const(name)) return name """ Private: adds class name to type e.g., "const type*" -> "const cname::type*" """ def _add_class(name, cname): words = name.split(" ") words[-1] = "%s::%s"%(cname, words[-1]) return " ".join(words) """ Private: removes class name from type e.g., "const cls_type*" -> "const type*" """ def _remove_class(name, cname, upper_case=False): if cname: cname = _camel_to_snake(cname) if upper_case: cname = cname.upper() RE_CLS = r"(.*)(%s_)(\w+)"%cname # remove "cls_" part if re.match(RE_CLS, name): name = re.sub(RE_CLS, r"\1\3", name) return name """ Public: returns c/c++ name of macro """ def make_macro_name(namespace, tags, obj, params=True): if params: return subt(namespace, tags, obj['name']) else: name = re.sub(r"(.*)\(.*", r"\1", obj['name']) # remove '()' part return subt(namespace, tags, name) """ Public: returns c/c++ name of enums, structs, unions, typedefs... """ def make_type_name(namespace, tags, obj, cpp=False): name = subt(namespace, tags, obj['name'], cpp=cpp) # if c++, remove class part of name if cpp and 'class' in obj: cname = subt(namespace, tags, obj['class'], cpp=cpp) name = _remove_class(name, cname) return name """ Public: returns c/c++ name of enums... """ def make_enum_name(namespace, tags, obj, cpp=False): name = make_type_name(namespace, tags, obj, cpp) if type_traits.is_flags(obj['name']): name = re.sub(r"flags", r"flag", name) return name """ Public: returns c/c++ name of etor """ def make_etor_name(namespace, tags, enum, etor, cpp=False, py=False, meta=None): if cpp or py: # if c++, remove the verbose enum part of the etor if type_traits.is_flags(enum) and not py: # e.g., "CLS_ENUM_NAME_ETOR_NAME" -> "ENUM_NAME_ETOR_NAME" cname = type_traits.find_class_name(enum, meta) cname = subt(namespace, tags, cname, cpp=cpp) name = subt(namespace, tags, etor, cpp=cpp) name = _remove_class(name, cname, upper_case=True) else: # e.g., "ENUM_NAME_ETOR_NAME" -> "ETOR_NAME" if type_traits.is_flags(enum): prefix = re.sub(r"(\w+)_flags_t", r"\1_flag", subt(namespace, tags, enum, cpp=cpp)).upper() else: prefix = re.sub(r"(\w+)_t", r"\1", subt(namespace, tags, enum, cpp=cpp)).upper() name = re.sub(r"%s_(\w+)"%prefix, r"\1", subt(namespace, tags, etor, cpp=cpp)) name = re.sub(r"^(\d+\w*)", r"_\1", name) else: name = subt(namespace, tags, etor, cpp=cpp) return name """ Private: returns c/c++ name of value """ def _get_value_name(namespace, tags, value, cpp, meta, is_array_size=False, cbase=None): if cpp: if value_traits.is_macro(value, meta): value = subt(namespace, tags, value) else: name = value_traits.find_enum_name(value, meta) if name: # e.g., "ETOR_NAME" -> "ENUM_NAME::ETOR_NAME" enum = subt(namespace, tags, name, cpp=cpp) # e.g., "CLS_ENUM_NAME" -> "ENUM_NAME" cname = type_traits.find_class_name(name, meta) cname = subt(namespace, tags, cname, cpp=cpp) enum = _remove_class(enum, cname) if cname and cbase: cbase = subt(namespace, tags, cbase, cpp=cpp) if cbase == cname: enum = _remove_class(enum, cname) else: enum = "%s::%s"%(cname, enum) if is_array_size: value = "static_cast(%s::%s)"%(enum, make_etor_name(namespace, tags, name, value, cpp=cpp, meta=meta)) else: value = "%s::%s"%(enum, make_etor_name(namespace, tags, name, value, cpp=cpp, meta=meta)) else: value = subt(namespace, tags, value, cpp=cpp) else: value = subt(namespace, tags, value, cpp=cpp) return value """ Public: returns a list of strings for declaring each enumerator in an enumeration c++ format: "ETOR_NAME = VALUE, ///< DESCRIPTION" python format: "ETOR_NAME = VALUE, ## DESCRIPTION" """ def make_etor_lines(namespace, tags, obj, cpp=False, py=False, meta=None): lines = [] for item in obj['etors']: name = make_etor_name(namespace, tags, obj['name'], item['name'], cpp, py, meta) if 'value' in item: delim = "," if not py else "" value = _get_value_name(namespace, tags, item['value'], cpp, meta, cbase=obj_traits.class_name(obj)) prologue = "%s = %s%s"%(name, value, delim) elif py: prologue = "%s = auto()"%(name) else: prologue = "%s,"%(name) comment_style = "##" if py else "///<" for line in split_line(subt(namespace, tags, item['desc'], True, cpp), 70): lines.append("%s%s %s"%(append_ws(prologue, 48), comment_style, line)) prologue = "" if cpp and not type_traits.is_flags(obj['name']): lines.append("FORCE_UINT32 = 0x7fffffff") elif not py: lines.append("%sFORCE_UINT32 = 0x7fffffff"%make_enum_name(namespace, tags, obj, cpp)[:-1].upper()) return lines """ Public: determines whether the enumeration represents a bitfield """ def is_enum_bitfield(obj): for item in obj['etors']: if 'value' in item and value_traits.is_bit(item['value']): return True return False """ Public: returns c/c++ name of any type """ def get_type_name(namespace, tags, obj, item, cpp=False, meta=None, handle_to_class=True): name = subt(namespace, tags, item, cpp=cpp) if cpp: cname = type_traits.find_class_name(item, meta) if cname: is_global = class_traits.is_global(cname, tags) is_namespace = class_traits.is_namespace(cname, namespace, tags) # cname == namespace? e.g., cname == "$x" is_handle = type_traits.is_handle(item) is_inscope = False if obj_traits.is_class(obj): # if the obj _is_ a class is_inscope = cname == obj['name'] # then is the item's class this obj? elif not is_global: # else if the obj belongs to a class is_inscope = cname == obj_traits.class_name(obj) # then is the item's class the same as the obj? cname_no_namespace = subt(namespace, tags, cname, cpp=cpp, remove_namespace=True) cname = subt(namespace, tags, cname, cpp=cpp) # remove tags from class name if not (is_global or is_namespace or is_handle or is_inscope): # need to prepend the class name to the type after removing namespace from the type name = subt(namespace, tags, item, cpp=cpp, remove_namespace=True) name = _remove_class(name, cname_no_namespace) name = _add_class(name, cname) elif handle_to_class and is_handle and not obj_traits.is_class(obj): # convert handles to class pointers name = re.sub(r"(const\s*)?(\w*:?:?\w+)(\**)", r"\1%s*\3"%cname, name) # e.g., const name* -> const cname** if not is_handle: # remove the verbose class part from the type name name = _remove_class(name, cname) return name """ Private: returns c/c++ name of any type """ def _get_type_name(namespace, tags, obj, item, cpp=False, meta=None, handle_to_class=True): return get_type_name(namespace, tags, obj, item['type'], cpp, meta, handle_to_class) """ Private: returns python c_type name of any type """ def get_ctype_name(namespace, tags, item): name = subt(namespace, tags, item['type']) name = _remove_const(name) name = re.sub(r"void\*", "c_void_p", name) name = re.sub(r"char\*", "c_char_p", name) name = re.sub(r"uint8_t", "c_ubyte", name) name = re.sub(r"uint16_t", "c_ushort", name) name = re.sub(r"uint32_t", "c_ulong", name) name = re.sub(r"uint64_t", "c_ulonglong", name) name = re.sub(r"size_t", "c_size_t", name) name = re.sub(r"float", "c_float", name) name = re.sub(r"double", "c_double", name) name = re.sub(r"\bchar", "c_char", name) name = re.sub(r"\bint", "c_int", name) if type_traits.is_pointer(name): name = _remove_ptr(name) name = "POINTER(%s)"%name elif 'name' in item and value_traits.is_array(item['name']): length = subt(namespace, tags, value_traits.get_array_length(item['name'])) name = "%s * %s"%(name, length) return name """ Public: returns c/c++ name of member of struct/class """ def make_member_name(namespace, tags, item, prefix="", cpp=False, meta=None, remove_array=False, cbase=None): if cpp and value_traits.is_macro(item['name'], meta): name = subt(namespace, tags, item['name']) elif cpp and value_traits.is_array(item['name']): name = value_traits.get_array_name(item['name']) name = subt(namespace, tags, name) alength = value_traits.get_array_length(item['name']) alength = _get_value_name(namespace, tags, alength, cpp, meta, is_array_size=True, cbase=cbase) name = "%s[%s]"%(name, alength) else: name = subt(namespace, tags, prefix+item['name'], cpp=cpp) if remove_array: name = value_traits.get_array_name(name) return name """ Public: returns a list of strings for each member of a structure or class c++ format: "TYPE NAME = INIT, ///< DESCRIPTION" python format: "("NAME", TYPE)" ## DESCRIPTION" """ def make_member_lines(namespace, tags, obj, prefix="", cpp=False, py=False, meta=None): lines = [] if 'members' not in obj: return lines for i, item in enumerate(obj['members']): name = make_member_name(namespace, tags, item, prefix, cpp, meta, remove_array=py, cbase=obj_traits.class_name(obj)) if py: tname = get_ctype_name(namespace, tags, item) else: tname = _get_type_name(namespace, tags, obj, item, cpp, meta) if cpp and 'init' in item: value = _get_value_name(namespace, tags, item['init'], cpp, meta, cbase=obj_traits.class_name(obj)) prologue = "%s %s = %s;"%(tname, name, value) elif py: delim = "," if i < (len(obj['members'])-1) else "" prologue = "(\"%s\", %s)%s"%(name, tname, delim) else: prologue = "%s %s;"%(tname, name) comment_style = "##" if py else "///<" ws_count = 64 if py else 48 for line in split_line(subt(namespace, tags, item['desc'], True, cpp), 70): lines.append("%s%s %s"%(append_ws(prologue, ws_count), comment_style, line)) prologue = "" return lines """ Public: returns a list of c++ strings for each member of a class format: "auto getNAME( void ) const { return MEMBER; }" """ def make_member_function_lines(namespace, tags, obj, prefix=""): lines = [] if 'members' not in obj: return lines for item in obj['members']: name = subt(namespace, tags, item['name'], cpp=True) is_pointer = type_traits.is_pointer(item['type']) if is_pointer and re.match(r"p\w+", name): # if this is a pointer and starts with 'p', fname = name[1:].title() # then remove the 'p' part of the name else: fname = name.title() lines.append("auto get%s( void ) const { return %s; }"%(fname, prefix+name)) return lines """ Private: returns the list of parameters, filtering based on desc tags """ def _filter_param_list(params, filters1=["[in]", "[in,out]", "[out]"], filters2=[""]): lst = [] for p in params: for f1 in filters1: if f1 in p['desc']: for f2 in filters2: if f2 in p['desc']: lst.append(p) break break return lst """ Private: returns c/c++ name of parameter """ def _get_param_name(namespace, tags, item, cpp): name = subt(namespace, tags, item['name'], cpp=cpp) if cpp and type_traits.is_handle(item['type']): name = re.sub(r"\bh([A-Z]\w+)", r"p\1", name) # change "hName" to "pName" name = re.sub(r"\bph([A-Z]\w+)", r"pp\1", name) # change "phName" to "ppName" if param_traits.is_output(item) and not param_traits.is_optional(item): name = re.sub(r"p(p[A-Z]\w+)", r"\1", name) #change ppName to pName return name def get_func_descs(namespace, tags, obj): descs = [] for item in obj['params']: if ( type_traits.is_descriptor(item['type']) or type_traits.is_properties(item['type']) or type_traits.is_counters(item['type']) or type_traits.is_port_config(item['type']) or type_traits.is_fan_config(item['type']) or type_traits.is_ras_config(item['type']) or type_traits.is_temp_config(item['type']) or type_traits.is_device_state(item['type']) or type_traits.is_process_state(item['type']) or type_traits.is_pci_state(item['type']) or type_traits.is_fabric_port_state(item['type']) or type_traits.is_freq_state(item['type']) or type_traits.is_led_state(item['type']) or type_traits.is_mem_state(item['type']) or type_traits.is_psu_state(item['type']) or type_traits.is_ras_state(item['type']) or type_traits.is_capabilities(item['type']) or type_traits.is_properties_exp(item['type'])): name = _get_param_name(namespace, tags, item, False) descs.append(name) return descs """ Public: returns a list of c++ strings for each parameter of a function format: "TYPE NAME = INIT, ///< DESCRIPTION" """ def make_param_lines(namespace, tags, obj, cpp=False, py=False, decl=False, meta=None, format=["type", "name", "init", "delim", "desc"], delim=","): lines = [] if cpp: is_static = function_traits.is_static(obj) is_global = function_traits.is_global(obj, tags) params = obj['params'] if is_static or is_global else obj['params'][1:] params = _filter_param_list(params, ["[in]", "[in,out]"]) + _filter_param_list(params, ["[out]"], ["[optional"]) else: params = obj['params'] for i, item in enumerate(params): name = _get_param_name(namespace, tags, item, cpp=cpp) if py: tname = get_ctype_name(namespace, tags, item) else: tname = _get_type_name(namespace, tags, obj, item, cpp, meta) init = "" local = "Local" if type_traits.is_pointer(item['type']) and type_traits.is_handle(item['type']) and param_traits.is_input(item) else "" if cpp: if decl and param_traits.is_optional(item): is_pointer = type_traits.is_pointer(item['type']) is_handle = type_traits.is_handle(item['type']) if is_pointer or is_handle: init += "= nullptr" else: init += "= 0" words = [] if "local" in format: name += local if "type*" in format: words.append(tname+"*") name = "p"+name elif "type" in format: words.append(tname) if "name" in format: words.append(name) if "init" in format and len(init) > 0: words.append(init) prologue = " ".join(words) if "delim" in format: if i < len(params)-1: prologue += delim if "desc" in format: desc = item['desc'] if cpp: desc = re.sub(r"handle of", r"pointer to", desc) for line in split_line(subt(namespace, tags, desc, True, cpp), 70): lines.append("%s///< %s"%(append_ws(prologue, 48), line)) prologue = "" else: lines.append(prologue) if "type" in format and len(lines) == 0 and not py: lines = ["void"] return lines """ Public: returns a string of c++ template parameters format: "TPARAM0, TPARAM1" """ def make_tparams_line(namespace, tags, obj): line = ", ".join(obj['tparams']) return subt(namespace, tags, line, cpp=True) """ Public: returns True if ctor has parameters """ def has_ctor_params(obj): params = _filter_param_list(obj['members'] if 'members' in obj else [], ["[in]"]) return len(params) > 0 """ Public: returns a list of c++ strings for ctor parameters of members format: "TYPE NAME, ///< DESCRIPTION" """ def make_ctor_param_lines(namespace, tags, obj, meta=None, format=["type", "name", "delim", "desc"]): lines = [] params = _filter_param_list(obj['members'] if 'members' in obj else [], ["[in]"]) for i, item in enumerate(params): name = subt(namespace, tags, item['name']) tname = _get_type_name(namespace, tags, obj, item, True, meta) if type_traits.is_descriptor(tname): tname = "const %s*"%tname # e.g., "xe_event_desc_t*" -> "const desc_t*" words = [] if "type" in format: words.append(tname) if "name" in format: words.append(name) prologue = " ".join(words) if "delim" in format: if i < len(params)-1: prologue += "," if "desc" in format: for line in split_line(subt(namespace, tags, item['desc'], True), 70): lines.append("%s///< %s"%(append_ws(prologue, 48), line)) prologue = "" else: lines.append(prologue) if "type" in format and len(lines) == 0: lines = ["void"] return lines """ Public: returns a list of c++ strings for initializing members from ctor parameters of members format: "MEMBER( NAME )," """ def make_ctor_param_init_lines(namespace, tags, obj, prefix="", meta=None): lines = [] params = _filter_param_list(obj['members'] if 'members' in obj else [], ["[in]"]) for i, item in enumerate(params): name = subt(namespace, tags, item['name']) tname = _get_type_name(namespace, tags, obj, item, cpp=True, meta=meta) member = prefix+name if type_traits.is_descriptor(tname): name = "( %s ) ? *%s : desc_t{}"%(name, name) delim = "," if i < len(params)-1 else "" lines.append("%s( %s )%s"%(member, name, delim)) return lines """ Private: returns c/c++ name of local variable from parameter name """ def _get_local_name(name): name = re.sub(r"\bp([A-Z]\w+)", r"\1", name) # change pName to Name name = re.sub(r"\bp([hA-Z]\w+)", r"\1", name) # change phName to hName name = re.sub(r"\bp(p[A-Z]\w+)", r"\1", name) # change ppName to pName name = name[0].lower() + name[1:] # change Name to name return name """ Public: returns a list of dict for declaring local variables in c++ wrapper """ def make_wrapper_params(namespace, tags, obj, meta, specs): params = [] returns = [] numSelf = 0 # if the input parameter is a class, # then need to use getHandle # if the input parameter is an array of classes # then need to create a std::vector of handles # if the output parameter is a class, # then need to create a local handle then call the ctor # if the output parameter is an array of classes # then need to create a std::vector to receive handles(s) then call the ctor for each # if the parameter is an input and the cpp type is different than the c type, # then need to use static_cast or reinterpret_cast # if the parameter is an output # then need to create a local variable is_static = function_traits.is_static(obj) is_global = function_traits.is_global(obj, tags) for i, item in enumerate(obj['params']): c_name = _get_param_name(namespace, tags, item, cpp=False) cpp_name = _get_param_name(namespace, tags, item, cpp=True) c_tname = _get_type_name(namespace, tags, obj, item, cpp=False, meta=meta) cpp_tname = _get_type_name(namespace, tags, obj, item, cpp=True, meta=meta, handle_to_class=False) cpp_cname = _get_type_name(namespace, tags, obj, item, cpp=True, meta=meta) local_name = _get_local_name(c_name) if param_traits.is_range(item): range_start = param_traits.range_start(item) range_end = param_traits.range_end(item) if type_traits.is_class_handle(item['type'], meta): if param_traits.is_output(item) or param_traits.is_inoutput(item): if param_traits.is_optional(item): params.append({ 'local': local_name, 'ctype': _remove_const_ptr(c_tname), 'cpptype': _remove_const_ptr(cpp_tname), 'range': (range_start, range_end), 'optional': True, 'arg': "%s.data()"%(local_name), 'class': _remove_ptr(cpp_cname, False), 'ctor': _make_ctor(namespace, tags, item, obj, meta, specs), 'name': cpp_name }) else: params.append({ 'local': local_name, 'ctype': _remove_const_ptr(c_tname), 'cpptype': _remove_const_ptr(cpp_tname), 'range': (range_start, range_end), 'optional': False, 'arg': "%s.data()"%(local_name), 'class': _remove_ptr(cpp_cname, False), 'ctor': _make_ctor(namespace, tags, item, obj, meta, specs), 'name': cpp_name }) if param_traits.is_output(item): returns.append(cpp_name) elif param_traits.is_optional(item): params.append({ 'local': local_name, 'ctype': _remove_const_ptr(c_tname), 'cpptype': _remove_const_ptr(cpp_tname), 'range': (range_start, range_end), 'init': cpp_name, 'optional': True, 'arg': "%s.data()"%(local_name) }) else: params.append({ 'local': local_name, 'ctype': _remove_const_ptr(c_tname), 'cpptype': _remove_const_ptr(cpp_tname), 'range': (range_start, range_end), 'init': cpp_name, 'optional': False, 'arg': "%s.data()"%(local_name) }) elif param_traits.is_output(item): params.append({ 'local': local_name, 'ctype': _remove_const_ptr(c_tname), 'cpptype': _remove_const_ptr(cpp_tname), 'range': (range_start, range_end), 'optional': param_traits.is_optional(item), 'arg': "%s.data()"%(local_name) }) returns.append(cpp_name) elif c_tname != cpp_tname: params.append({ 'arg': "reinterpret_cast<%s>( %s )"%(c_tname, cpp_name) }) else: params.append({ 'arg': cpp_name }) else: if type_traits.is_class_handle(item['type'], meta): is_this_handle = type_traits.find_class_name(item['type'], meta) == obj_traits.class_name(obj) if param_traits.is_output(item): if param_traits.is_optional(item): params.append({ 'local': local_name, 'ctype': _remove_const_ptr(c_tname), 'cpptype': _remove_const_ptr(cpp_tname), 'optional': True, 'arg': "( %s ) ? &%s : nullptr"%(cpp_name, local_name), 'release': False, 'class': _remove_ptr(cpp_cname, False), 'ctor': _make_ctor(namespace, tags, item, obj, meta, specs), 'name': cpp_name }) else: params.append({ 'local': local_name, 'ctype': _remove_const_ptr(c_tname), 'cpptype': _remove_const_ptr(cpp_tname), 'optional': False, 'arg': "&%s"%(local_name), 'release': False, 'class': _remove_ptr(cpp_cname, False), 'ctor': _make_ctor(namespace, tags, item, obj, meta, specs), 'name': cpp_name }) returns.append(cpp_name) elif param_traits.is_optional(item): params.append({ 'arg': "( %s ) ? reinterpret_cast<%s>( %s->getHandle() ) : nullptr"%(cpp_name, c_tname, cpp_name) }) elif (not is_static and not is_global) and is_this_handle: numSelf += 1 if numSelf == 1: params.append({ 'arg': "reinterpret_cast<%s>( getHandle() )"%(c_tname) }) else: params.append({ 'arg': "reinterpret_cast<%s>( %s->getHandle() )"%(c_tname, cpp_name) }) elif param_traits.is_release(item): params.append({ 'arg': "reinterpret_cast<%s>( %s->getHandle() )"%(c_tname, cpp_name), 'release': True, 'class': _remove_ptr(cpp_cname, False), 'name': cpp_name }) else: params.append({ 'arg': "reinterpret_cast<%s>( %s->getHandle() )"%(c_tname, cpp_name) }) elif param_traits.is_output(item): params.append({ 'local': local_name, 'ctype': _remove_const_ptr(c_tname), 'cpptype': _remove_const_ptr(cpp_tname), 'arg': "&%s"%(local_name), 'name': local_name }) if c_tname != cpp_tname: if type_traits.is_pointer(_remove_ptr(item['type'])) or (type_traits.is_handle(item['type']) and not type_traits.is_ipc_handle(item['type'])): returns.append("reinterpret_cast<%s>( %s )"%(_remove_const_ptr(cpp_tname), local_name)) else: returns.append("*reinterpret_cast<%s*>( &%s )"%(_remove_const_ptr(cpp_tname), local_name)) else: returns.append(local_name) elif c_tname != cpp_tname: if type_traits.is_ipc_handle(item['type']): params.append({ 'arg': "*reinterpret_cast<%s*>( &%s )"%(c_tname, cpp_name) }) elif type_traits.is_pointer(item['type']) or type_traits.is_handle(item['type']): params.append({ 'arg': "reinterpret_cast<%s>( %s )"%(c_tname, cpp_name) }) elif type_traits.is_struct(item['type'], meta): params.append({ 'arg': "*reinterpret_cast<%s*>( &%s )"%(c_tname, cpp_name) }) else: params.append({ 'arg': "static_cast<%s>( %s )"%(c_tname, cpp_name) }) else: params.append({ 'arg': cpp_name }) if len(returns) == 0: rvalue = "" elif len(returns) > 1: rvalue = "std::make_tuple( %s )"%", ".join(returns) else: rvalue = "%s"%returns[0] return params, rvalue """ Private: returns a ctor dict in c++ wrapper """ def _make_ctor(namespace, tags, item, obj, meta, specs): cobj = next(iter(filter_items(extract_objs(specs, 'class'), 'name', type_traits.find_class_name(item['type'], meta))), None) is_singleton = class_traits.is_singleton(cobj) fty_name = "g_%sFactory"%make_class_name(namespace, tags, cobj) if obj_traits.class_name(obj) in meta['class'][cobj['name']].get('child',[]): cobj2 = next(iter(filter_items(extract_objs(specs, 'class'), 'name', obj_traits.class_name(obj))), None) is_singleton = class_traits.is_singleton(cobj2) fty_name = "g_%sFactory"%make_class_name(namespace, tags, cobj2) return { 'params': _make_wrapper_ctor_params(namespace, tags, item, obj, cobj, meta), 'factory': fty_name if is_singleton else "" } """ Private: returns a list of c++ strings of ctor arguments in c++ wrapper """ def _make_wrapper_ctor_params(namespace, tags, item, obj, cobj, meta): params = [] is_static = function_traits.is_static(obj) is_global = function_traits.is_global(obj, tags) # generate list of names for each parameter of the current function oparams = [ _get_param_name(namespace, tags, oparam, cpp=True) for oparam in obj['params'] ] # walk the ctor parameter names cparams = make_ctor_param_lines(namespace, tags, cobj, meta=meta, format=['name']) for i, name in enumerate(cparams): if name == "handle": c_name = _get_param_name(namespace, tags, item, cpp=False) local_name = _get_local_name(c_name) cpp_tname = _get_type_name(namespace, tags, obj, item, cpp=True, meta=meta, handle_to_class=False) if param_traits.is_range(item): params.append("reinterpret_cast<%s>( %s[ i ] )"%(_remove_const_ptr(cpp_tname), local_name)) else: params.append("reinterpret_cast<%s>( %s )"%(_remove_const_ptr(cpp_tname), local_name)) elif name in oparams: if (not is_static and not is_global) and (0 == oparams.index(name)): params.append("this") else: params.append(name) else: if (not is_static and not is_global): params.append("m_"+name) else: params.append("nullptr") return params """ Public: returns a list of strings for the description format: "@brief DESCRIPTION" """ def make_desc_lines(namespace, tags, obj, cpp=False): lines = [] prologue = "@brief" for line in split_line(subt(namespace, tags, obj['desc'], True, cpp), 70): lines.append("%s %s"%(prologue, line)) prologue = " " return lines """ Public: returns a list of strings for the detailed description format: "@details DESCRIPTION" """ def make_details_lines(namespace, tags, obj, cpp=False): lines = [] if 'details' in obj: lines.append("") lines.append("@details") for item in obj['details']: if isinstance(item, dict): for key, values in item.items(): prologue = " -" for line in split_line(subt(namespace, tags, key, True, cpp), 70): lines.append("%s %s"%(prologue, line)) prologue = " " for val in values: prologue = " +" for line in split_line(subt(namespace, tags, val, True, cpp), 66): lines.append("%s %s"%(prologue, line)) prologue = " " else: prologue = " -" for line in split_line(subt(namespace, tags, item, True, cpp), 70): lines.append("%s %s"%(prologue, line)) prologue = " " if 'analogue' in obj: lines.append("") lines.append("@remarks") lines.append(" _Analogues_") for line in obj['analogue']: lines.append(" - %s"%line) return lines """ Public: returns a dict of auto-generated c++ parameter validation checks """ def make_param_checks(namespace, tags, obj, cpp=False, meta=None): checks = {} for item in obj.get('returns', []): for key, values in item.items(): key = subt(namespace, tags, key, False, cpp) for val in values: code = re.match(r"^\`(.*)\`$", val) if code: if key not in checks: checks[key] = [] checks[key].append(subt(namespace, tags, code.group(1), False, cpp)) return checks """ Public: returns a list of strings for possible return values """ def make_returns_lines(namespace, tags, obj, cpp=False, meta=None): lines = [] if cpp: params = _filter_param_list(obj['params'], ["[out]"]) if len(params) > 0: lines.append("@returns") for p in params: desc = re.sub(r"\[.*\](.*)", r"\1", p['desc']) tname = _remove_const_ptr(_get_type_name(namespace, tags, obj, p, cpp, meta)) lines.append(" - %s"%subt(namespace, tags, "%s:%s"%(tname, desc), True, cpp)) lines.append("") for item in obj.get('returns', []): for key, values in item.items(): if "$X_RESULT_NOT_READY" == key: if len(lines) == 0: lines.append("@returns") lines.append(" - %s"%subt(namespace, tags, "$x_bool_t:'0' when $X_RESULT_NOT_READY", cpp=cpp)) lines.append("@throws result_t") else: lines.append("@returns") for item in obj.get('returns', []): for key, values in item.items(): lines.append(" - %s"%subt(namespace, tags, key, True, cpp)) for val in values: lines.append(" + %s"%subt(namespace, tags, val, True, cpp)) return lines """ Public: returns c++ string for declaring function return type """ def make_return_type(namespace, tags, obj, cpp=False, decl=False, meta=None): # only "return" the parameters declared as "out" params = _filter_param_list(obj['params'], ["[out]"]) types = [] for p in params: if not param_traits.is_optional(p): tname = _remove_const_ptr(_get_type_name(namespace, tags, obj, p, cpp, meta)) if cpp: cname = type_traits.find_class_name(p['type'], meta) is_handle = type_traits.is_handle(p['type']) if cname and not decl and not is_handle: # need to prepend the class name to the type tname = _add_class(tname, subt(namespace, tags, cname, cpp=cpp)) elif cname and is_handle: # convert handles to class pointers tname = _remove_const_ptr(_get_type_name(namespace, tags, obj, p, cpp, meta)) types.append(tname) for item in obj.get('returns', []): for key, values in item.items(): if "$X_RESULT_NOT_READY" == key: types.append(subt(namespace, tags, "$x_bool_t", cpp=cpp)) if len(types) == 0: # if none exist, then just return "void" return "void" elif len(types) > 1: # if more than one return value, then return a tuple of values return "std::tuple<%s>"%", ".join(types) else: return types[0] """ Public: returns the name of a function """ def make_func_name(namespace, tags, obj, cpp=False): if not cpp: cname = obj_traits.class_name(obj) else: cname = "" return subt(namespace, tags, "%s%s"%(cname, obj['name']), cpp=cpp) """ Public: returns the name of a function """ def make_tracing_func_name(namespace, tags, obj): cname = obj_traits.class_name(obj) x_tag = tags['$x'] tags['$x'] = '' #temporaly remove namespace tag so funx doesn't contain "ze" fname = subt(namespace, tags, "%s%s"%(cname, obj['name']), cpp=False) fname = "zelTracer" + fname + "RegisterCallback" tags['$x'] = x_tag return fname """ Public: returns the name of a function pointer """ def make_pfn_name(namespace, tags, obj): return subt(namespace, tags, "pfn%s"%obj['name']) """ Public: returns the name of a function pointer """ def make_pfncb_name(namespace, tags, obj): return subt(namespace, tags, "pfn%sCb"%obj['name']) """ Public: returns the name of a function pointer """ def make_pfn_type(namespace, tags, obj, epilogue=""): newtags = dict() for key, value in tags.items(): if re.match(namespace, value): newtags[key] = "pfn" return "%s_%s%s_t"%(namespace, make_func_name(namespace, newtags, obj), epilogue) """ Public: returns the name of a function pointer """ def make_pfncb_type(namespace, tags, obj): return make_pfn_type(namespace, tags, obj, epilogue="Cb") """ Public: returns the name of a function pointer """ def make_pfncb_param_type(namespace, tags, obj): return "%s_params_t"%_camel_to_snake(make_func_name(namespace, tags, obj)) """ Public: returns the name of a class """ def make_class_name(namespace, tags, obj): name = subt(namespace, tags, obj['name'], cpp=True) return name """ Public: returns a c++ string for the declaration of a base class """ def make_baseclass_decl(namespace, tags, obj): if 'base' in obj: return " : public %s"%(subt(namespace, tags, obj['base'], cpp=True)) return "" """ Public: returns a c++ string for the declaration of a base class ctor """ def make_baseclass_ctor(namespace, tags, obj): base = subt(namespace, tags, obj['base'], cpp=True) ctor = base.split("::")[-1] return "%s::%s"%(base, ctor) """ Public: returns a list of all function objs for the specified class and version """ def get_class_function_objs(specs, cname, minVersion = 0, maxVersion = 9999): objects = [] for s in specs: for obj in s['objects']: is_function = obj_traits.is_function(obj) match_cls = cname == obj_traits.class_name(obj) if is_function and match_cls: func_ver = float(obj.get('version',"1.0")) if func_ver <= maxVersion and func_ver >= minVersion: objects.append(obj) return sorted(objects, key=lambda obj: (float(obj.get('version',"1.0"))*10000) + int(obj.get('ordinal',"100"))) """ Public: returns a list of all non-experimental function objs and a list of experimental function objs for the specified class """ def get_class_function_objs_exp(specs, cname): objects = [] exp_objects = [] optional = True for s in specs: for obj in s['objects']: is_function = obj_traits.is_function(obj) match_cls = cname == obj_traits.class_name(obj) if is_function and match_cls: if obj_traits.is_experimental(obj): exp_objects.append(obj) else: objects.append(obj) if obj.get('version',"1.0") == "1.0": optional = False objects = sorted(objects, key=lambda obj: (float(obj.get('version',"1.0"))*10000) + int(obj.get('ordinal',"100"))) exp_objects = sorted(exp_objects, key=lambda obj: (float(obj.get('version',"1.0"))*10000) + int(obj.get('ordinal',"100"))) return objects, exp_objects, optional """ Public: returns string name of DDI table for function object """ def get_table_name(namespace, tags, obj): cname = obj_traits.class_name(obj) if obj_traits.is_experimental(obj): cname=cname+"Exp" name = subt(namespace, tags, cname, cpp=True) # i.e., "$x" -> "" name = name if len(name) > 0 else "Global" return name """ Public: returns string name of callback table for function object """ def get_callback_table_name(namespace, tags, obj): cname = obj_traits.class_name(obj) name = subt(namespace, tags, cname, cpp=True) # i.e., "$x" -> "" name = name if len(name) > 0 else "Global" return name """ Public: returns a list of dict of each pfntables needed """ def get_pfntables(specs, meta, namespace, tags): tables = [] for cname in sorted(meta['class'], key=lambda x: meta['class'][x]['ordinal']): objs, exp_objs, optional = get_class_function_objs_exp(specs, cname) if len(objs) > 0: name = get_table_name(namespace, tags, objs[0]) table = "%s_%s_dditable_t"%(namespace, _camel_to_snake(name)) params = [] params.append({ 'type': "$x_api_version_t", 'name': "version", 'desc': "[in] API version requested" }) params.append({ 'type': "%s*"%table, 'name': "pDdiTable", 'desc': "[in,out] pointer to table of DDI function pointers" }) export = { 'name': "%sGet%sProcAddrTable"%(namespace, name), 'params': params } pfn = "%s_pfnGet%sProcAddrTable_t"%(namespace, name) tables.append({ 'name': name, 'type': table, 'export': export, 'pfn': pfn, 'functions': objs, 'experimental': False, 'optional': optional }) if len(exp_objs) > 0: name = get_table_name(namespace, tags, exp_objs[0]) table = "%s_%s_dditable_t"%(namespace, _camel_to_snake(name)) params = [] params.append({ 'type': "$x_api_version_t", 'name': "version", 'desc': "[in] API version requested" }) params.append({ 'type': "%s*"%table, 'name': "pDdiTable", 'desc': "[in,out] pointer to table of DDI function pointers" }) export = { 'name': "%sGet%sProcAddrTable"%(namespace, name), 'params': params } pfn = "%s_pfnGet%sProcAddrTable_t"%(namespace, name) tables.append({ 'name': name, 'type': table, 'export': export, 'pfn': pfn, 'functions': exp_objs, 'experimental': True, 'optional': True }) return tables """ Public: returns a list of dict of each pfntables """ def get_zel_pfncbtables(specs, meta, namespace, tags): tables = [] for cname in sorted(meta['class'], key=lambda x: meta['class'][x]['ordinal']): objs = get_class_function_objs(specs, cname, 1.0, 9999) if len(objs) > 0: name = get_table_name(namespace, tags, {'class': cname}) table = "zel_%s_callbacks_t"%(_camel_to_snake(name)) tables.append({ 'name': name, 'type': table, 'functions': objs }) return tables """ Public: returns a list of dict of each pfntables for all APIs introduced after 1.0 """ def get_new_pfncbtables(specs, meta, namespace, tags): tables = [] for cname in sorted(meta['class'], key=lambda x: meta['class'][x]['ordinal']): objs = get_class_function_objs(specs, cname, 1.1, 9999) if len(objs) > 0: name = get_table_name(namespace, tags, {'class': cname}) table = "%s_%s_callbacks_t"%(namespace, _camel_to_snake(name)) tables.append({ 'name': name, 'type': table, 'functions': objs }) return tables """ Public: returns a list of dict for converting loader input parameters """ def get_loader_prologue(namespace, tags, obj, meta): prologue = [] params = _filter_param_list(obj['params'], ["[in]"]) for item in params: if param_traits.is_mbz(item): continue if type_traits.is_class_handle(item['type'], meta): name = subt(namespace, tags, item['name']) tname = _remove_const_ptr(subt(namespace, tags, item['type'])) # e.g., "xe_device_handle_t" -> "xe_device_object_t" obj_name = re.sub(r"(\w+)_handle_t", r"\1_object_t", tname) fty_name = re.sub(r"(\w+)_handle_t", r"\1_factory", tname) if type_traits.is_pointer(item['type']): range_start = param_traits.range_start(item) range_end = param_traits.range_end(item) prologue.append({ 'name': name, 'obj': obj_name, 'range': (range_start, range_end), 'type': tname, 'factory': fty_name }) else: prologue.append({ 'name': name, 'obj': obj_name, 'optional': param_traits.is_optional(item) }) return prologue """ Public: returns a list of dict for converting loader output parameters """ def get_loader_epilogue(namespace, tags, obj, meta): epilogue = [] for i, item in enumerate(obj['params']): if param_traits.is_mbz(item): continue if param_traits.is_release(item) or param_traits.is_output(item) or param_traits.is_inoutput(item): if type_traits.is_class_handle(item['type'], meta): name = subt(namespace, tags, item['name']) tname = _remove_const_ptr(subt(namespace, tags, item['type'])) obj_name = re.sub(r"(\w+)_handle_t", r"\1_object_t", tname) fty_name = re.sub(r"(\w+)_handle_t", r"\1_factory", tname) if param_traits.is_range(item): range_start = param_traits.range_start(item) range_end = param_traits.range_end(item) epilogue.append({ 'name': name, 'type': tname, 'obj': obj_name, 'factory': fty_name, 'release': param_traits.is_release(item), 'range': (range_start, range_end) }) else: epilogue.append({ 'name': name, 'type': tname, 'obj': obj_name, 'factory': fty_name, 'release': param_traits.is_release(item), 'optional': param_traits.is_optional(item) }) return epilogue """ Public: returns true if proc table is added after 1.0 """ def isNewProcTable(tableName): return tableName in ["zesGetGlobalProcAddrTable","zesGetOverclockProcAddrTable","zesGetVFManagementProcAddrTable"]