Vulkan-Docs/scripts/spec_tools/base_printer.py

173 lines
5.6 KiB
Python
Raw Normal View History

Change log for February 3, 2019 Vulkan 1.1.99 spec update: * Update release number to 99. Public Issues: * Add missing pname:pMemoryHostPointerProperties description to flink:vkGetMemoryHostPointerPropertiesEXT.txt (public pull request 896). * Minor markup fixes (public pull request 900). * Minor update to `khronos.css` and markup fixes (originally proposed in public pull request 901, but done via an internal MR). Internal Issues: * Document restrictions on image queries for Y'CbCr formats in the <<features-formats-requiring-sampler-ycbcr-conversion>> table as well as for slink:sname:VkImageFormatProperties and slink:VkImageCreateInfo (internal issue 1361). * Correct type of the code:FragSizeEXT built-in in the <<interfaces-builtin-variables, Built-In Variables>> section (internal issue 1526). * Clean up math in the <<textures, Image Operations>> chapter by refactoring, using better naming conventions, updating diagrams to use the correct orientation, etc. (internal merge request 2968). * Fix minor typos for slink:VkImageCreateInfo and slink:VkImageStencilUsageCreateInfoEXT. * Add missing documentation for tlink:VkResolveModeFlagsKHR. * Fix extension dependency of pname:scalarBlockLayout in the <<features-features-requirements, Feature Requirements>> section. * Fix indexing math for shader binding table calculations in the <<shader-binding-table-indexing-rules, Indexing Rules>> section, and use spelling "`any-hit`" consistently. * Reconcile valid usage statement and text for sampled image layouts in slink:VkWriteDescriptorSet (https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/551). * Make SPIR-V code:OpConvertUToPtr and code:OpConvertPtrToU operations require a 64-bit integer for physical storage buffer pointers in the <<spirvenv-module-validation, Validation Rules within a Module>> section. * Update to KaTeX 10.0. New Extensions: * `VK_EXT_filter_cubic` * `VK_NV_dedicated_allocation_image_aliasing`
2019-02-04 09:26:23 +00:00
"""Provides the BasePrinter base class for MacroChecker/Message output techniques."""
# Copyright (c) 2018-2019 Collabora, Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author(s): Ryan Pavlik <ryan.pavlik@collabora.com>
from abc import ABC, abstractmethod
from pathlib import Path
from .macro_checker import MacroChecker
from .macro_checker_file import MacroCheckerFile
from .shared import EntityData, Message, MessageContext, MessageType
def getColumn(message_context):
"""Return the (zero-based) column number of the message context.
If a group is specified: returns the column of the start of the group.
If no group, but a match is specified: returns the column of the start of the match.
If no match: returns column 0 (whole line).
"""
if not message_context.match:
# whole line
return 0
if message_context.group is not None:
return message_context.match.start(message_context.group)
return message_context.match.start()
class BasePrinter(ABC):
"""Base class for a way of outputting results of a checker execution."""
def __init__(self):
"""Constructor."""
self.cwd = None
def close(self):
"""Write the tail end of the output and close it, if applicable.
Override if you want to print a summary or are writing to a file.
"""
pass
###
# Output methods: these should all print/output directly.
def output(self, obj):
"""Output any object.
Delegates to other output* methods, if type known,
otherwise uses self.outputFallback().
"""
if isinstance(obj, Message):
self.outputMessage(obj)
elif isinstance(obj, MacroCheckerFile):
self.outputCheckerFile(obj)
elif isinstance(obj, MacroChecker):
self.outputChecker(obj)
else:
self.outputFallback(self.formatBrief(obj))
@abstractmethod
def outputResults(self, checker, broken_links=True,
missing_includes=False):
"""Output the full results of a checker run.
Must be implemented. Typically will call self.output()
on the MacroChecker, as well as possibly outputting
broken links (if broken_links==True)
and missing includes (if missing_includes==True).
"""
raise NotImplementedError
def outputChecker(self, checker):
"""Output the contents of a MacroChecker object.
Default implementation calls self.output() on every MacroCheckerFile.
"""
for f in checker.files:
self.output(f)
def outputCheckerFile(self, fileChecker):
"""Output the contents of a MacroCheckerFile object.
Default implementation calls self.output() on every Message.
"""
for m in fileChecker.messages:
self.output(m)
@abstractmethod
def outputMessage(self, msg):
"""Output a Message.
Must be implemented.
"""
raise NotImplementedError
@abstractmethod
def outputFallback(self, msg):
"""Output some text in a general way.
Must be implemented.
"""
raise NotImplementedError
###
# Format methods: these should all return a string.
def formatContext(self, context, message_type=None):
"""Format a message context in a verbose way, if applicable.
May override, default implementation delegates to self.formatContextBrief().
"""
return self.formatContextBrief(context)
def formatContextBrief(self, context, with_color=True):
"""Format a message context in a brief way.
May override, default is relativeFilename:line:column
"""
return '{}:{}:{}'.format(self.getRelativeFilename(context.filename),
context.lineNum, getColumn(context))
def formatMessageTypeBrief(self, message_type, with_color=True):
"""Format a message type in a brief way.
May override, default is message_type:
"""
return '{}:'.format(message_type)
def formatEntityBrief(self, entity_data, with_color=True):
"""Format an entity in a brief way.
May override, default is macro:entity.
"""
return '{}:{}'.format(entity_data.macro, entity_data.entity)
def formatBrief(self, obj, with_color=True):
"""Format any object in a brief way.
Delegates to other format*Brief methods, if known,
otherwise uses str().
"""
if isinstance(obj, MessageContext):
return self.formatContextBrief(obj, with_color)
if isinstance(obj, MessageType):
return self.formatMessageTypeBrief(obj, with_color)
if isinstance(obj, EntityData):
return self.formatEntityBrief(obj, with_color)
return str(obj)
###
# Helper function
def getRelativeFilename(self, fn):
"""Return the given filename relative to the current directory, if possible."""
if not self.cwd:
# lazy init this member.
self.cwd = Path('.').resolve()
try:
return str(Path(fn).relative_to(self.cwd))
except ValueError:
return str(Path(fn))