summaryrefslogtreecommitdiff
path: root/Tools/Python/buildgen/BuildConfig.py
blob: e91bd294a5d2fdcf57e15e4b6cafe860b349a5b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/env python

# Copyright (c) 2007, Intel Corporation
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

"""Tools and build configuration"""

from sets import Set

class Config(dict):
    def __init__(self, file):
        """file (target configuration file)"""
        configFile = open(file)
        while True:
            line = configFile.readline()
            if line == "": break    ## no more line

            line = line.strip()
            # skip blank line
            if line == "": continue
            # skip comment line
            if line[0] == '#': continue
            # skip invalid line
            if line[0] == '=':
                print "! invalid configuration:", line
                continue

            defStrings = line.split('=', 1)
            name = defStrings[0].strip()
            value = defStrings[1].strip()
            self[name] = value

        configFile.close()

    def __getitem__(self, attr):
        if attr not in self:
            return ""

        value = dict.__getitem__(self, attr)
        if value == None:
            value = ""
        return value

class ToolConfig(dict):
    def __init__(self, file):
        """file (tools configuration file path)"""
        self.Targets = Set()
        self.Toolchains = Set()
        self.Archs = Set()
        self.ToolCodes = Set()
        self.Families = Set()
        self.Attributes = Set(["FAMILY", "NAME", "PATH", "FLAGS", "EXT", "DPATH", "SPATH", "LIBPATH", "INCLUDEPATH"])
        
        configFile = open(file)
        while True:
            line = configFile.readline()
            if line == "": break

            line = line.strip()
            # skip blank line
            if line == "": continue
            # skip comment line
            if line[0] == '#': continue
            # skip invalid line
            if line[0] == '=':
                print "! invalid definition:", line
                continue

            # split the definition at the first "="
            tool_def = line.split('=', 1)
            name = tool_def[0].strip()
            value = tool_def[1].strip()
            
            # the name of a tool definition must have five parts concatenated by "_"
            keys = name.split('_')
            # skip non-definition line
            if len(keys) < 5: continue
        
            keys = (keys[1], keys[0], keys[2], keys[3], keys[4])
            self[keys] = value
            
            ###############################################
            ## statistics
            ###############################################
            if keys[0] != '*': self.Toolchains.add(keys[0])
            if keys[1] != '*': self.Targets.add(keys[1])
            if keys[2] != '*': self.Archs.add(keys[2])
            if keys[3] != '*': self.ToolCodes.add(keys[3])
            if keys[4] == "FAMILY": self.Families.add(value)
            elif keys[4] == '*': raise Exception("No * allowed in ATTRIBUTE field")

        configFile.close()
        # expand the "*" in each field
        self.expand()

    def __getitem__(self, attrs):
        if len(attrs) != 5:
            return ""
        
        if attrs not in self:
            return ""
        
        value = dict.__getitem__(self, attrs)
        if value == None:
            value = ""
        return value
    
    def expand(self):
        summary = {}
        toolchains = []
        targets = []
        archs = []
        toolcodes = []
        for key in self:
            value = self[key]
            if key[0] == '*':
                toolchains = self.Toolchains
            else:
                toolchains = [key[0]]

            for toolchain in toolchains:
                if key[1] == '*':
                    targets = self.Targets
                else:
                    targets = [key[1]]
                    
                for target in targets:
                    if key[2] == '*':
                        archs = self.Archs
                    else:
                        archs = [key[2]]
                        
                    for arch in archs:
                        if key[3] == '*':
                            toolcodes = self.ToolCodes
                        else:
                            toolcodes = [key[3]]
                            
                        for toolcode in toolcodes:
                            attribute = key[4]
                            summary[(toolchain, target, arch, toolcode, attribute)] = value
        self.clear()
        for toolchain in self.Toolchains:
            for target in self.Targets:
                for arch in self.Archs:
                    for toolcode in self.ToolCodes:
                        key = (toolchain, target, arch, toolcode, "NAME")
                        if key not in summary: continue
                        for attr in self.Attributes:
                            key = (toolchain, target, arch, toolcode, attr)
                            if key not in summary: continue
                            self[key] = summary[key]


    def __str__(self):
        s = ""
        for entry in self:
            s += entry[0] + "_" + entry[1] + "_" + entry[2] + "_" + entry[3] + "_" + entry[4]
            s += " = " + self[entry] + "\n"
        return s

class TargetConfig(Config):
    pass

## for test
if __name__ == "__main__":
    import os
    if "WORKSPACE" not in os.environ:
        raise "No WORKSPACE given"
    cfg = ToolConfig(os.path.join(os.environ["WORKSPACE"], "Tools", "Conf", "tools_def.txt"))
    tgt = TargetConfig(os.path.join(os.environ["WORKSPACE"], "Tools", "Conf", "target.txt"))

    for key in cfg:
        print key,"=",cfg[key]
    
    print
    for name in tgt:
        print name,"=",tgt[name]