]>
Commit | Line | Data |
---|---|---|
d2059d05 | 1 | /** @file\r |
2 | ToolChainMap class\r | |
3 | \r | |
4 | ToolChainMap class is used for storing tool chain configurations.\r | |
a29c47e0 | 5 | \r |
6 | Copyright (c) 2006, Intel Corporation\r | |
7 | All rights reserved. This program and the accompanying materials\r | |
8 | are licensed and made available under the terms and conditions of the BSD License\r | |
9 | which accompanies this distribution. The full text of the license may be found at\r | |
10 | http://opensource.org/licenses/bsd-license.php\r | |
11 | \r | |
12 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
13 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
14 | \r | |
d2059d05 | 15 | **/\r |
a29c47e0 | 16 | \r |
17 | package org.tianocore.build.toolchain;\r | |
18 | \r | |
19 | import java.util.HashMap;\r | |
20 | import java.util.Map;\r | |
21 | import java.util.Set;\r | |
22 | \r | |
d2059d05 | 23 | /**\r |
24 | ToolChainMap is a wrapper class for a generic Map class which uses ToolChainKey\r | |
25 | class as its key. It's used to store and retrieve tool chain configuration \r | |
26 | information.\r | |
27 | **/\r | |
a29c47e0 | 28 | public class ToolChainMap {\r |
d2059d05 | 29 | //\r |
30 | // From which part of key can be used to match "*"\r | |
31 | // \r | |
8c84e1b1 | 32 | private int matchLevel = ToolChainKey.keyLength - 1;\r |
a29c47e0 | 33 | \r |
d2059d05 | 34 | //\r |
35 | // A Map object in which tool chain configuration information will be stored\r | |
36 | // \r | |
a29c47e0 | 37 | private Map<ToolChainKey, String> map = null;\r |
38 | \r | |
d2059d05 | 39 | /**\r |
40 | Public constructor. It just initializes the private Map object.\r | |
41 | **/\r | |
a29c47e0 | 42 | public ToolChainMap() {\r |
a29c47e0 | 43 | this.map = new HashMap<ToolChainKey, String>();\r |
44 | }\r | |
45 | \r | |
d2059d05 | 46 | /**\r |
47 | Wrapper function for Map.put(). It's used when default delimiter of\r | |
48 | ToolChainKey is not wanted and will be overrided by "delimiter" parameter.\r | |
49 | \r | |
50 | @param key Key string which is concatenated with "delimiter"\r | |
51 | @param delimiter The delimiter string in the key string\r | |
52 | @param value Value string associated with the "key"\r | |
53 | \r | |
54 | @retval String The "value" string if the "key" is valid.\r | |
55 | @retval null if the "key" is invalid\r | |
56 | **/\r | |
c773bec0 | 57 | public String put(String key, String delimiter, String value) {\r |
a29c47e0 | 58 | ToolChainKey toolChainKey;\r |
59 | \r | |
60 | try {\r | |
61 | toolChainKey = new ToolChainKey(key, delimiter);\r | |
62 | } catch (Exception e) {\r | |
c773bec0 | 63 | return null;\r |
a29c47e0 | 64 | }\r |
65 | return (String)map.put(toolChainKey, value);\r | |
66 | }\r | |
67 | \r | |
d2059d05 | 68 | /**\r |
69 | Wrapper function for Map.put().\r | |
70 | \r | |
71 | @param key Key string which is concatenated with default "delimiter"\r | |
72 | @param value Value string associated with the "key"\r | |
73 | \r | |
74 | @retval String The "value" string if the "key" is valid.\r | |
75 | @retval null if the "key" is invalid\r | |
76 | **/\r | |
c773bec0 | 77 | public String put(String key, String value) {\r |
a29c47e0 | 78 | ToolChainKey toolChainKey;\r |
79 | \r | |
80 | try {\r | |
81 | toolChainKey = new ToolChainKey(key);\r | |
82 | } catch (Exception e) {\r | |
c773bec0 | 83 | return null;\r |
a29c47e0 | 84 | }\r |
85 | return (String)map.put(toolChainKey, value);\r | |
86 | }\r | |
87 | \r | |
d2059d05 | 88 | /**\r |
89 | Wrapper function for Map.put(). The key is given in the form of string\r | |
90 | array.\r | |
91 | \r | |
92 | @param key Key string array\r | |
93 | @param value Value string associated with the "key"\r | |
94 | \r | |
95 | @retval String The "value" string if the "key" is valid.\r | |
96 | @retval null if the "key" is invalid\r | |
97 | **/\r | |
c773bec0 | 98 | public String put(String[] key, String value) {\r |
a29c47e0 | 99 | ToolChainKey toolChainKey;\r |
100 | \r | |
101 | try {\r | |
102 | toolChainKey = new ToolChainKey(key);\r | |
103 | } catch (Exception e) {\r | |
c773bec0 | 104 | return null;\r |
a29c47e0 | 105 | }\r |
106 | return (String)map.put(toolChainKey, value);\r | |
107 | }\r | |
108 | \r | |
d2059d05 | 109 | /**\r |
110 | Wrapper function for Map.put(). The key is given in ToolChainKey class.\r | |
111 | \r | |
112 | @param key ToolChainKey class\r | |
113 | @param value Value string associated with the "key"\r | |
114 | \r | |
115 | @retval String The "value" string if the "key" is valid.\r | |
116 | @retval null if the "key" is invalid\r | |
117 | **/\r | |
a29c47e0 | 118 | public String put(ToolChainKey key, String value) {\r |
119 | return (String)map.put(key, value);\r | |
120 | }\r | |
121 | \r | |
d2059d05 | 122 | /**\r |
123 | Wrapper function for Map.get().\r | |
124 | \r | |
125 | @param key Key string which is concatenated with default "delimiter"\r | |
126 | \r | |
127 | @return String\r | |
128 | **/\r | |
c773bec0 | 129 | public String get(String key) {\r |
a29c47e0 | 130 | ToolChainKey toolChainKey;\r |
131 | \r | |
132 | try {\r | |
133 | toolChainKey = new ToolChainKey(key);\r | |
134 | } catch (Exception e) {\r | |
c773bec0 | 135 | return null;\r |
a29c47e0 | 136 | }\r |
137 | return get(toolChainKey);\r | |
138 | }\r | |
139 | \r | |
d2059d05 | 140 | /**\r |
141 | Wrapper function for Map.get(). It's used when default delimiter of\r | |
142 | ToolChainKey is not wanted and will be overrided by "delimiter" parameter.\r | |
143 | \r | |
144 | @param key Key string which is concatenated with "delimiter"\r | |
145 | @param delimiter The delimiter string in the key string\r | |
146 | \r | |
147 | @return String\r | |
148 | **/\r | |
c773bec0 | 149 | public String get(String key, String delimiter) {\r |
a29c47e0 | 150 | ToolChainKey toolChainKey;\r |
151 | \r | |
152 | try {\r | |
153 | toolChainKey = new ToolChainKey(key, delimiter);\r | |
154 | } catch (Exception e) {\r | |
c773bec0 | 155 | return null;\r |
a29c47e0 | 156 | }\r |
157 | return get(toolChainKey);\r | |
158 | }\r | |
159 | \r | |
d2059d05 | 160 | /**\r |
161 | Wrapper function for Map.get(). The key is given in the form of string\r | |
162 | array.\r | |
163 | \r | |
164 | @param key Key string array\r | |
165 | \r | |
166 | @return String\r | |
167 | **/\r | |
c773bec0 | 168 | public String get(String[] key) {\r |
a29c47e0 | 169 | ToolChainKey toolChainKey;\r |
170 | \r | |
171 | try {\r | |
172 | toolChainKey = new ToolChainKey(key);\r | |
173 | } catch (Exception e) {\r | |
c773bec0 | 174 | return null;\r |
a29c47e0 | 175 | }\r |
176 | return get(toolChainKey);\r | |
177 | }\r | |
178 | \r | |
d2059d05 | 179 | /**\r |
180 | Wrapper function for Map.get(). The key is given in ToolChainKey class.\r | |
181 | All other form of get() method will eventually call this form of get. It\r | |
182 | will do real job of finding the value associated with the given key. Most\r | |
183 | of the job is to try to match the key with "wildcard".\r | |
184 | \r | |
185 | @param key ToolChainKey class\r | |
186 | \r | |
187 | @return String The value associated with the key\r | |
188 | **/\r | |
c773bec0 | 189 | public String get(ToolChainKey key) {\r |
d2059d05 | 190 | ///\r |
191 | /// First, we'll try to get the value through the exact given key\r | |
192 | /// \r | |
a29c47e0 | 193 | String result = map.get(key);\r |
194 | if (result != null || map.containsKey(key)) {\r | |
195 | return result;\r | |
196 | }\r | |
197 | \r | |
d2059d05 | 198 | ///\r |
199 | /// If nothing is found, then, we'll try all possible keys combined with\r | |
200 | /// wildcard "*". In order not to change the original key value, we have\r | |
201 | /// to clone one for later use. \r | |
202 | /// \r | |
a29c47e0 | 203 | String[] keySet = key.getKeySet();\r |
204 | ToolChainKey tmpKey;\r | |
205 | try {\r | |
206 | tmpKey = new ToolChainKey(keySet);\r | |
207 | } catch (Exception e) {\r | |
c773bec0 | 208 | return null;\r |
a29c47e0 | 209 | }\r |
210 | \r | |
d2059d05 | 211 | ///\r |
212 | /// In the current tool chain definition format (in name/value pair), \r | |
213 | /// there're five parts in the "name". The last part of the "name" must\r | |
8c84e1b1 | 214 | /// not be "wildcard". We should start combining "*" from left to right.\r |
d2059d05 | 215 | /// We'll try all the possible combinations until the value can be fetched.\r |
216 | /// \r | |
217 | /// The following code implements the logic which will try to use, for example,\r | |
218 | /// following key parts combinations sequentially to get the value.\r | |
219 | /// \r | |
220 | /// TARGET_TOOLCHAIN_ARCH_TOOLCODE_ATTRIBUTE\r | |
8c84e1b1 | 221 | /// ******_TOOLCHAIN_ARCH_TOOLCODE_ATTRIBUTE\r |
222 | /// TARGET_*********_ARCH_TOOLCODE_ATTRIBUTE\r | |
223 | /// ******_*********_ARCH_TOOLCODE_ATTRIBUTE\r | |
224 | /// TARGET_TOOLCHAIN_****_TOOLCODE_ATTRIBUTE\r | |
225 | /// ******_TOOLCHAIN_****_TOOLCODE_ATTRIBUTE\r | |
226 | /// TARGET_*********_****_TOOLCODE_ATTRIBUTE\r | |
227 | /// ******_*********_****_TOOLCODE_ATTRIBUTE\r | |
228 | /// TARGET_TOOLCHAIN_ARCH_********_ATTRIBUTE\r | |
229 | /// ******_TOOLCHAIN_ARCH_********_ATTRIBUTE\r | |
230 | /// TARGET_*********_ARCH_********_ATTRIBUTE\r | |
231 | /// ******_*********_ARCH_********_ATTRIBUTE\r | |
232 | /// TARGET_TOOLCHAIN_****_********_ATTRIBUTE\r | |
233 | /// ******_TOOLCHAIN_****_********_ATTRIBUTE\r | |
234 | /// TARGET_*********_****_********_ATTRIBUTE\r | |
235 | /// ******_*********_****_********_ATTRIBUTE\r | |
d2059d05 | 236 | /// \r |
237 | \r | |
238 | //\r | |
8c84e1b1 | 239 | // The wildcard "*" appears regularly (2^n). "*" in TARGET appears 2^0 \r |
240 | // times at every 2^0 TARGET, "*" in TOOLCHAIN appears 2^1 times at \r | |
241 | // every 2^1 TOOLCHAIN, and "*" in TOOLCODE appears 2^3 times at every \r | |
242 | // 2^3 TOOLCODE. We're going to use this to form all the combinations of key.\r | |
d2059d05 | 243 | // \r |
8c84e1b1 | 244 | int[] combinations = new int[matchLevel];\r |
245 | for (int i = 0; i < matchLevel; ++i) {\r | |
d2059d05 | 246 | //\r |
8c84e1b1 | 247 | // initialize the array with 2^n\r |
d2059d05 | 248 | // \r |
8c84e1b1 | 249 | combinations[i] = 1 << (i + 1);\r |
250 | }\r | |
251 | \r | |
252 | //\r | |
253 | // when last part goes down to zero, we tried all combinations of key\r | |
254 | // \r | |
255 | int lastIndex = matchLevel - 1;\r | |
256 | while (combinations[lastIndex] > 0) {\r | |
257 | //\r | |
258 | // form the key which has "*" in it\r | |
259 | // \r | |
260 | for (int i = 0; i < matchLevel; ++i) {\r | |
261 | //\r | |
262 | // start again if not finished\r | |
263 | // \r | |
264 | if (combinations[i] == 0) {\r | |
265 | combinations[i] = 1 << (i + 1);\r | |
266 | }\r | |
267 | \r | |
268 | //\r | |
269 | // half of 2^n is "*", the rest is non-*\r | |
270 | // \r | |
a29c47e0 | 271 | try {\r |
8c84e1b1 | 272 | if (combinations[i] > (1 << i)) {\r |
273 | tmpKey.setKey(keySet[i], i);\r | |
a29c47e0 | 274 | } else {\r |
8c84e1b1 | 275 | tmpKey.setKey("*", i);\r |
a29c47e0 | 276 | }\r |
277 | } catch (Exception e) {\r | |
c773bec0 | 278 | return null;\r |
a29c47e0 | 279 | }\r |
280 | \r | |
8c84e1b1 | 281 | combinations[i] -= 1;\r |
282 | }\r | |
283 | \r | |
284 | //\r | |
285 | // Try get the value from the map\r | |
286 | // \r | |
287 | result = map.get(tmpKey);\r | |
288 | if (result != null) {\r | |
d2059d05 | 289 | //\r |
8c84e1b1 | 290 | // The map actually has no exact key as the given "key", \r |
291 | // putting it back into map can speed up the get() next time\r | |
d2059d05 | 292 | // \r |
8c84e1b1 | 293 | map.put(key, result);\r |
294 | return result;\r | |
a29c47e0 | 295 | }\r |
a29c47e0 | 296 | }\r |
297 | \r | |
d2059d05 | 298 | //\r |
299 | // The map actually has no exact key as the given "key", putting it back\r | |
300 | // into map can speed up the get() next time even we got nothing.\r | |
301 | // \r | |
8c84e1b1 | 302 | map.put(key, null);\r |
303 | return null;\r | |
a29c47e0 | 304 | }\r |
305 | \r | |
d2059d05 | 306 | /**\r |
307 | Wrapper function for Map.size().\r | |
308 | \r | |
309 | @return int The size of map\r | |
310 | **/\r | |
a29c47e0 | 311 | public int size() {\r |
312 | return map.size();\r | |
313 | }\r | |
314 | \r | |
d2059d05 | 315 | /**\r |
316 | Wrapper function for Map.keySet().\r | |
317 | \r | |
318 | @return Set<ToolChainKey> A set of ToolChainKey objects\r | |
319 | */\r | |
a29c47e0 | 320 | public Set<ToolChainKey> keySet() {\r |
321 | return (Set<ToolChainKey>)map.keySet();\r | |
322 | }\r | |
b69bb9ba | 323 | \r |
324 | public String toString() {\r | |
325 | return map + "";\r | |
326 | }\r | |
a29c47e0 | 327 | }\r |
328 | \r |