• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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