1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#!/usr/bin/python3 -i
#
# Copyright (c) 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, or None."""
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)
_TRUE_STRING = 'true'
_FALSE_STRING = 'false'
def _parse_optional_elt(val):
if val not in (_TRUE_STRING, _FALSE_STRING):
raise ValueError("Each element of the optional attribute must be 'true', or 'false'")
return val == _TRUE_STRING
def parse_optional_from_param(param):
"""Get a list of booleans from a param: always returns at least one element."""
optional_str = param.get('optional', _FALSE_STRING)
return [_parse_optional_elt(elt) for elt in optional_str.split(',')]
def has_any_optional_in_param(param):
"""Returns True if we have any true in an optional attribute."""
return any(parse_optional_from_param(param))
|