28972318 |
1 | #!/usr/bin/env python\r |
2 | \r |
3 | # Copyright (c) 2007, Intel Corporation\r |
4 | # All rights reserved. This program and the accompanying materials\r |
5 | # are licensed and made available under the terms and conditions of the BSD License\r |
6 | # which accompanies this distribution. The full text of the license may be found at\r |
7 | # http://opensource.org/licenses/bsd-license.php\r |
8 | #\r |
9 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r |
10 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r |
11 | \r |
12 | """Tools and build configuration"""\r |
13 | \r |
14 | from sets import Set\r |
15 | \r |
16 | class Config(dict):\r |
17 | def __init__(self, file):\r |
18 | """file (target configuration file)"""\r |
19 | configFile = open(file)\r |
20 | while True:\r |
21 | line = configFile.readline()\r |
22 | if line == "": break ## no more line\r |
23 | \r |
24 | line = line.strip()\r |
25 | # skip blank line\r |
26 | if line == "": continue\r |
27 | # skip comment line\r |
28 | if line[0] == '#': continue\r |
29 | # skip invalid line\r |
30 | if line[0] == '=':\r |
31 | print "! invalid configuration:", line\r |
32 | continue\r |
33 | \r |
34 | defStrings = line.split('=', 1)\r |
35 | name = defStrings[0].strip()\r |
36 | value = defStrings[1].strip()\r |
37 | self[name] = value\r |
38 | \r |
39 | configFile.close()\r |
40 | \r |
41 | def __getitem__(self, attr):\r |
42 | if attr not in self:\r |
43 | return ""\r |
44 | \r |
45 | value = dict.__getitem__(self, attr)\r |
46 | if value == None:\r |
47 | value = ""\r |
48 | return value\r |
49 | \r |
50 | class ToolConfig(dict):\r |
51 | def __init__(self, file):\r |
52 | """file (tools configuration file path)"""\r |
53 | self.Targets = Set()\r |
54 | self.Toolchains = Set()\r |
55 | self.Archs = Set()\r |
56 | self.ToolCodes = Set()\r |
57 | self.Families = Set()\r |
58 | self.Attributes = Set(["FAMILY", "NAME", "PATH", "FLAGS", "EXT", "DPATH", "SPATH", "LIBPATH", "INCLUDEPATH"])\r |
59 | \r |
60 | configFile = open(file)\r |
61 | while True:\r |
62 | line = configFile.readline()\r |
63 | if line == "": break\r |
64 | \r |
65 | line = line.strip()\r |
66 | # skip blank line\r |
67 | if line == "": continue\r |
68 | # skip comment line\r |
69 | if line[0] == '#': continue\r |
70 | # skip invalid line\r |
71 | if line[0] == '=':\r |
72 | print "! invalid definition:", line\r |
73 | continue\r |
74 | \r |
75 | # split the definition at the first "="\r |
76 | tool_def = line.split('=', 1)\r |
77 | name = tool_def[0].strip()\r |
78 | value = tool_def[1].strip()\r |
79 | \r |
80 | # the name of a tool definition must have five parts concatenated by "_"\r |
81 | keys = name.split('_')\r |
82 | # skip non-definition line\r |
83 | if len(keys) < 5: continue\r |
84 | \r |
85 | keys = (keys[1], keys[0], keys[2], keys[3], keys[4])\r |
86 | self[keys] = value\r |
87 | \r |
88 | ###############################################\r |
89 | ## statistics\r |
90 | ###############################################\r |
91 | if keys[0] != '*': self.Toolchains.add(keys[0])\r |
92 | if keys[1] != '*': self.Targets.add(keys[1])\r |
93 | if keys[2] != '*': self.Archs.add(keys[2])\r |
94 | if keys[3] != '*': self.ToolCodes.add(keys[3])\r |
95 | if keys[4] == "FAMILY": self.Families.add(value)\r |
96 | elif keys[4] == '*': raise Exception("No * allowed in ATTRIBUTE field")\r |
97 | \r |
98 | configFile.close()\r |
99 | # expand the "*" in each field\r |
100 | self.expand()\r |
101 | \r |
102 | def __getitem__(self, attrs):\r |
103 | if len(attrs) != 5:\r |
104 | return ""\r |
105 | \r |
106 | if attrs not in self:\r |
107 | return ""\r |
108 | \r |
109 | value = dict.__getitem__(self, attrs)\r |
110 | if value == None:\r |
111 | value = ""\r |
112 | return value\r |
113 | \r |
114 | def expand(self):\r |
115 | summary = {}\r |
116 | toolchains = []\r |
117 | targets = []\r |
118 | archs = []\r |
119 | toolcodes = []\r |
120 | for key in self:\r |
121 | value = self[key]\r |
122 | if key[0] == '*':\r |
123 | toolchains = self.Toolchains\r |
124 | else:\r |
125 | toolchains = [key[0]]\r |
126 | \r |
127 | for toolchain in toolchains:\r |
128 | if key[1] == '*':\r |
129 | targets = self.Targets\r |
130 | else:\r |
131 | targets = [key[1]]\r |
132 | \r |
133 | for target in targets:\r |
134 | if key[2] == '*':\r |
135 | archs = self.Archs\r |
136 | else:\r |
137 | archs = [key[2]]\r |
138 | \r |
139 | for arch in archs:\r |
140 | if key[3] == '*':\r |
141 | toolcodes = self.ToolCodes\r |
142 | else:\r |
143 | toolcodes = [key[3]]\r |
144 | \r |
145 | for toolcode in toolcodes:\r |
146 | attribute = key[4]\r |
147 | summary[(toolchain, target, arch, toolcode, attribute)] = value\r |
148 | self.clear()\r |
149 | for toolchain in self.Toolchains:\r |
150 | for target in self.Targets:\r |
151 | for arch in self.Archs:\r |
152 | for toolcode in self.ToolCodes:\r |
153 | key = (toolchain, target, arch, toolcode, "NAME")\r |
154 | if key not in summary: continue\r |
155 | for attr in self.Attributes:\r |
156 | key = (toolchain, target, arch, toolcode, attr)\r |
157 | if key not in summary: continue\r |
158 | self[key] = summary[key]\r |
159 | \r |
160 | \r |
161 | def __str__(self):\r |
162 | s = ""\r |
163 | for entry in self:\r |
164 | s += entry[0] + "_" + entry[1] + "_" + entry[2] + "_" + entry[3] + "_" + entry[4]\r |
165 | s += " = " + self[entry] + "\n"\r |
166 | return s\r |
167 | \r |
168 | class TargetConfig(Config):\r |
169 | pass\r |
170 | \r |
171 | ## for test\r |
172 | if __name__ == "__main__":\r |
173 | import os\r |
174 | if "WORKSPACE" not in os.environ:\r |
175 | raise "No WORKSPACE given"\r |
176 | cfg = ToolConfig(os.path.join(os.environ["WORKSPACE"], "Tools", "Conf", "tools_def.txt"))\r |
177 | tgt = TargetConfig(os.path.join(os.environ["WORKSPACE"], "Tools", "Conf", "target.txt"))\r |
178 | \r |
179 | for key in cfg:\r |
180 | print key,"=",cfg[key]\r |
181 | \r |
182 | print\r |
183 | for name in tgt:\r |
184 | print name,"=",tgt[name]\r |
185 | |