diff options
Diffstat (limited to 'codegen/vulkan/scripts/spec_tools/attributes.py')
-rw-r--r-- | codegen/vulkan/scripts/spec_tools/attributes.py | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/codegen/vulkan/scripts/spec_tools/attributes.py b/codegen/vulkan/scripts/spec_tools/attributes.py new file mode 100644 index 00000000..ef771811 --- /dev/null +++ b/codegen/vulkan/scripts/spec_tools/attributes.py @@ -0,0 +1,114 @@ +#!/usr/bin/python3 -i +# +# Copyright 2013-2021 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 +"""Utilities for working with attributes of the XML registry.""" + +import re + +_PARAM_REF_NAME_RE = re.compile( + r"(?P<name>[\w]+)(?P<brackets>\[\])?(?P<delim>\.|::|->)?") + + +def _split_param_ref(val): + return [name for name, _, _ in _PARAM_REF_NAME_RE.findall(val)] + + +def _human_readable_deref(val, make_param_name=None): + """Turn the "name[].member[]" notation into plain English.""" + parts = [] + matches = _PARAM_REF_NAME_RE.findall(val) + for name, brackets, delim in reversed(matches): + if make_param_name: + name = make_param_name(name) + if delim: + parts.append('member of') + if brackets: + parts.append('each element of') + parts.append('the') + parts.append(name) + parts.append('parameter') + return ' '.join(parts) + + +class LengthEntry: + """An entry in a (comma-separated) len attribute""" + NULL_TERMINATED_STRING = 'null-terminated' + MATH_STRING = 'latexmath:' + + def __init__(self, val): + self.full_reference = val + self.other_param_name = None + self.null_terminated = False + self.number = None + self.math = None + self.param_ref_parts = None + if val == LengthEntry.NULL_TERMINATED_STRING: + self.null_terminated = True + return + + if val.startswith(LengthEntry.MATH_STRING): + self.math = val.replace(LengthEntry.MATH_STRING, '')[1:-1] + return + + if val.isdigit(): + self.number = int(val) + return + + # Must be another param name. + self.param_ref_parts = _split_param_ref(val) + self.other_param_name = self.param_ref_parts[0] + + def __str__(self): + return self.full_reference + + def get_human_readable(self, make_param_name=None): + assert(self.other_param_name) + return _human_readable_deref(self.full_reference, make_param_name=make_param_name) + + def __repr__(self): + "Formats an object for repr(), debugger display, etc." + return 'spec_tools.attributes.LengthEntry("{}")'.format(self.full_reference) + + @staticmethod + def parse_len_from_param(param): + """Get a list of LengthEntry.""" + len_str = param.get('len') + if len_str is None: + return None + return [LengthEntry(elt) for elt in len_str.split(',')] + + +class ExternSyncEntry: + """An entry in a (comma-separated) externsync attribute""" + + TRUE_STRING = 'true' + TRUE_WITH_CHILDREN_STRING = 'true_with_children' + + def __init__(self, val): + self.full_reference = val + self.entirely_extern_sync = (val in (ExternSyncEntry.TRUE_STRING, ExternSyncEntry.TRUE_WITH_CHILDREN_STRING)) + self.children_extern_sync = (val == ExternSyncEntry.TRUE_WITH_CHILDREN_STRING) + if self.entirely_extern_sync: + return + + self.param_ref_parts = _split_param_ref(val) + self.member = self.param_ref_parts[0] + + def get_human_readable(self, make_param_name=None): + assert(not self.entirely_extern_sync) + return _human_readable_deref(self.full_reference, make_param_name=make_param_name) + + @staticmethod + def parse_externsync_from_param(param): + """Get a list of ExternSyncEntry.""" + sync_str = param.get('externsync') + if sync_str is None: + return None + return [ExternSyncEntry(elt) for elt in sync_str.split(',')] + + def __repr__(self): + "Formats an object for repr(), debugger display, etc." + return 'spec_tools.attributes.ExternSyncEntry("{}")'.format(self.full_reference) + |