]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/global/GlobalData.java
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@671 6f19259b...
[mirror_edk2.git] / Tools / Source / FrameworkWizard / src / org / tianocore / frameworkwizard / platform / ui / global / GlobalData.java
CommitLineData
a13899c5 1/** @file\r
2 GlobalData class. \r
3 \r
4 GlobalData provide initializing, instoring, querying and update global data.\r
5 It is a bridge to intercommunicate between multiple component, such as AutoGen,\r
6 PCD and so on. \r
7 \r
8Copyright (c) 2006, Intel Corporation\r
9All rights reserved. This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13\r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16**/\r
17package org.tianocore.frameworkwizard.platform.ui.global;\r
18\r
19import org.apache.xmlbeans.XmlObject;\r
20import org.tianocore.DbPathAndFilename;\r
21import org.tianocore.FrameworkDatabaseDocument;\r
22import org.tianocore.ModuleSurfaceAreaDocument;\r
23import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;\r
24import org.tianocore.frameworkwizard.platform.ui.id.FpdModuleIdentification;\r
25import org.tianocore.frameworkwizard.platform.ui.id.ModuleIdentification;\r
26import org.tianocore.frameworkwizard.platform.ui.id.PackageIdentification;\r
27import org.tianocore.frameworkwizard.platform.ui.id.PlatformIdentification;\r
28\r
29import java.io.File;\r
30import java.util.Comparator;\r
31import java.util.HashMap;\r
32import java.util.HashSet;\r
33import java.util.Iterator;\r
34import java.util.LinkedHashSet;\r
35import java.util.List;\r
36import java.util.Map;\r
37import java.util.Set;\r
38import java.util.Stack;\r
39import java.util.TreeMap;\r
40import java.util.TreeSet;\r
41import java.util.logging.Logger;\r
42import java.util.regex.Matcher;\r
43import java.util.regex.Pattern;\r
44\r
45/**\r
46 GlobalData provide initializing, instoring, querying and update global data.\r
47 It is a bridge to intercommunicate between multiple component, such as AutoGen,\r
48 PCD and so on. \r
49 \r
50 <p>Note that all global information are initialized incrementally. All data will \r
51 parse and record only of necessary during build time. </p>\r
52 \r
53 @since GenBuild 1.0\r
54**/\r
55public class GlobalData {\r
56\r
57\r
58 public static Logger log = Logger.getAnonymousLogger();\r
59 public static KeyComparator comparator = new KeyComparator();\r
60 ///\r
61 /// Record current WORKSPACE Directory\r
62 ///\r
63 private static String workspaceDir = "";\r
64 \r
65 ///\r
66 /// Be used to ensure Global data will be initialized only once.\r
67 ///\r
68 private static boolean globalFlag = false;\r
69 \r
70 ///\r
71 /// Framework Database information: package list and platform list\r
72 ///\r
73 private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>(); \r
74\r
75 private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();\r
76\r
77 ///\r
78 /// Every detail SPD informations: Module list, Library class definition,\r
79 /// Package header file, GUID/PPI/Protocol definitions\r
80 ///\r
81 private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();\r
82\r
83 ///\r
84 /// Build informations are divided into three parts:\r
85 /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA\r
86 ///\r
87 private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();\r
88\r
89 private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();\r
90\r
91 private static XmlObject fpdBuildOptions;\r
92\r
93 private static XmlObject fpdDynamicPcds;\r
94 \r
95 ///\r
96 /// Parsed modules list\r
97 ///\r
98 private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();\r
99 \r
100 ///\r
101 /// built modules list with ARCH, TARGET, TOOLCHAIN\r
102 ///\r
103 private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();\r
104 \r
105 ///\r
106 /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.\r
107 ///\r
108// private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();\r
109\r
110 ///\r
111 /// build target + tool chain family/tag name + arch + command types + command options\r
112 ///\r
113 private static Map<String, Object> toolChainOptions;\r
114 private static Map<String, Object> toolChainFamilyOptions;\r
115 private static Map<String, String> toolChainDefinitions;\r
116 private static Map<FpdModuleIdentification, Map<String, Object>> moduleToolChainOptions = new HashMap<FpdModuleIdentification, Map<String, Object>>();;\r
117 private static Map<FpdModuleIdentification, Map<String, Object>> moduleToolChainFamilyOptions = new HashMap<FpdModuleIdentification, Map<String, Object>>();;\r
118 ///\r
119 ///\r
120 ///\r
121 private static Set<String> targets;\r
122 ///\r
123 ///\r
124 ///\r
125 private static Set<String> toolChainFamilies;\r
126 ///\r
127 ///\r
128 ///\r
129 private static Set<String> toolChains;\r
130 ///\r
131 /// keep track which toolchain family a toolchain tag belongs to\r
132 ///\r
133 private static Map<String, Set<String>> toolChainFamilyMap;\r
134 private static Map<String, Set<String>> toolChainCommandMap;\r
135 \r
136 ///\r
137 /// list of Arch: EBC, ARM, IA32, X64, IPF, PPC\r
138 ///\r
139 private static Set<String> archs;\r
140\r
141 ///\r
142 /// list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK, PP\r
143 ///\r
144 private static Set<String> commandTypes;\r
145 \r
146 /**\r
147 Parse framework database (DB) and all SPD files listed in DB to initialize\r
148 the environment for next build. This method will only be executed only once\r
149 in the whole build process. \r
150 \r
151 @param workspaceDatabaseFile the file name of framework database\r
152 @param workspaceDir current workspace directory path\r
153 @throws Exception\r
154 Framework Dababase or SPD or MSA file is not valid\r
155 **/\r
156 public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws Exception {\r
157 //\r
158 // ensure this method will be revoked only once\r
159 //\r
160 if (globalFlag) {\r
161 return;\r
162 }\r
163 globalFlag = true;\r
164 \r
165 //\r
166 // Backup workspace directory. It will be used by other method\r
167 //\r
168 GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");\r
169 File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);\r
170 try {\r
171 FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);\r
172 //\r
173 // validate FrameworkDatabaseFile\r
174 //\r
175// if (! db.validate()) {\r
176// throw new Exception("Framework Database file [" + dbFile.getPath() + "] is invalid.");\r
177// }\r
178 //\r
179 // Get package list\r
180 //\r
181 List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();\r
182 \r
183 Iterator iter = packages.iterator();\r
184 while (iter.hasNext()) {\r
185 DbPathAndFilename dbPath = (DbPathAndFilename)iter.next();\r
186 String fileName = dbPath.getStringValue();\r
187 Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));\r
188 packageList.add(spd.getPackageId());\r
189 spdTable.put(spd.getPackageId(), spd);\r
190 }\r
191\r
192 \r
193 } catch (Exception e) {\r
194 e.printStackTrace();\r
195 throw new Exception("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());\r
196 }\r
197 }\r
198 \r
199 /**\r
200 Get the current WORKSPACE Directory. \r
201 \r
202 @return current workspace directory\r
203 **/\r
204 public synchronized static String getWorkspacePath() {\r
205 return workspaceDir;\r
206 }\r
207\r
208\r
209 /**\r
210 Get the MSA file name with absolute path\r
211 */\r
212 public synchronized static File getMsaFile(ModuleIdentification moduleId) throws Exception {\r
213 File msaFile = null;\r
214 //\r
215 // TBD. Do only when package is null. \r
216 //\r
217 Iterator iter = packageList.iterator();\r
218 while (iter.hasNext()) {\r
219 PackageIdentification packageId = (PackageIdentification)iter.next();\r
220 Spd spd = spdTable.get(packageId);\r
221 msaFile = spd.getModuleFile(moduleId);\r
222 if (msaFile != null ) {\r
223 break ;\r
224 }\r
225 }\r
226 if (msaFile == null){\r
227 throw new Exception("Can't find Module [" + moduleId.getName() + "] in all packages. ");\r
228 }\r
229 else {\r
230 return msaFile;\r
231 }\r
232 }\r
233\r
234 public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) {\r
235 //\r
236 // If package already defined in module\r
237 //\r
238 if (moduleId.getPackage() != null) {\r
239 return moduleId.getPackage();\r
240 }\r
241 \r
242 PackageIdentification packageId = null;\r
243 Iterator iter = packageList.iterator();\r
244 while (iter.hasNext()) {\r
245 packageId = (PackageIdentification)iter.next();\r
246 \r
247 Spd spd = spdTable.get(packageId);\r
248 if (spd.getModuleFile(moduleId) != null ) {\r
249 moduleId.setPackage(packageId);\r
250 break ;\r
251 }\r
252 }\r
253 if (packageId == null){\r
254 return null;\r
255 }\r
256 else {\r
257 return packageId;\r
258 }\r
259 }\r
260 \r
261 /**\r
262 Difference between build and parse: ToolChain and Target\r
263 **/\r
264 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {\r
265 return builtModules.contains(moduleId);\r
266 }\r
267 \r
268 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {\r
269 builtModules.add(fpdModuleId);\r
270 }\r
271\r
272 \r
273 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws Exception{\r
274 Map<String, XmlObject> result = new HashMap<String, XmlObject>();\r
275 Set keySet = doc.keySet();\r
276 Iterator iter = keySet.iterator();\r
277 while (iter.hasNext()){\r
278 String key = (String)iter.next();\r
279 XmlObject item = cloneXmlObject(doc.get(key), true);\r
280 result.put(key, item);\r
281 }\r
282 fpdModuleSA.put(fpdModuleId, result);\r
283 }\r
284 \r
285 /**\r
286 Query overrided module surface area information. If current is Package\r
287 or Platform build, also include the information from FPD file. \r
288 \r
289 <p>Note that surface area parsing is incremental. That means the method will \r
290 only parse the MSA and MBD files if necessary. </p>\r
291 \r
292 @param moduleName the base name of the module\r
293 @return the overrided module surface area information\r
294 @throws Exception\r
295 MSA or MBD is not valid\r
296 **/\r
297 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws Exception {\r
298 if (parsedModules.containsKey(fpdModuleId)) {\r
299 return parsedModules.get(fpdModuleId);\r
300 }\r
301 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();\r
302 ModuleIdentification moduleId = fpdModuleId.getModule();\r
303 //\r
304 // First part: get the MSA files info\r
305 //\r
306 doc = getNativeMsa(moduleId);\r
307 \r
308 //\r
309 // Second part: put build options\r
310 //\r
311 doc.put("BuildOptions", fpdBuildOptions);\r
312 \r
313 //\r
314 // Third part: get Module info from FPD, such as Library instances, PCDs\r
315 //\r
316 if (fpdModuleSA.containsKey(fpdModuleId)){\r
317 //\r
318 // merge module info in FPD to final Doc\r
319 // For Library Module, do nothing here\r
320 //\r
321 doc.putAll(fpdModuleSA.get(fpdModuleId));\r
322 }\r
323 parsedModules.put(fpdModuleId, doc);\r
324 return doc;\r
325 }\r
326\r
327 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws Exception {\r
328 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);\r
329 return getDoc(fpdModuleId);\r
330 }\r
331 /**\r
332 Query the native MSA information with module base name. \r
333 \r
334 <p>Note that MSA parsing is incremental. That means the method will \r
335 only to parse the MSA files when never parsed before. </p>\r
336 \r
337 @param moduleName the base name of the module\r
338 @return the native MSA information\r
339 @throws Exception\r
340 MSA file is not valid\r
341 **/\r
342 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws Exception {\r
343 if (nativeMsa.containsKey(moduleId)) {\r
344 return nativeMsa.get(moduleId);\r
345 }\r
346 File msaFile = getMsaFile(moduleId);\r
347 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);\r
348 nativeMsa.put(moduleId, msaMap);\r
349 return msaMap;\r
350 }\r
351 \r
352 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws Exception {\r
353 if (! msaFile.exists()) {\r
354 throw new Exception("Surface Area file [" + msaFile.getPath() + "] can't found.");\r
355 }\r
356 try {\r
357 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);\r
358 //\r
359 // Validate File if they accord with XML Schema\r
360 //\r
361// if ( ! doc.validate()){\r
362// throw new Exception("Module Surface Area file [" + msaFile.getPath() + "] is invalid.");\r
363// }\r
364 //\r
365 // parse MSA file\r
366 //\r
367 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();\r
368 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();\r
369 msaMap.put("ModuleSurfaceArea", msa);\r
370 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));\r
371 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));\r
372 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));\r
373 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));\r
374 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));\r
375 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));\r
376 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));\r
377 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));\r
378 return msaMap;\r
379 }\r
380 catch (Exception ex){\r
381 throw new Exception(ex.getMessage());\r
382 }\r
383 }\r
384 \r
385 public static Map<String, XmlObject> getFpdBuildOptions() {\r
386 Map<String, XmlObject> map = new HashMap<String, XmlObject>();\r
387 map.put("BuildOptions", fpdBuildOptions);\r
388 return map;\r
389 }\r
390 \r
391 public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws Exception{\r
392 GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);\r
393 }\r
394\r
395 public static XmlObject getFpdDynamicPcds() {\r
396 return fpdDynamicPcds;\r
397 }\r
398\r
399 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {\r
400 GlobalData.fpdDynamicPcds = fpdDynamicPcds;\r
401 }\r
402\r
403 //////////////////////////////////////////////\r
404 //////////////////////////////////////////////\r
405 \r
406 public static Set<ModuleIdentification> getModules(PackageIdentification packageId){\r
407 Spd spd = spdTable.get(packageId);\r
408 if (spd == null ) {\r
409 Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();\r
410 return dummy;\r
411 }\r
412 else {\r
413 return spd.getModules();\r
414 }\r
415 }\r
416\r
417 /**\r
418 The header file path is relative to workspace dir\r
419 **/\r
420 public static String[] getLibraryClassHeaderFiles(PackageIdentification[] packages, String name) {\r
421 if (packages == null ){\r
422 // throw Exception or not????\r
423 return new String[0];\r
424 }\r
425 String[] result = null;\r
426 for (int i = 0; i < packages.length; i++){\r
427 Spd spd = spdTable.get(packages[i]);\r
428 //\r
429 // If find one package defined the library class\r
430 //\r
431 if( (result = spd.getLibClassIncluder(name)) != null){\r
432 return result;\r
433 } \r
434 }\r
435 return null;\r
436 \r
437 }\r
438 \r
439 /**\r
440 The header file path is relative to workspace dir\r
441 **/ \r
442 public static String getPackageHeaderFiles(PackageIdentification packages, String moduleType) throws Exception {\r
443 if (packages == null ){\r
444 return new String("");\r
445 }\r
446 Spd spd = spdTable.get(packages);\r
447 //\r
448 // If can't find package header file, skip it\r
449 //\r
450 String temp = null;\r
451 if (spd != null){\r
452 if( (temp = spd.getPackageIncluder(moduleType)) != null){\r
453 return temp;\r
454 }else {\r
455 temp = "";\r
456 return temp;\r
457 }\r
458 }else {\r
459 return null;\r
460 }\r
461 } \r
462 \r
463 /**\r
464 return two values: {cName, GuidValue}\r
465 **/\r
466 public static String[] getGuid(PackageIdentification[] packages, String name) throws Exception {\r
467 if (packages == null ){\r
468 // throw Exception or not????\r
469 return new String[0];\r
470 }\r
471 String[] result = null;\r
472 for (int i = 0; i < packages.length; i++){\r
473 Spd spd = spdTable.get(packages[i]);\r
474 //\r
475 // If find one package defined the GUID\r
476 //\r
477 if( (result = spd.getGuid(name)) != null){\r
478 return result;\r
479 }\r
480 }\r
481 return null;\r
482 }\r
483 \r
484 /**\r
485 return two values: {cName, GuidValue}\r
486 **/ \r
487 public static String[] getPpiGuid(PackageIdentification[] packages, String name) throws Exception {\r
488 if (packages == null ){\r
489 return new String[0];\r
490 }\r
491 String[] result = null;\r
492 for (int i = 0; i < packages.length; i++){\r
493 Spd spd = spdTable.get(packages[i]);\r
494 //\r
495 // If find one package defined the Ppi GUID\r
496 //\r
497 if( (result = spd.getPpi(name)) != null){\r
498 return result;\r
499 }\r
500 }\r
501 return null;\r
502 \r
503 }\r
504 \r
505 /**\r
506 return two values: {cName, GuidValue}\r
507 **/ \r
508 public static String[] getProtocolGuid(PackageIdentification[] packages, String name) throws Exception {\r
509 if (packages == null ){\r
510 return new String[0];\r
511 }\r
512 String[] result = null;\r
513 for (int i = 0; i < packages.length; i++){\r
514 Spd spd = spdTable.get(packages[i]);\r
515 //\r
516 // If find one package defined the protocol GUID\r
517 //\r
518 if( (result = spd.getProtocol(name)) != null){\r
519 return result;\r
520 }\r
521 }\r
522 return null;\r
523 \r
524 }\r
525 \r
526 /////////////////////////// Update!! Update!! Update!!\r
527// public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {\r
528// return pcdDbManager;\r
529// }\r
530 ///////////////////////////\r
531 public synchronized static PlatformIdentification getPlatform(String name) throws Exception {\r
532 Iterator iter = platformList.iterator();\r
533 while(iter.hasNext()){\r
534 PlatformIdentification platformId = (PlatformIdentification)iter.next();\r
535 if (platformId.getName().equalsIgnoreCase(name)) {\r
536 GlobalData.log.info("Platform: " + platformId + platformId.getFpdFile());\r
537 return platformId;\r
538 }\r
539 }\r
540 throw new Exception("Can't find platform [" + name + "] in current workspace. ");\r
541 }\r
542 \r
543 public synchronized static File getPackageFile(PackageIdentification packageId) throws Exception {\r
544 Iterator iter = packageList.iterator();\r
545 while(iter.hasNext()){\r
546 PackageIdentification packageItem = (PackageIdentification)iter.next();\r
547 if (packageItem.equals(packageId)) {\r
548 packageId.setName(packageItem.getName());\r
549 return packageItem.getSpdFile();\r
550 }\r
551 }\r
552 throw new Exception("Can't find " + packageId + " in current workspace. ");\r
553 }\r
554 \r
555 public synchronized static File getModuleFile(ModuleIdentification moduleId) throws Exception {\r
556 PackageIdentification packageId = getPackageForModule(moduleId);\r
557 moduleId.setPackage(packageId);\r
558 Spd spd = spdTable.get(packageId);\r
559 return spd.getModuleFile(moduleId);\r
560 }\r
561 //\r
562 // expanded by FrameworkWizard\r
563 //\r
564 public synchronized static XmlObject getModuleXmlObject(ModuleIdentification moduleId) throws Exception {\r
565 PackageIdentification packageId = getPackageForModule(moduleId);\r
566 moduleId.setPackage(packageId);\r
567 Spd spd = spdTable.get(packageId);\r
568 return spd.msaDocMap.get(moduleId);\r
569 }\r
570 \r
571 public synchronized static XmlObject getPackageXmlObject(PackageIdentification packageId) {\r
572 Spd spd = spdTable.get(packageId);\r
573 if (spd != null){\r
574 return spd.spdDocMap.get("PackageSurfaceArea");\r
575 }\r
576 return null;\r
577 }\r
578 \r
579 public synchronized static Set<PackageIdentification> getPackageList(){\r
580 return packageList;\r
581 }\r
582 ///// remove!!\r
583 private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws Exception {\r
584 if ( object == null) {\r
585 return null;\r
586 }\r
587 XmlObject result = null;\r
588 try {\r
589 result = XmlObject.Factory.parse(object.getDomNode()\r
590 .cloneNode(deep));\r
591 } catch (Exception ex) {\r
592 throw new Exception(ex.getMessage());\r
593 }\r
594 return result;\r
595 }\r
596\r
597 ////// Tool Chain Related, try to refine and put some logic process to ToolChainFactory\r
598 public static void setBuildToolChainFamilyOptions(Map<String, Object> map) {\r
599 toolChainFamilyOptions = map;\r
600 }\r
601\r
602 public static Map<String, Object> getToolChainFamilyOptions() {\r
603 return toolChainFamilyOptions;\r
604 }\r
605\r
606 public static void setBuildToolChainOptions(Map<String, Object> map) {\r
607 toolChainOptions = map;\r
608 }\r
609\r
610 public static Map<String, Object> getToolChainOptions() {\r
611 return toolChainOptions;\r
612 }\r
613\r
614 public static void setTargets(Set<String> targetSet) {\r
615 GlobalData.log.info("TargetSet: " + targetSet);\r
616 targets = targetSet;\r
617 }\r
618\r
619 public static String[] getTargets() {\r
620 return (String[])targets.toArray(new String[targets.size()]);\r
621 }\r
622\r
623 public static void setToolChains(Set<String> toolChainSet) {\r
624 toolChains = toolChainSet;\r
625 }\r
626\r
627 public static String[] getToolChains() {\r
628 String[] toolChainList = new String[toolChains.size()];\r
629 return (String[])toolChains.toArray(toolChainList);\r
630 }\r
631\r
632 public static void setToolChainFamilies(Set<String> toolChainFamilySet) {\r
633 toolChainFamilies = toolChainFamilySet;\r
634 }\r
635\r
636 public static void setToolChainFamiliyMap(Map<String, Set<String>> map) {\r
637 /*\r
638 Set<String> keys = map.keySet();\r
639 Iterator it = keys.iterator();\r
640 while (it.hasNext()) {\r
641 String toolchain = (String)it.next();\r
642 Set<String> familyMap = (Set<String>)map.get(toolchain);\r
643 Iterator fit = familyMap.iterator();\r
644 System.out.print(toolchain + ": ");\r
645 while (fit.hasNext()) {\r
646 System.out.print((String)fit.next() + " ");\r
647 }\r
648 System.out.println("");\r
649 }\r
650 */\r
651 toolChainFamilyMap = map;\r
652 }\r
653\r
654 public static String[] getToolChainFamilies() {\r
655 String[] toolChainFamilyList = new String[toolChainFamilies.size()];\r
656 return (String[])toolChainFamilies.toArray(toolChainFamilyList);\r
657 }\r
658\r
659 public static String[] getToolChainFamilies(String toolChain) {\r
660 Set<String> familySet = (Set<String>)toolChainFamilyMap.get(toolChain);\r
661 String[] toolChainFamilyList = new String[familySet.size()];\r
662 return (String[])familySet.toArray(toolChainFamilyList);\r
663 }\r
664\r
665 public static Set<String> getToolChainFamilySet(String toolChain) {\r
666 return (Set<String>)toolChainFamilyMap.get(toolChain);\r
667 }\r
668\r
669 public static void setArchs(Set<String> archSet) {\r
670 archs = archSet;\r
671 }\r
672\r
673 public static String[] getArchs() {\r
674 String[] archList = new String[archs.size()];\r
675 return (String[])archs.toArray(archList);\r
676 }\r
677 /*\r
678\r
679 */\r
680 public static void SetCommandTypes(Set<String> commandTypeSet) {\r
681 commandTypes = commandTypeSet;\r
682 }\r
683 /*\r
684\r
685 */\r
686 public static void SetCommandTypes(Map<String, Set<String>> commandTypeMap) {\r
687 toolChainCommandMap = commandTypeMap;\r
688 }\r
689 /*\r
690\r
691 */\r
692 public static String[] getCommandTypes() {\r
693 String[] commandList = new String[commandTypes.size()];\r
694 return (String[])commandTypes.toArray(commandList);\r
695 }\r
696 /*\r
697\r
698 */\r
699 public static String[] getCommandTypes(String toolChain) {\r
700 Set<String> commands = (Set<String>)toolChainCommandMap.get(toolChain);\r
701 if (commands == null) {\r
702 return new String[0];\r
703 }\r
704\r
705 String[] commandList = new String[commands.size()];\r
706 return (String[])commands.toArray(commandList);\r
707 }\r
708 /*\r
709\r
710 */\r
711 public static String getCommandSetting(String target, String toolChain, \r
712 String arch, String command, String attribute, FpdModuleIdentification fpdModuleId) {\r
713 String[] commandDescription = new String[] {target, toolChain, arch, command, attribute};\r
714 return getCommandSetting(commandDescription, fpdModuleId);\r
715 }\r
716 /*\r
717\r
718 */\r
719 public static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) {\r
720 if (commandDescription[4].equals("FLAGS")) {\r
721 return getCommandFlags(commandDescription, fpdModuleId);\r
722 }\r
723\r
724 StringBuffer commandDescString = new StringBuffer(32);\r
725\r
726 int i = 0;\r
727 while (true) {\r
728 commandDescString.append(commandDescription[i++]);\r
729 if (i >= commandDescription.length) {\r
730 break;\r
731 }\r
732 commandDescString.append("_");\r
733 }\r
734\r
735 return getCommandSetting(commandDescString.toString());\r
736 }\r
737 /*\r
738\r
739 */\r
740 public static String getCommandSetting(String commandDescString) {\r
741 return (String)toolChainDefinitions.get(commandDescString);\r
742 }\r
743 /*\r
744\r
745 */\r
746 public static String getCommandFlags(String[] commandDescription, FpdModuleIdentification fpdModuleId) {\r
747 String setting = getSetting(toolChainOptions, commandDescription, fpdModuleId, false);\r
748\r
749 if (setting == null) {\r
750 String commandDesc = commandDescription[4];\r
751 commandDescription[4] = "FAMILY";\r
752 String toolChainFamily = getCommandSetting(commandDescription, fpdModuleId);\r
753 commandDescription[4] = commandDesc;\r
754\r
755 commandDesc = commandDescription[1];\r
756 commandDescription[1] = toolChainFamily;\r
757 setting = getSetting(toolChainFamilyOptions, commandDescription, fpdModuleId, true);\r
758 commandDescription[1] = commandDesc;\r
759 }\r
760\r
761 if (setting == null) {\r
762 setting = "";\r
763 }\r
764 \r
765 \r
766 Set<String> addFlagsSet = new LinkedHashSet<String>();\r
767 Set<String> subFlagsSet = new LinkedHashSet<String>();\r
768 putFlagsToSet(addFlagsSet, setting);\r
769\r
770 return getFlags(addFlagsSet, subFlagsSet);\r
771 }\r
772 /*\r
773\r
774 */\r
775 private static String getSetting(Map<String, Object> optionMap, String[] commandDescription, \r
776 FpdModuleIdentification fpdModuleId, boolean toolChainFamilyFlag) {\r
777\r
778 String setting = (String)getOption(optionMap, commandDescription);\r
779 if (fpdModuleId == null) {\r
780 return setting;\r
781 }\r
782 //\r
783 // module overrides\r
784 //\r
785 //\r
786 // get module xml doc\r
787 //\r
788 Map<String, XmlObject> fpdModule = (Map<String, XmlObject>)fpdModuleSA.get(fpdModuleId);\r
789 if (fpdModuleId == null) {\r
790 return setting;\r
791 }\r
792 SurfaceAreaQuery.push(fpdModule);\r
793 //\r
794 // check if the module has been parsed\r
795 //\r
796 Map<String, Object> moduleOptions = (Map<String, Object>)moduleToolChainOptions.get(fpdModuleId);\r
797 if (moduleOptions == null) {\r
798 //\r
799 // get all the build options of this module\r
800 //\r
801 moduleOptions = new TreeMap<String, Object>(comparator);\r
802 parseBuildOptions(moduleOptions, SurfaceAreaQuery.getOptions(toolChainFamilyFlag));\r
803 }\r
804 //\r
805 // get setting for current qualified command\r
806 //\r
807 Set<String> addSet = new TreeSet<String>();\r
808 Set<String> subSet = new TreeSet<String>();\r
809 putFlagsToSet(addSet, setting);\r
810 String moduleSetting = getOption(moduleOptions, commandDescription);\r
811 if (moduleSetting != null) {\r
812 moduleSetting = parseOptionString(moduleSetting, addSet, subSet);\r
813 }\r
814 //\r
815 // do necessary setting override\r
816 //\r
817 if (moduleSetting == null) {\r
818 setting = getRawFlags(addSet, subSet);\r
819 } else {\r
820 setting = moduleSetting;\r
821 }\r
822\r
823 SurfaceAreaQuery.pop();\r
824 return setting;\r
825 }\r
826 /*\r
827\r
828 */\r
829 public static void setToolChainDefinitions(Map<String, String> def) {\r
830 toolChainDefinitions = def;\r
831 }\r
832\r
833 public static Map<String, String> getToolChainDefinitions() {\r
834 return toolChainDefinitions;\r
835 }\r
836\r
837 /**\r
838 Separate the string and instore in set.\r
839 \r
840 <p> String is separated by Java Regulation Expression \r
841 "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r
842 \r
843 <p>For example: </p>\r
844 \r
845 <pre>\r
846 "/nologo", "/W3", "/WX"\r
847 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r
848 </pre>\r
849 \r
850 @param set store the separated string\r
851 @param str string to separate\r
852 **/\r
853 private static void putFlagsToSet(Set<String> set, String str) {\r
854 if (str == null || str.length() == 0) {\r
855 return;\r
856 }\r
857\r
858 Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
859 Matcher matcher = myPattern.matcher(str + " ");\r
860 while (matcher.find()) {\r
861 String item = str.substring(matcher.start(1), matcher.end(1));\r
862 set.add(item);\r
863 }\r
864 }\r
865 \r
866 /**\r
867 Generate the final flags string will be used by compile command. \r
868 \r
869 @param add the add flags set\r
870 @param sub the sub flags set\r
871 @return final flags after add set substract sub set\r
872 **/\r
873 private static String getFlags(Set<String> add, Set<String> sub) {\r
874 String result = "";\r
875 add.removeAll(sub);\r
876 Iterator iter = add.iterator();\r
877 while (iter.hasNext()) {\r
878 String str = (String) iter.next();\r
879 result += str.substring(1, str.length() - 1) + " ";\r
880 }\r
881 return result;\r
882 }\r
883\r
884 /**\r
885 Generate the flags string with original format. The format is defined by \r
886 Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r
887 \r
888 <p>For example: </p>\r
889 \r
890 <pre>\r
891 "/nologo", "/W3", "/WX"\r
892 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r
893 </pre>\r
894 \r
895 @param add the add flags set\r
896 @param sub the sub flags set\r
897 @return flags with original format\r
898 **/\r
899 private static String getRawFlags(Set<String> add, Set<String> sub) {\r
900 String result = null;\r
901 add.removeAll(sub);\r
902 Iterator iter = add.iterator();\r
903 while (iter.hasNext()) {\r
904 String str = (String) iter.next();\r
905 result += "\"" + str.substring(1, str.length() - 1) + "\", ";\r
906 }\r
907 return result;\r
908 }\r
909\r
910 private static String parseOptionString(String optionString, Set<String> addSet, Set<String> subSet) {\r
911 boolean overrideOption = false;\r
912 Pattern pattern = Pattern.compile("ADD\\.\\[(.+)\\]");\r
913 Matcher matcher = pattern.matcher(optionString);\r
914\r
915 while (matcher.find()) {\r
916 overrideOption = true;\r
917 String addOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();\r
918 putFlagsToSet(addSet, addOption);\r
919 \r
920 }\r
921\r
922 pattern = Pattern.compile("SUB\\.\\[(.+)\\]");\r
923 matcher = pattern.matcher(optionString);\r
924\r
925 while (matcher.find()) {\r
926 overrideOption = true;\r
927 String subOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();\r
928 putFlagsToSet(subSet, subOption);\r
929 }\r
930\r
931 if (overrideOption == true) {\r
932 return null;\r
933 }\r
934\r
935 return optionString;\r
936 }\r
937\r
938 public static String getOption(Map<String, Object> options, String[] toolDefString) {\r
939 Stack<Map<String, Object>> stack = new Stack<Map<String, Object>>();\r
940 Map<String, Object> map = options;\r
941 Map<String, Object> lastMap;\r
942 String option = null;\r
943 int length = toolDefString.length - 2;\r
944\r
945 int i = 0;\r
946 String key = null;\r
947 boolean backtrack = false;\r
948 while (true) {\r
949 if (map == null) {\r
950 if (stack.empty()) {\r
951 break;\r
952 }\r
953 map = (Map<String, Object>)stack.pop();\r
954 if (backtrack) {\r
955 --i;\r
956 }\r
957 key = "*";\r
958 backtrack = true;\r
959 } else {\r
960 if (i >= length) {\r
961 break;\r
962 }\r
963 key = toolDefString[i];\r
964 stack.push(map);\r
965 ++i;\r
966 backtrack = false;\r
967 }\r
968 lastMap = map;\r
969 map = (Map<String, Object>)lastMap.get(key);\r
970 }\r
971\r
972 if (map != null) {\r
973 option = (String)map.get(toolDefString[i]);\r
974 }\r
975\r
976 return option;\r
977 }\r
978\r
979 private static void parseBuildOptions(Map<String, Object> optionMap, String[][] options) {\r
980 Map<String, Object> map;\r
981 Map<String, Object> nextMap;\r
982\r
983 for (int i = 0; i < options.length; ++i) {\r
984 map = optionMap;\r
985\r
986 int flagIndex = options[i].length - 1;\r
987 int cmdIndex = flagIndex - 1;\r
988 int archIndex = cmdIndex - 1;\r
989 for (int j = 0; j < cmdIndex; ++j) {\r
990 String s = options[i][j];\r
991 if (s == null || s.trim().length() == 0) {\r
992 s = "*";\r
993 }\r
994 s = s.trim().toUpperCase();\r
995\r
996 nextMap = (Map<String, Object>)map.get(s);\r
997 if (nextMap == null) {\r
998 nextMap = new HashMap<String, Object>();\r
999 map.put(s, nextMap);\r
1000 }\r
1001\r
1002 map = nextMap;\r
1003 }\r
1004\r
1005 String cmd = options[i][cmdIndex];\r
1006 String flag = options[i][flagIndex];\r
1007 if (cmd == null || cmd.trim().length() == 0) {\r
1008 cmd = "*";\r
1009 }\r
1010 if (flag == null) {\r
1011 flag = "";\r
1012 }\r
1013 map.put(cmd.trim().toUpperCase(), flag.trim().toUpperCase());\r
1014 }\r
1015 }\r
1016\r
1017}\r
1018\r
1019final class KeyComparator implements Comparator<String> {\r
1020 public int compare(String x, String y) {\r
1021 return x.compareToIgnoreCase(y);\r
1022 }\r
1023 \r
1024}\r
1025\r