diff options
Diffstat (limited to 'codegen/vulkan/scripts/spec_tools/validity.py')
-rw-r--r-- | codegen/vulkan/scripts/spec_tools/validity.py | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/codegen/vulkan/scripts/spec_tools/validity.py b/codegen/vulkan/scripts/spec_tools/validity.py deleted file mode 100644 index 745ba013..00000000 --- a/codegen/vulkan/scripts/spec_tools/validity.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/python3 -i -# -# Copyright 2013-2021 The Khronos Group Inc. -# -# SPDX-License-Identifier: Apache-2.0 - -import re - - -_A_VS_AN_RE = re.compile(r' a ([a-z]+:)?([aAeEiIoOxX]\w+\b)(?!:)') - -_STARTS_WITH_MACRO_RE = re.compile(r'^[a-z]+:.*') - - -def _checkAnchorComponents(anchor): - """Raise an exception if any component of a VUID anchor name is illegal.""" - if anchor: - # Any other invalid things in an anchor name should be detected here. - if any((' ' in anchor_part for anchor_part in anchor)): - raise RuntimeError("Illegal component of a VUID anchor name!") - - -def _fix_a_vs_an(s): - """Fix usage (often generated) of the indefinite article 'a' when 'an' is appropriate. - - Explicitly excludes the markup macros.""" - return _A_VS_AN_RE.sub(r' an \1\2', s) - - -class ValidityCollection: - """Combines validity for a single entity.""" - - def __init__(self, entity_name=None, conventions=None, strict=True): - self.entity_name = entity_name - self.conventions = conventions - self.lines = [] - self.strict = strict - - def possiblyAddExtensionRequirement(self, extension_name, entity_preface): - """Add an extension-related validity statement if required. - - entity_preface is a string that goes between "must be enabled prior to " - and the name of the entity, and normally ends in a macro. - For instance, might be "calling flink:" for a function. - """ - if extension_name and not extension_name.startswith(self.conventions.api_version_prefix): - msg = 'The {} extension must: be enabled prior to {}{}'.format( - self.conventions.formatExtension(extension_name), entity_preface, self.entity_name) - self.addValidityEntry(msg, anchor=('extension', 'notenabled')) - - def addValidityEntry(self, msg, anchor=None): - """Add a validity entry, optionally with a VUID anchor. - - If any trailing arguments are supplied, - an anchor is generated by concatenating them with dashes - at the end of the VUID anchor name. - """ - if not msg: - raise RuntimeError("Tried to add a blank validity line!") - parts = ['*'] - _checkAnchorComponents(anchor) - if anchor: - if not self.entity_name: - raise RuntimeError('Cannot add a validity entry with an anchor to a collection that does not know its entity name.') - parts.append('[[{}]]'.format( - '-'.join(['VUID', self.entity_name] + list(anchor)))) - parts.append(msg) - combined = _fix_a_vs_an(' '.join(parts)) - if combined in self.lines: - raise RuntimeError("Duplicate validity added!") - self.lines.append(combined) - - def addText(self, msg): - """Add already formatted validity text.""" - if self.strict: - raise RuntimeError('addText called when collection in strict mode') - if not msg: - return - msg = msg.rstrip() - if not msg: - return - self.lines.append(msg) - - def _extend(self, lines): - lines = list(lines) - dupes = set(lines).intersection(self.lines) - if dupes: - raise RuntimeError("The two sets contain some shared entries! " + str(dupes)) - self.lines.extend(lines) - - def __iadd__(self, other): - """Perform += with a string, iterable, or ValidityCollection.""" - if other is None: - pass - elif isinstance(other, str): - if self.strict: - raise RuntimeError( - 'Collection += a string when collection in strict mode') - if not other: - # empty string - pass - elif other.startswith('*'): - # Handle already-formatted - self.addText(other) - else: - # Do the formatting ourselves. - self.addValidityEntry(other) - elif isinstance(other, ValidityEntry): - if other: - if other.verbose: - print(self.entity_name, 'Appending', str(other)) - self.addValidityEntry(str(other), anchor=other.anchor) - elif isinstance(other, ValidityCollection): - if not self.entity_name == other.entity_name: - raise RuntimeError( - "Trying to combine two ValidityCollections for different entities!") - self._extend(other.lines) - else: - # Deal with other iterables. - self._extend(other) - - return self - - def __bool__(self): - """Is the collection non-empty?""" - empty = not self.lines - return not empty - - @property - def text(self): - """Access validity statements as a single string or None.""" - if not self.lines: - return None - return '\n'.join(self.lines) + '\n' - - def __str__(self): - """Access validity statements as a single string or empty string.""" - if not self: - return '' - return self.text - - def __repr__(self): - return '<ValidityCollection: {}>'.format(self.lines) - - -class ValidityEntry: - """A single validity line in progress.""" - - def __init__(self, text=None, anchor=None): - """Prepare to add a validity entry, optionally with a VUID anchor. - - An anchor is generated by concatenating the elements of the anchor tuple with dashes - at the end of the VUID anchor name. - """ - _checkAnchorComponents(anchor) - if isinstance(anchor, str): - # anchor needs to be a tuple - anchor = (anchor,) - - # VUID does not allow special chars except ":" - if anchor is not None: - anchor = [(anchor_value.replace('->', '::').replace('.', '::')) for anchor_value in anchor] - - self.anchor = anchor - self.parts = [] - self.verbose = False - if text: - self.append(text) - - def append(self, part): - """Append a part of a string. - - If this is the first entry part and the part doesn't start - with a markup macro, the first character will be capitalized.""" - if not self.parts and not _STARTS_WITH_MACRO_RE.match(part): - self.parts.append(part[:1].upper()) - self.parts.append(part[1:]) - else: - self.parts.append(part) - if self.verbose: - print('ValidityEntry', id(self), 'after append:', str(self)) - - def drop_end(self, n): - """Remove up to n trailing characters from the string.""" - temp = str(self) - n = min(len(temp), n) - self.parts = [temp[:-n]] - - def __iadd__(self, other): - """Perform += with a string,""" - self.append(other) - return self - - def __bool__(self): - """Return true if we have something more than just an anchor.""" - empty = not self.parts - return not empty - - def __str__(self): - """Access validity statement as a single string or empty string.""" - if not self: - raise RuntimeError("No parts added?") - return ''.join(self.parts).strip() - - def __repr__(self): - parts = ['<ValidityEntry: '] - if self: - parts.append('"') - parts.append(str(self)) - parts.append('"') - else: - parts.append('EMPTY') - if self.anchor: - parts.append(', anchor={}'.format('-'.join(self.anchor))) - parts.append('>') - return ''.join(parts) |