4 GlobalData provide initializing, instoring, querying and update global data.
5 It is a bridge to intercommunicate between multiple component, such as AutoGen,
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
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.
17 package org
.tianocore
.frameworkwizard
.platform
.ui
.global
;
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
;
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
;
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
;
46 GlobalData provide initializing, instoring, querying and update global data.
47 It is a bridge to intercommunicate between multiple component, such as AutoGen,
50 <p>Note that all global information are initialized incrementally. All data will
51 parse and record only of necessary during build time. </p>
55 public class GlobalData
{
58 public static Logger log
= Logger
.getAnonymousLogger();
59 public static KeyComparator comparator
= new KeyComparator();
61 /// Record current WORKSPACE Directory
63 private static String workspaceDir
= "";
66 /// Be used to ensure Global data will be initialized only once.
68 private static boolean globalFlag
= false;
71 /// Framework Database information: package list and platform list
73 private static Set
<PackageIdentification
> packageList
= new HashSet
<PackageIdentification
>();
75 private static Set
<PlatformIdentification
> platformList
= new HashSet
<PlatformIdentification
>();
78 /// Every detail SPD informations: Module list, Library class definition,
79 /// Package header file, GUID/PPI/Protocol definitions
81 private static final Map
<PackageIdentification
, Spd
> spdTable
= new HashMap
<PackageIdentification
, Spd
>();
84 /// Build informations are divided into three parts:
85 /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
87 private static Map
<ModuleIdentification
, Map
<String
, XmlObject
>> nativeMsa
= new HashMap
<ModuleIdentification
, Map
<String
, XmlObject
>>();
89 private static Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> fpdModuleSA
= new HashMap
<FpdModuleIdentification
, Map
<String
, XmlObject
>>();
91 private static XmlObject fpdBuildOptions
;
93 private static XmlObject fpdDynamicPcds
;
96 /// Parsed modules list
98 private static Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> parsedModules
= new HashMap
<FpdModuleIdentification
, Map
<String
, XmlObject
>>();
101 /// built modules list with ARCH, TARGET, TOOLCHAIN
103 private static Set
<FpdModuleIdentification
> builtModules
= new HashSet
<FpdModuleIdentification
>();
106 /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.
108 // private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
111 /// build target + tool chain family/tag name + arch + command types + command options
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
>>();;
121 private static Set
<String
> targets
;
125 private static Set
<String
> toolChainFamilies
;
129 private static Set
<String
> toolChains
;
131 /// keep track which toolchain family a toolchain tag belongs to
133 private static Map
<String
, Set
<String
>> toolChainFamilyMap
;
134 private static Map
<String
, Set
<String
>> toolChainCommandMap
;
137 /// list of Arch: EBC, ARM, IA32, X64, IPF, PPC
139 private static Set
<String
> archs
;
142 /// list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK, PP
144 private static Set
<String
> commandTypes
;
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.
151 @param workspaceDatabaseFile the file name of framework database
152 @param workspaceDir current workspace directory path
154 Framework Dababase or SPD or MSA file is not valid
156 public synchronized static void initInfo(String workspaceDatabaseFile
, String workspaceDir
) throws Exception
{
158 // ensure this method will be revoked only once
166 // Backup workspace directory. It will be used by other method
168 GlobalData
.workspaceDir
= workspaceDir
.replaceAll("(\\\\)", "/");
169 File dbFile
= new File(workspaceDir
+ File
.separatorChar
+ workspaceDatabaseFile
);
171 FrameworkDatabaseDocument db
= (FrameworkDatabaseDocument
) XmlObject
.Factory
.parse(dbFile
);
173 // validate FrameworkDatabaseFile
175 // if (! db.validate()) {
176 // throw new Exception("Framework Database file [" + dbFile.getPath() + "] is invalid.");
181 List
<DbPathAndFilename
> packages
= db
.getFrameworkDatabase().getPackageList().getFilenameList();
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
);
193 } catch (Exception e
) {
195 throw new Exception("Parse workspace Database [" + dbFile
.getPath() + "] Error.\n" + e
.getMessage());
200 Get the current WORKSPACE Directory.
202 @return current workspace directory
204 public synchronized static String
getWorkspacePath() {
210 Get the MSA file name with absolute path
212 public synchronized static File
getMsaFile(ModuleIdentification moduleId
) throws Exception
{
215 // TBD. Do only when package is null.
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 ) {
226 if (msaFile
== null){
227 throw new Exception("Can't find Module [" + moduleId
.getName() + "] in all packages. ");
234 public synchronized static PackageIdentification
getPackageForModule(ModuleIdentification moduleId
) {
236 // If package already defined in module
238 if (moduleId
.getPackage() != null) {
239 return moduleId
.getPackage();
242 PackageIdentification packageId
= null;
243 Iterator iter
= packageList
.iterator();
244 while (iter
.hasNext()) {
245 packageId
= (PackageIdentification
)iter
.next();
247 Spd spd
= spdTable
.get(packageId
);
248 if (spd
.getModuleFile(moduleId
) != null ) {
249 moduleId
.setPackage(packageId
);
253 if (packageId
== null){
262 Difference between build and parse: ToolChain and Target
264 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId
) {
265 return builtModules
.contains(moduleId
);
268 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId
) {
269 builtModules
.add(fpdModuleId
);
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
);
282 fpdModuleSA
.put(fpdModuleId
, result
);
286 Query overrided module surface area information. If current is Package
287 or Platform build, also include the information from FPD file.
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>
292 @param moduleName the base name of the module
293 @return the overrided module surface area information
295 MSA or MBD is not valid
297 public synchronized static Map
<String
, XmlObject
> getDoc(FpdModuleIdentification fpdModuleId
) throws Exception
{
298 if (parsedModules
.containsKey(fpdModuleId
)) {
299 return parsedModules
.get(fpdModuleId
);
301 Map
<String
, XmlObject
> doc
= new HashMap
<String
, XmlObject
>();
302 ModuleIdentification moduleId
= fpdModuleId
.getModule();
304 // First part: get the MSA files info
306 doc
= getNativeMsa(moduleId
);
309 // Second part: put build options
311 doc
.put("BuildOptions", fpdBuildOptions
);
314 // Third part: get Module info from FPD, such as Library instances, PCDs
316 if (fpdModuleSA
.containsKey(fpdModuleId
)){
318 // merge module info in FPD to final Doc
319 // For Library Module, do nothing here
321 doc
.putAll(fpdModuleSA
.get(fpdModuleId
));
323 parsedModules
.put(fpdModuleId
, doc
);
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
);
332 Query the native MSA information with module base name.
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>
337 @param moduleName the base name of the module
338 @return the native MSA information
340 MSA file is not valid
342 public synchronized static Map
<String
, XmlObject
> getNativeMsa(ModuleIdentification moduleId
) throws Exception
{
343 if (nativeMsa
.containsKey(moduleId
)) {
344 return nativeMsa
.get(moduleId
);
346 File msaFile
= getMsaFile(moduleId
);
347 Map
<String
, XmlObject
> msaMap
= getNativeMsa(msaFile
);
348 nativeMsa
.put(moduleId
, msaMap
);
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.");
357 ModuleSurfaceAreaDocument doc
= (ModuleSurfaceAreaDocument
)XmlObject
.Factory
.parse(msaFile
);
359 // Validate File if they accord with XML Schema
361 // if ( ! doc.validate()){
362 // throw new Exception("Module Surface Area file [" + msaFile.getPath() + "] is invalid.");
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));
380 catch (Exception ex
){
381 throw new Exception(ex
.getMessage());
385 public static Map
<String
, XmlObject
> getFpdBuildOptions() {
386 Map
<String
, XmlObject
> map
= new HashMap
<String
, XmlObject
>();
387 map
.put("BuildOptions", fpdBuildOptions
);
391 public static void setFpdBuildOptions(XmlObject fpdBuildOptions
) throws Exception
{
392 GlobalData
.fpdBuildOptions
= cloneXmlObject(fpdBuildOptions
, true);
395 public static XmlObject
getFpdDynamicPcds() {
396 return fpdDynamicPcds
;
399 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds
) {
400 GlobalData
.fpdDynamicPcds
= fpdDynamicPcds
;
403 //////////////////////////////////////////////
404 //////////////////////////////////////////////
406 public static Set
<ModuleIdentification
> getModules(PackageIdentification packageId
){
407 Spd spd
= spdTable
.get(packageId
);
409 Set
<ModuleIdentification
> dummy
= new HashSet
<ModuleIdentification
>();
413 return spd
.getModules();
418 The header file path is relative to workspace dir
420 public static String
[] getLibraryClassHeaderFiles(PackageIdentification
[] packages
, String name
) {
421 if (packages
== null ){
422 // throw Exception or not????
423 return new String
[0];
425 String
[] result
= null;
426 for (int i
= 0; i
< packages
.length
; i
++){
427 Spd spd
= spdTable
.get(packages
[i
]);
429 // If find one package defined the library class
431 if( (result
= spd
.getLibClassIncluder(name
)) != null){
440 The header file path is relative to workspace dir
442 public static String
getPackageHeaderFiles(PackageIdentification packages
, String moduleType
) throws Exception
{
443 if (packages
== null ){
444 return new String("");
446 Spd spd
= spdTable
.get(packages
);
448 // If can't find package header file, skip it
452 if( (temp
= spd
.getPackageIncluder(moduleType
)) != null){
464 return two values: {cName, GuidValue}
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];
471 String
[] result
= null;
472 for (int i
= 0; i
< packages
.length
; i
++){
473 Spd spd
= spdTable
.get(packages
[i
]);
475 // If find one package defined the GUID
477 if( (result
= spd
.getGuid(name
)) != null){
485 return two values: {cName, GuidValue}
487 public static String
[] getPpiGuid(PackageIdentification
[] packages
, String name
) throws Exception
{
488 if (packages
== null ){
489 return new String
[0];
491 String
[] result
= null;
492 for (int i
= 0; i
< packages
.length
; i
++){
493 Spd spd
= spdTable
.get(packages
[i
]);
495 // If find one package defined the Ppi GUID
497 if( (result
= spd
.getPpi(name
)) != null){
506 return two values: {cName, GuidValue}
508 public static String
[] getProtocolGuid(PackageIdentification
[] packages
, String name
) throws Exception
{
509 if (packages
== null ){
510 return new String
[0];
512 String
[] result
= null;
513 for (int i
= 0; i
< packages
.length
; i
++){
514 Spd spd
= spdTable
.get(packages
[i
]);
516 // If find one package defined the protocol GUID
518 if( (result
= spd
.getProtocol(name
)) != null){
526 /////////////////////////// Update!! Update!! Update!!
527 // public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
528 // return pcdDbManager;
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());
540 throw new Exception("Can't find platform [" + name
+ "] in current workspace. ");
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();
552 throw new Exception("Can't find " + packageId
+ " in current workspace. ");
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
);
562 // expanded by FrameworkWizard
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
);
571 public synchronized static XmlObject
getPackageXmlObject(PackageIdentification packageId
) {
572 Spd spd
= spdTable
.get(packageId
);
574 return spd
.spdDocMap
.get("PackageSurfaceArea");
579 public synchronized static Set
<PackageIdentification
> getPackageList(){
583 private static XmlObject
cloneXmlObject(XmlObject object
, boolean deep
) throws Exception
{
584 if ( object
== null) {
587 XmlObject result
= null;
589 result
= XmlObject
.Factory
.parse(object
.getDomNode()
591 } catch (Exception ex
) {
592 throw new Exception(ex
.getMessage());
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
;
602 public static Map
<String
, Object
> getToolChainFamilyOptions() {
603 return toolChainFamilyOptions
;
606 public static void setBuildToolChainOptions(Map
<String
, Object
> map
) {
607 toolChainOptions
= map
;
610 public static Map
<String
, Object
> getToolChainOptions() {
611 return toolChainOptions
;
614 public static void setTargets(Set
<String
> targetSet
) {
615 GlobalData
.log
.info("TargetSet: " + targetSet
);
619 public static String
[] getTargets() {
620 return (String
[])targets
.toArray(new String
[targets
.size()]);
623 public static void setToolChains(Set
<String
> toolChainSet
) {
624 toolChains
= toolChainSet
;
627 public static String
[] getToolChains() {
628 String
[] toolChainList
= new String
[toolChains
.size()];
629 return (String
[])toolChains
.toArray(toolChainList
);
632 public static void setToolChainFamilies(Set
<String
> toolChainFamilySet
) {
633 toolChainFamilies
= toolChainFamilySet
;
636 public static void setToolChainFamiliyMap(Map
<String
, Set
<String
>> map
) {
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() + " ");
648 System.out.println("");
651 toolChainFamilyMap
= map
;
654 public static String
[] getToolChainFamilies() {
655 String
[] toolChainFamilyList
= new String
[toolChainFamilies
.size()];
656 return (String
[])toolChainFamilies
.toArray(toolChainFamilyList
);
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
);
665 public static Set
<String
> getToolChainFamilySet(String toolChain
) {
666 return (Set
<String
>)toolChainFamilyMap
.get(toolChain
);
669 public static void setArchs(Set
<String
> archSet
) {
673 public static String
[] getArchs() {
674 String
[] archList
= new String
[archs
.size()];
675 return (String
[])archs
.toArray(archList
);
680 public static void SetCommandTypes(Set
<String
> commandTypeSet
) {
681 commandTypes
= commandTypeSet
;
686 public static void SetCommandTypes(Map
<String
, Set
<String
>> commandTypeMap
) {
687 toolChainCommandMap
= commandTypeMap
;
692 public static String
[] getCommandTypes() {
693 String
[] commandList
= new String
[commandTypes
.size()];
694 return (String
[])commandTypes
.toArray(commandList
);
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];
705 String
[] commandList
= new String
[commands
.size()];
706 return (String
[])commands
.toArray(commandList
);
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
);
719 public static String
getCommandSetting(String
[] commandDescription
, FpdModuleIdentification fpdModuleId
) {
720 if (commandDescription
[4].equals("FLAGS")) {
721 return getCommandFlags(commandDescription
, fpdModuleId
);
724 StringBuffer commandDescString
= new StringBuffer(32);
728 commandDescString
.append(commandDescription
[i
++]);
729 if (i
>= commandDescription
.length
) {
732 commandDescString
.append("_");
735 return getCommandSetting(commandDescString
.toString());
740 public static String
getCommandSetting(String commandDescString
) {
741 return (String
)toolChainDefinitions
.get(commandDescString
);
746 public static String
getCommandFlags(String
[] commandDescription
, FpdModuleIdentification fpdModuleId
) {
747 String setting
= getSetting(toolChainOptions
, commandDescription
, fpdModuleId
, false);
749 if (setting
== null) {
750 String commandDesc
= commandDescription
[4];
751 commandDescription
[4] = "FAMILY";
752 String toolChainFamily
= getCommandSetting(commandDescription
, fpdModuleId
);
753 commandDescription
[4] = commandDesc
;
755 commandDesc
= commandDescription
[1];
756 commandDescription
[1] = toolChainFamily
;
757 setting
= getSetting(toolChainFamilyOptions
, commandDescription
, fpdModuleId
, true);
758 commandDescription
[1] = commandDesc
;
761 if (setting
== null) {
766 Set
<String
> addFlagsSet
= new LinkedHashSet
<String
>();
767 Set
<String
> subFlagsSet
= new LinkedHashSet
<String
>();
768 putFlagsToSet(addFlagsSet
, setting
);
770 return getFlags(addFlagsSet
, subFlagsSet
);
775 private static String
getSetting(Map
<String
, Object
> optionMap
, String
[] commandDescription
,
776 FpdModuleIdentification fpdModuleId
, boolean toolChainFamilyFlag
) {
778 String setting
= (String
)getOption(optionMap
, commandDescription
);
779 if (fpdModuleId
== null) {
786 // get module xml doc
788 Map
<String
, XmlObject
> fpdModule
= (Map
<String
, XmlObject
>)fpdModuleSA
.get(fpdModuleId
);
789 if (fpdModuleId
== null) {
792 SurfaceAreaQuery
.push(fpdModule
);
794 // check if the module has been parsed
796 Map
<String
, Object
> moduleOptions
= (Map
<String
, Object
>)moduleToolChainOptions
.get(fpdModuleId
);
797 if (moduleOptions
== null) {
799 // get all the build options of this module
801 moduleOptions
= new TreeMap
<String
, Object
>(comparator
);
802 parseBuildOptions(moduleOptions
, SurfaceAreaQuery
.getOptions(toolChainFamilyFlag
));
805 // get setting for current qualified command
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
);
815 // do necessary setting override
817 if (moduleSetting
== null) {
818 setting
= getRawFlags(addSet
, subSet
);
820 setting
= moduleSetting
;
823 SurfaceAreaQuery
.pop();
829 public static void setToolChainDefinitions(Map
<String
, String
> def
) {
830 toolChainDefinitions
= def
;
833 public static Map
<String
, String
> getToolChainDefinitions() {
834 return toolChainDefinitions
;
838 Separate the string and instore in set.
840 <p> String is separated by Java Regulation Expression
841 "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
846 "/nologo", "/W3", "/WX"
847 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
850 @param set store the separated string
851 @param str string to separate
853 private static void putFlagsToSet(Set
<String
> set
, String str
) {
854 if (str
== null || str
.length() == 0) {
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));
867 Generate the final flags string will be used by compile command.
869 @param add the add flags set
870 @param sub the sub flags set
871 @return final flags after add set substract sub set
873 private static String
getFlags(Set
<String
> add
, Set
<String
> sub
) {
876 Iterator iter
= add
.iterator();
877 while (iter
.hasNext()) {
878 String str
= (String
) iter
.next();
879 result
+= str
.substring(1, str
.length() - 1) + " ";
885 Generate the flags string with original format. The format is defined by
886 Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
891 "/nologo", "/W3", "/WX"
892 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
895 @param add the add flags set
896 @param sub the sub flags set
897 @return flags with original format
899 private static String
getRawFlags(Set
<String
> add
, Set
<String
> sub
) {
900 String result
= null;
902 Iterator iter
= add
.iterator();
903 while (iter
.hasNext()) {
904 String str
= (String
) iter
.next();
905 result
+= "\"" + str
.substring(1, str
.length() - 1) + "\", ";
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
);
915 while (matcher
.find()) {
916 overrideOption
= true;
917 String addOption
= optionString
.substring(matcher
.start(1), matcher
.end(1)).trim();
918 putFlagsToSet(addSet
, addOption
);
922 pattern
= Pattern
.compile("SUB\\.\\[(.+)\\]");
923 matcher
= pattern
.matcher(optionString
);
925 while (matcher
.find()) {
926 overrideOption
= true;
927 String subOption
= optionString
.substring(matcher
.start(1), matcher
.end(1)).trim();
928 putFlagsToSet(subSet
, subOption
);
931 if (overrideOption
== true) {
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;
947 boolean backtrack
= false;
953 map
= (Map
<String
, Object
>)stack
.pop();
963 key
= toolDefString
[i
];
969 map
= (Map
<String
, Object
>)lastMap
.get(key
);
973 option
= (String
)map
.get(toolDefString
[i
]);
979 private static void parseBuildOptions(Map
<String
, Object
> optionMap
, String
[][] options
) {
980 Map
<String
, Object
> map
;
981 Map
<String
, Object
> nextMap
;
983 for (int i
= 0; i
< options
.length
; ++i
) {
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) {
994 s
= s
.trim().toUpperCase();
996 nextMap
= (Map
<String
, Object
>)map
.get(s
);
997 if (nextMap
== null) {
998 nextMap
= new HashMap
<String
, Object
>();
1005 String cmd
= options
[i
][cmdIndex
];
1006 String flag
= options
[i
][flagIndex
];
1007 if (cmd
== null || cmd
.trim().length() == 0) {
1013 map
.put(cmd
.trim().toUpperCase(), flag
.trim().toUpperCase());
1019 final class KeyComparator
implements Comparator
<String
> {
1020 public int compare(String x
, String y
) {
1021 return x
.compareToIgnoreCase(y
);