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