diff options
Diffstat (limited to 'codegen/vulkan/scripts/spec_tools/shared.py')
-rw-r--r-- | codegen/vulkan/scripts/spec_tools/shared.py | 257 |
1 files changed, 0 insertions, 257 deletions
diff --git a/codegen/vulkan/scripts/spec_tools/shared.py b/codegen/vulkan/scripts/spec_tools/shared.py deleted file mode 100644 index bb6f1657..00000000 --- a/codegen/vulkan/scripts/spec_tools/shared.py +++ /dev/null @@ -1,257 +0,0 @@ -"""Types, constants, and utility functions used by multiple sub-modules in spec_tools.""" - -# Copyright (c) 2018-2019 Collabora, Ltd. -# -# SPDX-License-Identifier: Apache-2.0 -# -# Author(s): Ryan Pavlik <ryan.pavlik@collabora.com> - -import platform -from collections import namedtuple -from enum import Enum -from inspect import getframeinfo -from pathlib import Path -from sys import stdout - -# if we have termcolor and we know our stdout is a TTY, -# pull it in and use it. -if hasattr(stdout, 'isatty') and stdout.isatty(): - try: - from termcolor import colored as colored_impl - HAVE_COLOR = True - except ImportError: - HAVE_COLOR = False -elif platform.system() == 'Windows': - try: - from termcolor import colored as colored_impl - import colorama - colorama.init() - HAVE_COLOR = True - except ImportError: - HAVE_COLOR = False - -else: - HAVE_COLOR = False - - -def colored(s, color=None, attrs=None): - """Call termcolor.colored with same arguments if this is a tty and it is available.""" - if HAVE_COLOR: - return colored_impl(s, color, attrs=attrs) - return s - - -### -# Constants used in multiple places. -AUTO_FIX_STRING = 'Note: Auto-fix available.' -EXTENSION_CATEGORY = 'extension' -CATEGORIES_WITH_VALIDITY = set(('protos', 'structs')) -NON_EXISTENT_MACROS = set(('plink', 'ttext', 'dtext')) - -### -# MessageContext: All the information about where a message relates to. -MessageContext = namedtuple('MessageContext', - ['filename', 'lineNum', 'line', - 'match', 'group']) - - -def getInterestedRange(message_context): - """Return a (start, end) pair of character index for the match in a MessageContext.""" - if not message_context.match: - # whole line - return (0, len(message_context.line)) - return (message_context.match.start(), message_context.match.end()) - - -def getHighlightedRange(message_context): - """Return a (start, end) pair of character index for the highlighted range in a MessageContext.""" - if message_context.group is not None and message_context.match is not None: - return (message_context.match.start(message_context.group), - message_context.match.end(message_context.group)) - # no group (whole match) or no match (whole line) - return getInterestedRange(message_context) - - -def toNameAndLine(context, root_path=None): - """Convert MessageContext into a simple filename:line string.""" - my_fn = Path(context.filename) - if root_path: - my_fn = my_fn.relative_to(root_path) - return '{}:{}'.format(str(my_fn), context.lineNum) - - -def generateInclude(dir_traverse, generated_type, category, entity): - """Create an include:: directive for geneated api or validity from the various pieces.""" - return 'include::{directory_traverse}{generated_type}/{category}/{entity_name}.txt[]'.format( - directory_traverse=dir_traverse, - generated_type=generated_type, - category=category, - entity_name=entity) - - -# Data stored per entity (function, struct, enumerant type, enumerant, extension, etc.) -EntityData = namedtuple( - 'EntityData', ['entity', 'macro', 'elem', 'filename', 'category', 'directory']) - - -class MessageType(Enum): - """Type of a message.""" - - WARNING = 1 - ERROR = 2 - NOTE = 3 - - def __str__(self): - """Format a MessageType as a lowercase string.""" - return str(self.name).lower() - - def formattedWithColon(self): - """Format a MessageType as a colored, lowercase string followed by a colon.""" - if self == MessageType.WARNING: - return colored(str(self) + ':', 'magenta', attrs=['bold']) - if self == MessageType.ERROR: - return colored(str(self) + ':', 'red', attrs=['bold']) - return str(self) + ':' - - -class MessageId(Enum): - """Enumerates the varieties of messages that can be generated. - - Control over enabled messages with -Wbla or -Wno_bla is per-MessageId. - """ - - MISSING_TEXT = 1 - LEGACY = 2 - WRONG_MACRO = 3 - MISSING_MACRO = 4 - BAD_ENTITY = 5 - BAD_ENUMERANT = 6 - BAD_MACRO = 7 - UNRECOGNIZED_CONTEXT = 8 - UNKNOWN_MEMBER = 9 - DUPLICATE_INCLUDE = 10 - UNKNOWN_INCLUDE = 11 - API_VALIDITY_ORDER = 12 - UNDOCUMENTED_MEMBER = 13 - MEMBER_PNAME_MISSING = 14 - MISSING_VALIDITY_INCLUDE = 15 - MISSING_API_INCLUDE = 16 - MISUSED_TEXT = 17 - EXTENSION = 18 - REFPAGE_TAG = 19 - REFPAGE_MISSING_DESC = 20 - REFPAGE_XREFS = 21 - REFPAGE_XREFS_COMMA = 22 - REFPAGE_TYPE = 23 - REFPAGE_NAME = 24 - REFPAGE_BLOCK = 25 - REFPAGE_MISSING = 26 - REFPAGE_MISMATCH = 27 - REFPAGE_UNKNOWN_ATTRIB = 28 - REFPAGE_SELF_XREF = 29 - REFPAGE_XREF_DUPE = 30 - REFPAGE_WHITESPACE = 31 - REFPAGE_DUPLICATE = 32 - UNCLOSED_BLOCK = 33 - - def __str__(self): - """Format as a lowercase string.""" - return self.name.lower() - - def enable_arg(self): - """Return the corresponding Wbla string to make the 'enable this message' argument.""" - return 'W{}'.format(self.name.lower()) - - def disable_arg(self): - """Return the corresponding Wno_bla string to make the 'enable this message' argument.""" - return 'Wno_{}'.format(self.name.lower()) - - def desc(self): - """Return a brief description of the MessageId suitable for use in --help.""" - return MessageId.DESCRIPTIONS[self] - - -MessageId.DESCRIPTIONS = { - MessageId.MISSING_TEXT: "a *text: macro is expected but not found", - MessageId.LEGACY: "legacy usage of *name: macro when *link: is applicable", - MessageId.WRONG_MACRO: "wrong macro used for an entity", - MessageId.MISSING_MACRO: "a macro might be missing", - MessageId.BAD_ENTITY: "entity not recognized, etc.", - MessageId.BAD_ENUMERANT: "unrecognized enumerant value used in ename:", - MessageId.BAD_MACRO: "unrecognized macro used", - MessageId.UNRECOGNIZED_CONTEXT: "pname used with an unrecognized context", - MessageId.UNKNOWN_MEMBER: "pname used but member/argument by that name not found", - MessageId.DUPLICATE_INCLUDE: "duplicated include line", - MessageId.UNKNOWN_INCLUDE: "include line specified file we wouldn't expect to exists", - MessageId.API_VALIDITY_ORDER: "saw API include after validity include", - MessageId.UNDOCUMENTED_MEMBER: "saw an apparent struct/function documentation, but missing a member", - MessageId.MEMBER_PNAME_MISSING: "pname: missing from a 'scope' operator", - MessageId.MISSING_VALIDITY_INCLUDE: "missing validity include", - MessageId.MISSING_API_INCLUDE: "missing API include", - MessageId.MISUSED_TEXT: "a *text: macro is found but not expected", - MessageId.EXTENSION: "an extension name is incorrectly marked", - MessageId.REFPAGE_TAG: "a refpage tag is missing an expected field", - MessageId.REFPAGE_MISSING_DESC: "a refpage tag has an empty description", - MessageId.REFPAGE_XREFS: "an unrecognized entity is mentioned in xrefs of a refpage tag", - MessageId.REFPAGE_XREFS_COMMA: "a comma was founds in xrefs of a refpage tag, which is space-delimited", - MessageId.REFPAGE_TYPE: "a refpage tag has an incorrect type field", - MessageId.REFPAGE_NAME: "a refpage tag has an unrecognized entity name in its refpage field", - MessageId.REFPAGE_BLOCK: "a refpage block is not correctly opened or closed.", - MessageId.REFPAGE_MISSING: "an API include was found outside of a refpage block.", - MessageId.REFPAGE_MISMATCH: "an API or validity include was found in a non-matching refpage block.", - MessageId.REFPAGE_UNKNOWN_ATTRIB: "a refpage tag has an unrecognized attribute", - MessageId.REFPAGE_SELF_XREF: "a refpage tag has itself in the list of cross-references", - MessageId.REFPAGE_XREF_DUPE: "a refpage cross-references list has at least one duplicate", - MessageId.REFPAGE_WHITESPACE: "a refpage cross-references list has non-minimal whitespace", - MessageId.REFPAGE_DUPLICATE: "a refpage tag has been seen for a single entity for a second time", - MessageId.UNCLOSED_BLOCK: "one or more blocks remain unclosed at the end of a file" -} - - -class Message(object): - """An Error, Warning, or Note with a MessageContext, MessageId, and message text. - - May optionally have a replacement, a see_also array, an auto-fix, - and a stack frame where the message was created. - """ - - def __init__(self, message_id, message_type, message, context, - replacement=None, see_also=None, fix=None, frame=None): - """Construct a Message. - - Typically called by MacroCheckerFile.diag(). - """ - self.message_id = message_id - - self.message_type = message_type - - if isinstance(message, str): - self.message = [message] - else: - self.message = message - - self.context = context - if context is not None and context.match is not None and context.group is not None: - if context.group not in context.match.groupdict(): - raise RuntimeError( - 'Group "{}" does not exist in the match'.format(context.group)) - - self.replacement = replacement - - self.fix = fix - - if see_also is None: - self.see_also = None - elif isinstance(see_also, MessageContext): - self.see_also = [see_also] - else: - self.see_also = see_also - - self.script_location = None - if frame: - try: - frameinfo = getframeinfo(frame) - self.script_location = "{}:{}".format( - frameinfo.filename, frameinfo.lineno) - finally: - del frame |