early-access version 2323
This commit is contained in:
69
externals/Vulkan-Headers/registry/generator.py
vendored
69
externals/Vulkan-Headers/registry/generator.py
vendored
@@ -43,7 +43,10 @@ def enquote(s):
|
||||
"""Return string argument with surrounding quotes,
|
||||
for serialization into Python code."""
|
||||
if s:
|
||||
return "'{}'".format(s)
|
||||
if isinstance(s, str):
|
||||
return "'{}'".format(s)
|
||||
else:
|
||||
return s
|
||||
return None
|
||||
|
||||
|
||||
@@ -119,8 +122,11 @@ class GeneratorOptions:
|
||||
removeExtensions=None,
|
||||
emitExtensions=None,
|
||||
emitSpirv=None,
|
||||
emitFormats=None,
|
||||
reparentEnums=True,
|
||||
sortProcedure=regSortFeatures):
|
||||
sortProcedure=regSortFeatures,
|
||||
requireCommandAliases=False,
|
||||
):
|
||||
"""Constructor.
|
||||
|
||||
Arguments:
|
||||
@@ -152,6 +158,8 @@ class GeneratorOptions:
|
||||
to None.
|
||||
- emitSpirv - regex matching names of extensions and capabilities
|
||||
to actually emit interfaces for.
|
||||
- emitFormats - regex matching names of formats to actually emit
|
||||
interfaces for.
|
||||
- reparentEnums - move <enum> elements which extend an enumerated
|
||||
type from <feature> or <extension> elements to the target <enums>
|
||||
element. This is required for almost all purposes, but the
|
||||
@@ -217,6 +225,10 @@ class GeneratorOptions:
|
||||
"""regex matching names of extensions and capabilities
|
||||
to actually emit interfaces for."""
|
||||
|
||||
self.emitFormats = self.emptyRegex(emitFormats)
|
||||
"""regex matching names of formats
|
||||
to actually emit interfaces for."""
|
||||
|
||||
self.reparentEnums = reparentEnums
|
||||
"""boolean specifying whether to remove <enum> elements from
|
||||
<feature> or <extension> when extending an <enums> type."""
|
||||
@@ -230,6 +242,10 @@ class GeneratorOptions:
|
||||
self.codeGenerator = False
|
||||
"""True if this generator makes compilable code"""
|
||||
|
||||
self.requireCommandAliases = requireCommandAliases
|
||||
"""True if alias= attributes of <command> tags are transitively
|
||||
required."""
|
||||
|
||||
def emptyRegex(self, pat):
|
||||
"""Substitute a regular expression which matches no version
|
||||
or extension names for None or the empty string."""
|
||||
@@ -257,6 +273,17 @@ class OutputGenerator:
|
||||
'basetype': 'basetypes',
|
||||
}
|
||||
|
||||
def breakName(self, name, msg):
|
||||
"""Break into debugger if this is a special name"""
|
||||
|
||||
# List of string names to break on
|
||||
bad = (
|
||||
)
|
||||
|
||||
if name in bad and True:
|
||||
print('breakName {}: {}'.format(name, msg))
|
||||
pdb.set_trace()
|
||||
|
||||
def __init__(self, errFile=sys.stderr, warnFile=sys.stderr, diagFile=sys.stdout):
|
||||
"""Constructor
|
||||
|
||||
@@ -337,7 +364,7 @@ class OutputGenerator:
|
||||
# print('About to translate value =', value, 'type =', type(value))
|
||||
if needsNum:
|
||||
numVal = int(value, 0)
|
||||
# If there's a non-integer, numeric 'type' attribute (e.g. 'u' or
|
||||
# If there is a non-integer, numeric 'type' attribute (e.g. 'u' or
|
||||
# 'ull'), append it to the string value.
|
||||
# t = enuminfo.elem.get('type')
|
||||
# if t is not None and t != '' and t != 'i' and t != 's':
|
||||
@@ -418,7 +445,7 @@ class OutputGenerator:
|
||||
+ ') found with different values:' + strVal
|
||||
+ ' and ' + strVal2)
|
||||
|
||||
# Don't add the duplicate to the returned list
|
||||
# Do not add the duplicate to the returned list
|
||||
continue
|
||||
elif numVal in valueMap:
|
||||
# Duplicate value found (such as an alias); report it, but
|
||||
@@ -519,7 +546,7 @@ class OutputGenerator:
|
||||
|
||||
# Accumulate non-numeric enumerant values separately and append
|
||||
# them following the numeric values, to allow for aliases.
|
||||
# NOTE: this doesn't do a topological sort yet, so aliases of
|
||||
# NOTE: this does not do a topological sort yet, so aliases of
|
||||
# aliases can still get in the wrong order.
|
||||
aliasText = ''
|
||||
|
||||
@@ -553,7 +580,7 @@ class OutputGenerator:
|
||||
# Work around this by chasing the aliases to get the actual value.
|
||||
while numVal is None:
|
||||
alias = self.registry.tree.find("enums/enum[@name='" + strVal + "']")
|
||||
(numVal, strVal) = self.enumToValue(alias, True)
|
||||
(numVal, strVal) = self.enumToValue(alias, True, bitwidth, True)
|
||||
decl += "static const {} {} = {};\n".format(flagTypeName, name, strVal)
|
||||
|
||||
if numVal is not None:
|
||||
@@ -612,7 +639,7 @@ class OutputGenerator:
|
||||
|
||||
# Accumulate non-numeric enumerant values separately and append
|
||||
# them following the numeric values, to allow for aliases.
|
||||
# NOTE: this doesn't do a topological sort yet, so aliases of
|
||||
# NOTE: this does not do a topological sort yet, so aliases of
|
||||
# aliases can still get in the wrong order.
|
||||
aliasText = []
|
||||
|
||||
@@ -651,7 +678,7 @@ class OutputGenerator:
|
||||
self.logMsg('error', 'Allowable range for C enum types is [', minValidValue, ',', maxValidValue, '], but', name, 'has a value outside of this (', strVal, ')\n')
|
||||
exit(1)
|
||||
|
||||
# Don't track min/max for non-numbers (numVal is None)
|
||||
# Do not track min/max for non-numbers (numVal is None)
|
||||
if isEnum and numVal is not None and elem.get('extends') is None:
|
||||
if minName is None:
|
||||
minName = maxName = name
|
||||
@@ -674,7 +701,7 @@ class OutputGenerator:
|
||||
" {}_RANGE_SIZE{} = ({} - {} + 1),".format(expandPrefix, expandSuffix, maxName, minName)))
|
||||
|
||||
# Generate a range-padding value to ensure the enum is 32 bits, but
|
||||
# only in code generators, so it doesn't appear in documentation
|
||||
# only in code generators, so it does not appear in documentation
|
||||
if (self.genOpts.codeGenerator or
|
||||
self.conventions.generate_max_enum_in_docs):
|
||||
body.append(" {}_MAX_ENUM{} = 0x7FFFFFFF".format(
|
||||
@@ -747,7 +774,7 @@ class OutputGenerator:
|
||||
def beginFile(self, genOpts):
|
||||
"""Start a new interface file
|
||||
|
||||
- genOpts - GeneratorOptions controlling what's generated and how"""
|
||||
- genOpts - GeneratorOptions controlling what is generated and how"""
|
||||
self.genOpts = genOpts
|
||||
self.should_insert_may_alias_macro = \
|
||||
self.genOpts.conventions.should_insert_may_alias_macro(self.genOpts)
|
||||
@@ -778,7 +805,6 @@ class OutputGenerator:
|
||||
self.warnFile.flush()
|
||||
if self.diagFile:
|
||||
self.diagFile.flush()
|
||||
self.outFile.flush()
|
||||
if self.outFile != sys.stdout and self.outFile != sys.stderr:
|
||||
self.outFile.close()
|
||||
|
||||
@@ -800,7 +826,7 @@ class OutputGenerator:
|
||||
- emit - actually write to the header only when True"""
|
||||
self.emit = emit
|
||||
self.featureName = interface.get('name')
|
||||
# If there's an additional 'protect' attribute in the feature, save it
|
||||
# If there is an additional 'protect' attribute in the feature, save it
|
||||
self.featureExtraProtect = interface.get('protect')
|
||||
|
||||
def endFeature(self):
|
||||
@@ -812,7 +838,7 @@ class OutputGenerator:
|
||||
|
||||
def genRequirements(self, name, mustBeFound = True):
|
||||
"""Generate text showing what core versions and extensions introduce
|
||||
an API. This exists in the base Generator class because it's used by
|
||||
an API. This exists in the base Generator class because it is used by
|
||||
the shared enumerant-generating interfaces (buildEnumCDecl, etc.).
|
||||
Here it returns an empty string for most generators, but can be
|
||||
overridden by e.g. DocGenerator.
|
||||
@@ -825,7 +851,7 @@ class OutputGenerator:
|
||||
return ''
|
||||
|
||||
def validateFeature(self, featureType, featureName):
|
||||
"""Validate we're generating something only inside a `<feature>` tag"""
|
||||
"""Validate we are generating something only inside a `<feature>` tag"""
|
||||
if self.featureName is None:
|
||||
raise UserWarning('Attempt to generate', featureType,
|
||||
featureName, 'when not in feature')
|
||||
@@ -887,6 +913,14 @@ class OutputGenerator:
|
||||
Extend to generate as desired in your derived class."""
|
||||
return
|
||||
|
||||
def genFormat(self, format, formatinfo, alias):
|
||||
"""Generate interface for a format element.
|
||||
|
||||
- formatinfo - FormatInfo
|
||||
|
||||
Extend to generate as desired in your derived class."""
|
||||
return
|
||||
|
||||
def makeProtoName(self, name, tail):
|
||||
"""Turn a `<proto>` `<name>` into C-language prototype
|
||||
and typedef declarations for that name.
|
||||
@@ -939,6 +973,9 @@ class OutputGenerator:
|
||||
|
||||
# Clear prefix for subsequent iterations
|
||||
prefix = ''
|
||||
|
||||
paramdecl = paramdecl + prefix
|
||||
|
||||
if aligncol == 0:
|
||||
# Squeeze out multiple spaces other than the indentation
|
||||
paramdecl = indent + ' '.join(paramdecl.split())
|
||||
@@ -1013,7 +1050,7 @@ class OutputGenerator:
|
||||
return None
|
||||
|
||||
def isStructAlwaysValid(self, structname):
|
||||
"""Try to do check if a structure is always considered valid (i.e. there's no rules to its acceptance)."""
|
||||
"""Try to do check if a structure is always considered valid (i.e. there is no rules to its acceptance)."""
|
||||
# A conventions object is required for this call.
|
||||
if not self.conventions:
|
||||
raise RuntimeError("To use isStructAlwaysValid, be sure your options include a Conventions object.")
|
||||
@@ -1109,7 +1146,7 @@ class OutputGenerator:
|
||||
# Leading text
|
||||
pdecl += noneStr(proto.text)
|
||||
tdecl += noneStr(proto.text)
|
||||
# For each child element, if it's a <name> wrap in appropriate
|
||||
# For each child element, if it is a <name> wrap in appropriate
|
||||
# declaration. Otherwise append its contents and tail contents.
|
||||
for elem in proto:
|
||||
text = noneStr(elem.text)
|
||||
|
Reference in New Issue
Block a user