diff options
| author | Mike Schuchardt <mikes@lunarg.com> | 2018-02-21 15:59:17 -0700 |
|---|---|---|
| committer | Mike Schuchardt <mikes@lunarg.com> | 2018-03-09 13:54:31 -0700 |
| commit | 84d0e6e621aa6dc3a6eb23c972b3f023a706e7ad (patch) | |
| tree | a23b8a27d30d3581eb44c9e018bf205bc38f07a7 /scripts/generator.py | |
| parent | 0dd40a6100a0be62a504a67f4426b7a0d304ed5b (diff) | |
| download | usermoji-84d0e6e621aa6dc3a6eb23c972b3f023a706e7ad.tar.xz | |
header: Update to 1.1.69 private header
Change-Id: If9fc0f065f77ecff14123f665e603e6f2595d571
Diffstat (limited to 'scripts/generator.py')
| -rwxr-xr-x | scripts/generator.py | 124 |
1 files changed, 106 insertions, 18 deletions
diff --git a/scripts/generator.py b/scripts/generator.py index c5745986..a0f79ac2 100755 --- a/scripts/generator.py +++ b/scripts/generator.py @@ -15,7 +15,7 @@ # limitations under the License. from __future__ import unicode_literals -import io,os,re,sys +import io,os,re,sys,pdb def write( *args, **kwargs ): file = kwargs.pop('file',sys.stdout) @@ -69,7 +69,7 @@ def regSortNameKey(feature): # Second sort key for regSortFeatures. # Sorts by feature version. <extension> elements all have version number "0" def regSortFeatureVersionKey(feature): - return float(feature.version) + return float(feature.versionNumber) # Tertiary sort key for regSortFeatures. # Sorts by extension number. <feature> elements all have extension number 0. @@ -99,7 +99,7 @@ def regSortFeatures(featureList): # emitversions - regex matching API versions to actually emit # interfaces for (though all requested versions are considered # when deciding which interfaces to generate). For GL 4.3 glext.h, -# this might be '1\.[2-5]|[2-4]\.[0-9]'. +# this might be '1\.[2-5]|[2-4]\.[0-9]'. # defaultExtensions - If not None, a string which must in its # entirety match the pattern in the "supported" attribute of # the <extension>. Defaults to None. Usually the same as apiname. @@ -108,6 +108,9 @@ def regSortFeatures(featureList): # removeExtensions - regex matching names of extensions to # remove (after defaultExtensions and addExtensions). Defaults # to None. +# emitExtensions - regex matching names of extensions to actually emit +# interfaces for (though all requested versions are considered when +# deciding which interfaces to generate). # sortProcedure - takes a list of FeatureInfo objects and sorts # them in place to a preferred order in the generated output. # Default is core API versions, ARB/KHR/OES extensions, all @@ -126,6 +129,7 @@ class GeneratorOptions: defaultExtensions = None, addExtensions = None, removeExtensions = None, + emitExtensions = None, sortProcedure = regSortFeatures): self.filename = filename self.directory = directory @@ -136,6 +140,7 @@ class GeneratorOptions: self.defaultExtensions = defaultExtensions self.addExtensions = self.emptyRegex(addExtensions) self.removeExtensions = self.emptyRegex(removeExtensions) + self.emitExtensions = self.emptyRegex(emitExtensions) self.sortProcedure = sortProcedure # # Substitute a regular expression which matches no version @@ -170,16 +175,16 @@ class GeneratorOptions: # interface - element for the <version> / <extension> to generate # emit - actually write to the header only when True # endFeature() - finish an interface. -# genType(typeinfo,name) - generate interface for a type +# genType(typeinfo,name,alias) - generate interface for a type # typeinfo - TypeInfo for a type -# genStruct(typeinfo,name) - generate interface for a C "struct" type. +# genStruct(typeinfo,name,alias) - generate interface for a C "struct" type. # typeinfo - TypeInfo for a type interpreted as a struct -# genGroup(groupinfo,name) - generate interface for a group of enums (C "enum") +# genGroup(groupinfo,name,alias) - generate interface for a group of enums (C "enum") # groupinfo - GroupInfo for a group -# genEnum(enuminfo, name) - generate interface for an enum (constant) +# genEnum(enuminfo,name,alias) - generate interface for an enum (constant) # enuminfo - EnumInfo for an enum # name - enum name -# genCmd(cmdinfo) - generate interface for a command +# genCmd(cmdinfo,name,alias) - generate interface for a command # cmdinfo - CmdInfo for a command # isEnumRequired(enumElem) - return True if this <enum> element is required # elem - <enum> element to test @@ -260,6 +265,9 @@ class OutputGenerator: # typename specified by 'extends'. This requires probing # the registry database, and imbeds knowledge of the # Vulkan extension enum scheme in this function. + # A 'alias' attribute contains the name of another enum + # which this is an alias of. The other enum must be + # declared first when emitting this enum. def enumToValue(self, elem, needsNum): name = elem.get('name') numVal = None @@ -302,8 +310,66 @@ class OutputGenerator: # More logic needed! self.logMsg('diag', 'Enum', name, '-> offset [', numVal, ',', value, ']') return [numVal, value] + if 'alias' in elem.keys(): + return [None, elem.get('alias')] return [None, None] # + # checkDuplicateEnums - sanity check for enumerated values + # enums - list of <enum> Elements + # returns the list with duplicates stripped + def checkDuplicateEnums(self, enums): + # Dictionaries indexed by name and numeric value. + # Entries are [ Element, numVal, strVal ] matching name or value + + nameMap = {} + valueMap = {} + + stripped = [] + for elem in enums: + name = elem.get('name') + (numVal, strVal) = self.enumToValue(elem, True) + + if name in nameMap: + # Duplicate name found; check values + (name2, numVal2, strVal2) = nameMap[name] + + # Duplicate enum values for the same name are benign. This + # happens when defining the same enum conditionally in + # several extension blocks. + if (strVal2 == strVal or (numVal != None and + numVal == numVal2)): + True + # self.logMsg('info', 'checkDuplicateEnums: Duplicate enum (' + name + + # ') found with the same value:' + strVal) + else: + self.logMsg('warn', 'checkDuplicateEnums: Duplicate enum (' + name + + ') found with different values:' + strVal + + ' and ' + strVal2) + + # Don't add the duplicate to the returned list + continue + elif numVal in valueMap: + # Duplicate value found (such as an alias); report it, but + # still add this enum to the list. + (name2, numVal2, strVal2) = valueMap[numVal] + + try: + self.logMsg('warn', 'Two enums found with the same value: ' + + name + ' = ' + name2.get('name') + ' = ' + strVal) + except: + pdb.set_trace() + + # Track this enum to detect followon duplicates + nameMap[name] = [ elem, numVal, strVal ] + if numVal != None: + valueMap[numVal] = [ elem, numVal, strVal ] + + # Add this enum to the list + stripped.append(elem) + + # Return the list + return stripped + # def makeDir(self, path): self.logMsg('diag', 'OutputGenerator::makeDir(' + path + ')') if not (path in self.madeDirs.keys()): @@ -345,15 +411,15 @@ class OutputGenerator: # <feature> tag def validateFeature(self, featureType, featureName): if (self.featureName == None): - raise UserWarning('Attempt to generate', featureType, name, - 'when not in feature') + raise UserWarning('Attempt to generate', featureType, + featureName, 'when not in feature') # # Type generation - def genType(self, typeinfo, name): + def genType(self, typeinfo, name, alias): self.validateFeature('type', name) # # Struct (e.g. C "struct" type) generation - def genStruct(self, typeinfo, name): + def genStruct(self, typeinfo, name, alias): self.validateFeature('struct', name) # The mixed-mode <member> tags may contain no-op <comment> tags. @@ -364,15 +430,15 @@ class OutputGenerator: member.remove(comment) # # Group (e.g. C "enum" type) generation - def genGroup(self, groupinfo, name): + def genGroup(self, groupinfo, name, alias): self.validateFeature('group', name) # # Enumerant (really, constant) generation - def genEnum(self, enuminfo, name): + def genEnum(self, enuminfo, name, alias): self.validateFeature('enum', name) # # Command generation - def genCmd(self, cmd, name): + def genCmd(self, cmd, name, alias): self.validateFeature('command', name) # # Utility functions - turn a <proto> <name> into C-language prototype @@ -429,9 +495,31 @@ class OutputGenerator: # required, False otherwise # elem - <enum> element to test def isEnumRequired(self, elem): - return (elem.get('extname') is None or - re.match(self.genOpts.addExtensions, elem.get('extname')) is not None or - self.genOpts.defaultExtensions == elem.get('supported')) + required = elem.get('required') != None + self.logMsg('diag', 'isEnumRequired:', elem.get('name'), + '->', required) + return required + + #@@@ This code is overridden by equivalent code now run in + #@@@ Registry.generateFeature + + required = False + + extname = elem.get('extname') + if extname is not None: + # 'supported' attribute was injected when the <enum> element was + # moved into the <enums> group in Registry.parseTree() + if self.genOpts.defaultExtensions == elem.get('supported'): + required = True + elif re.match(self.genOpts.addExtensions, extname) is not None: + required = True + elif elem.get('version') is not None: + required = re.match(self.genOpts.emitversions, elem.get('version')) is not None + else: + required = True + + return required + # # makeCDecls - return C prototype and function pointer typedef for a # command, as a two-element list of strings. |
