summaryrefslogtreecommitdiffhomepage
path: root/registry/reg.py
diff options
context:
space:
mode:
Diffstat (limited to 'registry/reg.py')
-rwxr-xr-x[-rw-r--r--]registry/reg.py87
1 files changed, 58 insertions, 29 deletions
diff --git a/registry/reg.py b/registry/reg.py
index fb30ed8..27164c8 100644..100755
--- a/registry/reg.py
+++ b/registry/reg.py
@@ -19,7 +19,8 @@ import re
import sys
import xml.etree.ElementTree as etree
from collections import defaultdict, namedtuple
-from generator import OutputGenerator, write
+from generator import OutputGenerator, write, noneInt
+import pdb
# matchAPIProfile - returns whether an API and profile
# being generated matches an element's profile
@@ -70,6 +71,12 @@ def matchAPIProfile(api, profile, elem):
return False
return True
+# Print all the keys in an Element - only for diagnostics
+# def printKeys(msg, elem):
+# print('printKeys:', msg, file=sys.stderr)
+# for key in elem.keys():
+# print(' {} -> {}'.format(key, elem.get(key)), file=sys.stderr)
+
# BaseInfo - base class for information about a registry feature
# (type/group/enum/command/API/extension).
# required - should this feature be defined during header generation
@@ -89,26 +96,41 @@ class BaseInfo:
def resetState(self):
self.required = False
self.declared = False
- def compareElem(self, info):
- # Just compares the tag and attributes.
- # @@ This should be virtualized. In particular, comparing <enum>
- # tags requires special-casing on the attributes, as 'extnumber' is
- # only relevant when 'offset' is present.
- selfKeys = sorted(self.elem.keys())
- infoKeys = sorted(info.elem.keys())
-
- if selfKeys != infoKeys:
+ def compareKeys(self, info, key, required = False):
+ # Return True if self.elem and info.elem have the same attribute
+ # value for key.
+ # If 'required' is not True, also returns True if neither element
+ # has an attribute value for key.
+ if required and key not in self.elem.keys():
return False
-
- # Ignore value of 'extname' and 'extnumber', as these will inherently
- # be different when redefining the same interface in different feature
- # and/or extension blocks.
- for key in selfKeys:
- if key not in ('extname', 'extnumber') and \
- (self.elem.get(key) != info.elem.get(key)):
+ return self.elem.get(key) == info.elem.get(key)
+ def compareElem(self, info, infoName):
+ # Return True if self.elem and info.elem have the same definition
+ # info - the other object
+ # infoName - 'type' / 'group' / 'enum' / 'command' / 'feature' / 'extension'
+
+ if infoName == 'enum':
+ if self.compareKeys(info, 'extends'):
+ # Either both extend the same type, or no type
+ if (self.compareKeys(info, 'value', required = True) or
+ self.compareKeys(info, 'bitpos', required = True)):
+ # If both specify the same value or bit position,
+ # they're equal
+ return True
+ elif (self.compareKeys(info, 'extends') and
+ self.compareKeys(info, 'extnumber') and
+ self.compareKeys(info, 'offset') and
+ self.compareKeys(info, 'dir')):
+ # If both specify the same relative offset, they're equal
+ return True
+ else:
+ return False
+ else:
+ # The same enum can't extend two different types
return False
-
- return True
+ else:
+ # Non-<enum>s should never be redefined
+ return False
# TypeInfo - registry information about a type. No additional state
# beyond BaseInfo is required.
@@ -164,29 +186,34 @@ class CmdInfo(BaseInfo):
# FeatureInfo - registry information about an API <feature>
# or <extension>
# name - feature name string (e.g. 'VK_KHR_surface')
-# version - feature version number (e.g. 1.2). <extension>
+# category - category, e.g. VERSION or khr/vendor tag
+# version - feature name string
# features are unversioned and assigned version number 0.
# ** This is confusingly taken from the 'number' attribute of <feature>.
# Needs fixing.
+# versionNumber - API version number, taken from the 'number' attribute
+# of <feature>. Extensions do not have API version numbers and are
+# assigned number 0.
# number - extension number, used for ordering and for
# assigning enumerant offsets. <feature> features do
# not have extension numbers and are assigned number 0.
-# category - category, e.g. VERSION or khr/vendor tag
# emit - has this feature been defined already?
class FeatureInfo(BaseInfo):
"""Represents the state of an API feature (version/extension)"""
def __init__(self, elem):
BaseInfo.__init__(self, elem)
self.name = elem.get('name')
- # Determine element category (vendor). Only works
- # for <extension> elements.
+ self.sortorder = noneInt(elem.get('sortorder'), 0)
+
if elem.tag == 'feature':
+ # Element category (vendor) is meaningless for <feature>
self.category = 'VERSION'
self.version = elem.get('name')
self.versionNumber = elem.get('number')
self.number = "0"
self.supported = None
else:
+ # Extract vendor portion of VK_<vendor>_<name>
self.category = self.name.split('_', 2)[1]
self.version = "0"
self.versionNumber = "0"
@@ -295,12 +322,14 @@ class Registry:
else:
key = elem.get('name')
if key in dictionary:
- if not dictionary[key].compareElem(info):
+ if not dictionary[key].compareElem(info, infoName):
self.gen.logMsg('warn', 'Attempt to redefine', key,
- 'with different value (this may be benign)')
- #else:
- # self.gen.logMsg('warn', 'Benign redefinition of', key,
- # 'with identical value')
+ '(this should not happen)')
+ # printKeys('old element', dictionary[key].elem)
+ # printKeys('new element', info.elem)
+ else:
+ # Benign redefinition - intentional cases exist.
+ True
else:
dictionary[key] = info
@@ -1053,7 +1082,7 @@ class Registry:
self.gen.logMsg('diag', 'NOT including extension',
extName, '(does not match api attribute or explicitly requested extensions)')
- # Sort the extension features list, if a sort procedure is defined
+ # Sort the features list, if a sort procedure is defined
if self.genOpts.sortProcedure:
self.genOpts.sortProcedure(features)