Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

1945 lines
64 KiB
Python

"""
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<int>(%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"]