1#!/usr/bin/python3 -i 2# 3# Copyright 2013-2021 The Khronos Group Inc. 4# 5# SPDX-License-Identifier: Apache-2.0 6 7from generator import OutputGenerator, enquote, write 8from scriptgenerator import ScriptOutputGenerator 9import pprint 10 11class PyOutputGenerator(ScriptOutputGenerator): 12 """PyOutputGenerator - subclass of ScriptOutputGenerator. 13 Generates Python data structures describing API names and 14 relationships.""" 15 16 def __init__(self, *args, **kwargs): 17 super().__init__(*args, **kwargs) 18 19 def beginDict(self, name): 20 """String starting definition of a named dictionary""" 21 return f'{name} = {{' 22 23 def endDict(self): 24 """ String ending definition of a named dictionary""" 25 return '}' 26 27 def writeDict(self, dict, name, printValues = True): 28 """Write dictionary as a Python dictionary with the given name. 29 If printValues is False, just output keys with None values.""" 30 31 write(self.beginDict(name), file=self.outFile) 32 for key in sorted(dict): 33 if printValues: 34 value = enquote(dict[key]) 35 else: 36 value = 'None' 37 write(f'{enquote(key)} : {value},', file=self.outFile) 38 write(self.endDict(), file=self.outFile) 39 40 def writeList(self, l, name): 41 """Write list l as a Ruby hash with the given name""" 42 43 self.writeDict(l, name, printValues = False) 44 45 def endFile(self): 46 # Creates the inverse mapping of nonexistent APIs to their aliases. 47 super().createInverseMap() 48 49 # Print out all the dictionaries as Python strings. 50 # Could just print(dict) but that's not human-readable 51 dicts = ( [ self.basetypes, 'basetypes' ], 52 [ self.consts, 'consts' ], 53 [ self.enums, 'enums' ], 54 [ self.flags, 'flags' ], 55 [ self.funcpointers, 'funcpointers' ], 56 [ self.protos, 'protos' ], 57 [ self.structs, 'structs' ], 58 [ self.handles, 'handles' ], 59 [ self.defines, 'defines' ], 60 [ self.typeCategory, 'typeCategory' ], 61 [ self.alias, 'alias' ], 62 [ self.nonexistent, 'nonexistent' ], 63 ) 64 65 for (dict, name) in dicts: 66 self.writeDict(dict, name) 67 68 # Dictionary containing the relationships of a type 69 # (e.g. a dictionary with each related type as keys). 70 # Could just print(self.mapDict), but prefer something 71 # human-readable and stable-ordered 72 write(self.beginDict('mapDict'), file=self.outFile) 73 for baseType in sorted(self.mapDict.keys()): 74 write('{} : {},'.format(enquote(baseType), 75 pprint.pformat(self.mapDict[baseType])), file=self.outFile) 76 write(self.endDict(), file=self.outFile) 77 78 # List of included feature names 79 self.writeList(sorted(self.features), 'features') 80 81 # Generate feature <-> interface mappings 82 for feature in self.features: 83 self.mapInterfaces(feature) 84 85 # Write out the reverse map from APIs to requiring features 86 write(self.beginDict('requiredBy'), file=self.outFile) 87 for api in sorted(self.apimap): 88 # Sort requirements by first feature in each one 89 deps = sorted(self.apimap[api], key = lambda dep: dep[0]) 90 reqs = ', '.join('({}, {})'.format(enquote(dep[0]), enquote(dep[1])) for dep in deps) 91 write('{} : [{}],'.format(enquote(api), reqs), file=self.outFile) 92 write(self.endDict(), file=self.outFile) 93 94 super().endFile() 95