2 // This Class processes multiple MSA files and merges them into a single,
3 // merged MSA file. It will optionally add the merged MSA file into a package.
6 // Copyright (c) 2006, Intel Corporation All rights reserved.
8 // This program and the accompanying materials are licensed and made
9 // available under the terms and conditions of the BSD License which
10 // accompanies this distribution. The full text of the license may
11 // be found at http://opensource.org/licenses/bsd-license.php
13 // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 package org
.tianocore
.Merge
;
22 // import java.lang.*;
23 // import java.lang.ExceptionInInitializerError;
25 // import org.apache.xmlbeans.*;
26 import org
.apache
.xmlbeans
.XmlCursor
;
27 // import org.apache.xmlbeans.XmlObject;
28 import org
.apache
.xmlbeans
.XmlOptions
;
29 import org
.apache
.xmlbeans
.XmlException
;
30 import org
.tianocore
.*;
32 // import org.tianocore.*;
33 import org
.tianocore
.ModuleSurfaceAreaDocument
.*;
34 import org
.tianocore
.MsaHeaderDocument
.*;
35 import org
.tianocore
.LicenseDocument
.*;
36 import org
.tianocore
.ModuleDefinitionsDocument
.*;
37 import org
.tianocore
.LibraryClassDefinitionsDocument
.*;
38 import org
.tianocore
.SourceFilesDocument
.*;
39 import org
.tianocore
.PackageDependenciesDocument
.*;
40 import org
.tianocore
.ProtocolsDocument
.*;
41 import org
.tianocore
.EventsDocument
.*;
42 import org
.tianocore
.HobsDocument
.*;
43 import org
.tianocore
.PPIsDocument
.*;
44 import org
.tianocore
.VariablesDocument
.*;
45 import org
.tianocore
.BootModesDocument
.*;
46 import org
.tianocore
.SystemTablesDocument
.*;
47 import org
.tianocore
.DataHubsDocument
.*;
48 import org
.tianocore
.HiiPackagesDocument
.*;
49 import org
.tianocore
.GuidsDocument
.*;
50 import org
.tianocore
.ExternsDocument
.*;
51 import org
.tianocore
.PcdCodedDocument
.*;
52 import org
.tianocore
.ModuleBuildOptionsDocument
.*;
53 import org
.tianocore
.UserExtensionsDocument
.*;
55 import org
.tianocore
.PackageSurfaceAreaDocument
.*;
56 import org
.tianocore
.MsaFilesDocument
.*;
58 public class CombineMsa
{
60 private final int DEBUG
= 0;
62 private final int PASS
= 0;
64 private final int FAIL
= 1;
66 private final int FOUND
= 0;
68 private final int NOTFOUND
= 1;
70 private int result
= PASS
;
72 private String licenseTxt
= "";
74 private ArrayList
<String
> aLicenses
= new ArrayList
<String
>();
76 private String Copyright
= "";
78 private ArrayList
<String
> aCopyright
= new ArrayList
<String
>();
80 private String Abstract
= "\n Merged Modules: \n";
82 private String Description
= "\n Merging Modules: \n";
84 private String sArchitectures
= "";
86 private MsaHeader header
= null;
88 private final String Specification
= "FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052";
90 private ModuleSurfaceArea mergeMsaFile
= null;
92 private ModuleSurfaceArea leafMsa
= null;
94 private ModuleDefinitions moduleDefs
= null;
96 private LibraryClassDefinitions libClassDefs
= null;
98 private ArrayList
<String
> aLibClassDefs
= new ArrayList
<String
>();
100 private int libraryClassIndex
= 0;
102 private SourceFiles mergeSourceFiles
= null;
104 private int sourceFileIndex
= 0;
106 private PackageDependencies mergePackageDependencies
= null;
108 private ArrayList
<String
> aPackageList
= new ArrayList
<String
>();
110 private int packageDependenciesIndex
= 0;
112 private Protocols mergeProtocols
= null;
114 private ArrayList
<String
> aProtocolList
= new ArrayList
<String
>();
116 private ArrayList
<String
> aProtocolNotifyList
= new ArrayList
<String
>();
118 private int protocolIndex
= 0;
120 private int protocolNotifyIndex
= 0;
122 private Events mergeEvents
= null;
124 private Events
.CreateEvents mergeCreateEvents
= null;
126 private Events
.SignalEvents mergeSignalEvents
= null;
128 private ArrayList
<String
> aCreateEventsList
= new ArrayList
<String
>();
130 private ArrayList
<String
> aSignalEventsList
= new ArrayList
<String
>();
132 private int createEventIndex
= 0;
134 private int signalEventIndex
= 0;
136 private Hobs mergeHobs
= null;
138 private ArrayList
<String
> aHobsList
= new ArrayList
<String
>();
140 private int hobsIndex
= 0;
142 private PPIs mergePpis
= null;
144 private ArrayList
<String
> aPpiList
= new ArrayList
<String
>();
146 private ArrayList
<String
> aPpiNotifyList
= new ArrayList
<String
>();
148 private int ppiIndex
= 0;
150 private int ppiNotifyIndex
= 0;
152 private Variables mergeVariables
= null;
154 private ArrayList
<String
> aVariablesList
= new ArrayList
<String
>();
156 private int variablesIndex
= 0;
158 private BootModes mergeBootModes
= null;
160 private ArrayList
<String
> aBootModesList
= new ArrayList
<String
>();
162 private int bootModesIndex
= 0;
164 private SystemTables mergeSystemTables
= null;
166 private ArrayList
<String
> aSystemTablesList
= new ArrayList
<String
>();
168 private int systemTableIndex
= 0;
170 private DataHubs mergeDataHubs
= null;
172 private ArrayList
<String
> aDataHubsList
= new ArrayList
<String
>();
174 private int dataHubsIndex
= 0;
176 private HiiPackages mergeHiiPackages
= null;
178 private ArrayList
<String
> aHiiPackagesList
= new ArrayList
<String
>();
180 private int hiiPackageIndex
= 0;
182 private Guids mergeGuids
= null;
184 private ArrayList
<String
> aGuidsList
= new ArrayList
<String
>();
186 private int guidsIndex
= 0;
188 private Externs mergeExterns
= null;
190 private ArrayList
<String
> aEntryPointList
= new ArrayList
<String
>();
192 private ArrayList
<String
> aUnloadImageList
= new ArrayList
<String
>();
194 private ArrayList
<String
> aDriverBindingList
= new ArrayList
<String
>();
196 private ArrayList
<String
> aConstructorList
= new ArrayList
<String
>();
198 private ArrayList
<String
> aDestructorList
= new ArrayList
<String
>();
200 private ArrayList
<String
> aVirtualAddressMapList
= new ArrayList
<String
>();
202 private ArrayList
<String
> aExitBootServicesList
= new ArrayList
<String
>();
204 private int externsIndex
= 0;
206 private ArrayList
<String
> aSpecArray
= new ArrayList
<String
>();
208 private int specIndex
= 0;
210 private PcdCoded mergePcdCoded
= null;
212 private ArrayList
<String
> aPcdCNameList
= new ArrayList
<String
>();
214 private ArrayList
<String
> aPcdItemTypeList
= new ArrayList
<String
>();
216 private int pcdIndex
= 0;
218 private ModuleBuildOptions mergeBuildOptions
= null;
220 private UserExtensions mergeUserExtensions
= null;
222 private XmlCursor cursor
= null;
224 private String mergeUsage
= "";
226 private String leafUsage
= "";
228 private int VERBOSE
= 0;
230 // The combineMsaFiles routine is the primary routine for creating a
233 public int combineMsaFiles(String msaFilename
, ArrayList
<String
> msaFiles
, String uiName
, String spdFilename
,
234 String baseName
, int Flags
) {
235 // msaFile has been verified to either not exist, or, if it does exist,
236 // it will be over written.
237 // All files in the msaFiles ArrayList have been verifed to exist.
238 // If the uiName is not null, we will have a new UI Name for the merged
240 // If the uiName is null, we will use the module name from the first
242 // If the spdFile is not null, the Package (SPD) file has been verified
244 // If the spdFile is null, don't attempt to add the new msa file.
248 if (mergeMsaFile
== null) {
250 // create the data structure for the merged Module
252 mergeMsaFile
= ModuleSurfaceArea
.Factory
.newInstance();
254 System
.out
.println("Merging " + msaFiles
.size() + " Modules");
256 // we always require a Header and a Module Definition section.
257 // These will be added to the mergeMsaFile after we have completed
258 // all processing of the Leaf MSA files.
260 header
= MsaHeaderDocument
.Factory
.newInstance().addNewMsaHeader();
261 moduleDefs
= ModuleDefinitionsDocument
.Factory
.newInstance().addNewModuleDefinitions();
263 // A merged module cannot be created from binary modules - we force
264 // the new module to be source here, however we will test every
265 // module to make sure that none are binary; exiting the program if
266 // a module is binary
268 moduleDefs
.setBinaryModule(false);
270 for (int i
= 0; i
< msaFiles
.size(); i
++) {
271 String leafFilename
= msaFiles
.get(i
).toString();
272 leafMsa
= getLeafFile(leafFilename
);
273 if (leafMsa
== null) {
274 System
.out
.println("Could not read Leaf MSA file: " + leafFilename
);
279 // Special code for first file, since this file is used
280 // to initialize some of the data in the mergeMsaFile.
281 // Set the Merge module's ModuleName to the name in the
282 // first Leaf Module. If a new module name is given,
283 // over write it later, just before writing the Merge
285 header
.setModuleName(leafMsa
.getMsaHeader().getModuleName().toString());
287 // All modules must be of the same module type, we set it
288 // here, and test the other Leaf modules' type later.
289 header
.setModuleType(leafMsa
.getMsaHeader().getModuleType());
291 // This is a new Module, so we need a new GUID
292 header
.setGuidValue(UUID
.randomUUID().toString());
294 // Use the version from the first Leaf module as the
295 // Merge Module version number.
296 header
.setVersion(leafMsa
.getMsaHeader().getVersion().toString());
298 // There is no special requirement for processing the
299 // following, so we just fall through on these elements
301 // Abstract will be added after parsing all leaf MSA files.
302 // Description will be added after parsing all leaf MSA files.
303 // Copyright will be added after parsing all leaf MSA files.
304 // License will be added after parsing all leaf MSA files.
306 // Force the specification to match this tool's spec version.
307 header
.setSpecification(Specification
);
309 // Set the Merged Module's Output Basename to match the first
311 String OutputFileName
= leafMsa
.getModuleDefinitions().getOutputFileBasename().toString();
313 // Just in case someone put a space character in the first
314 // leaf module's output filename, replace the spaces with
316 OutputFileName
.replace(" ", "_");
317 moduleDefs
.setOutputFileBasename(OutputFileName
);
319 // We start with the first module's list of supported
320 // architectures. As we process the additional leaf modules,
321 // we may have to remove some supported architectures from
322 // the list, as we can only build for the "least common
323 // denominator" subset of architectures.
324 sArchitectures
= leafMsa
.getModuleDefinitions().getSupportedArchitectures().toString();
325 if ((DEBUG
> 5) || (VERBOSE
> 5))
326 System
.out
.println("New Header: \"" + header
.getModuleName().toString() + "\"");
329 // We test the license in each leaf module, and will only print
330 // licenses that are may be different in wording (white spaces
331 // and line feeds are ignored in this test.)
332 if (leafMsa
.getMsaHeader().getLicense() != null)
333 licenseTxt
+= checkDuplicateStrings(leafMsa
.getMsaHeader().getLicense().getStringValue().trim(),
335 if ((DEBUG
> 10) || (VERBOSE
> 10))
336 System
.out
.println("License: " + licenseTxt
);
338 // We test the copyright line from each leaf module, and will
339 // add additional copyright lines only if they are different
340 // in wording (white spaces and line feeds are ignored in this
342 if (leafMsa
.getMsaHeader().getCopyright() != null)
343 Copyright
+= checkDuplicateStrings(leafMsa
.getMsaHeader().getCopyright().toString().trim(),
345 if ((DEBUG
> 10) || (VERBOSE
> 10))
346 System
.out
.println("Copyright: " + Copyright
);
348 // ALL leaf modules must be of the same Module Type, if not,
349 // print an error and exit.
350 if (header
.getModuleType() != leafMsa
.getMsaHeader().getModuleType()) {
351 System
.out
.println("ERROR: Module Types different!");
352 System
.out
.println(" Expected: " + header
.getModuleType());
353 System
.out
.println(" " + leafFilename
+ " ModuleType: " + leafMsa
.getMsaHeader().getModuleType());
354 System
.out
.println("Merge ABORTED!");
358 // Combine the Abstract and Descriptions into a single
359 // description entry, prefixing each with the Leaf MSA filename,
360 // so you know which description is from which Leaf module.
361 Description
+= " -- " + leafFilename
+ " -- \n Abstract: "
362 + leafMsa
.getMsaHeader().getAbstract().toString() + "\n Description: "
363 + leafMsa
.getMsaHeader().getDescription().toString() + "\n";
365 // Use the Abstract of the Merged Module to list the Leaf
366 // Module's MSA files.
367 Abstract
+= " -- " + leafFilename
+ " -- \n";
369 // Ignore ClonedFrom right now
372 // Process Supported Architectures
373 // A merged module supports the lowest common set of
375 String testArch
= "";
376 if (leafMsa
.getModuleDefinitions().getSupportedArchitectures() == null) {
378 .println("Module " + leafFilename
+ " does not have the Supported Architectures defined!");
379 System
.out
.println("Supported Architectures is a required element!");
380 System
.out
.println("Merge ABORTED!");
383 testArch
= leafMsa
.getModuleDefinitions().getSupportedArchitectures().toString();
384 String aArch
[] = sArchitectures
.split(" ");
385 for (int ictr
= 0; ictr
< aArch
.length
; ictr
++) {
386 if (!testArch
.contains(aArch
[ictr
])) {
387 sArchitectures
= sArchitectures
.replace(aArch
[ictr
], "");
390 if (sArchitectures
.length() < 2) {
391 System
.out
.println("ERROR: The Leaf Modules' Supported Architectures are mutually exclusive.");
392 System
.out
.println("At least one architecture must be common to all Leaf Modules!");
393 System
.out
.println("Merge Aborting!");
397 // Now start to process the rest of the Leaf Module's MSA files.
398 // We will only test a Leaf module's section if it has data, skipping
400 // As part of this process, we will only create a Library Class Definition
401 // if one was defined, and we will only do it one time.
402 if (leafMsa
.isSetLibraryClassDefinitions()) {
404 // If libClassDefs == null, create a new libClassDefs and add
405 // this module's libClassDefs to the merge Module's
406 // If libClassDefs != null, check that we have only unique LibraryClass entries
407 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
408 // Mark the LibraryClass as ALWAYS_PRODUCED
409 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
410 // Mark the LibraryClass as ALWAYS_CONSUMED
411 // It is permissable to have one PRODUCED and one CONSUMED entry
412 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
413 // and another Leaf uses BY_START, create two entries, one for each.
415 // The RecommendedInstance attributes can be ignored!
417 // First PASS of the TOOL
418 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
420 // Probable Enhancement
421 // The SupArchList, if set, must be for the "Lowest Common Denominator"
423 // First PASS of the TOOL
424 // The SupModuleList must be identical for all Leaf Modules!
425 // Probable Enhancement
426 // The SupModuleList should be combined to include all possible supported module types.
428 // First PASS of the TOOL
429 // Ignore the FeatureFlag - we are not using it now.
430 // Probable Enhancement
431 // FeatureFlags must be identical for each LibraryClass, otherwize fail the Merge
433 // Create the working copy if one does not exist!
434 if (libClassDefs
== null)
435 libClassDefs
= LibraryClassDefinitionsDocument
.Factory
.newInstance()
436 .addNewLibraryClassDefinitions();
438 // Get the Leaf LibraryClassDefinitions Section
439 LibraryClassDefinitions leafLibClassDef
= leafMsa
.getLibraryClassDefinitions();
441 // We only need to test there are entries in the Leaf LibraryClassDefinitions section!
442 if (leafLibClassDef
.getLibraryClassList().size() > 0) {
443 for (int index
= 0; index
< leafLibClassDef
.getLibraryClassList().size(); index
++) {
445 // We can use the Keyword to search to see if the Leaf's Library Class was already
446 // added to the Merge Module.
448 String leafKeyword
= leafLibClassDef
.getLibraryClassList().get(index
).getKeyword()
452 if (leafLibClassDef
.getLibraryClassList().get(index
).getUsage() != null)
453 leafUsage
= leafLibClassDef
.getLibraryClassList().get(index
).getUsage().toString()
456 String leafSupArchList
= "";
457 if (leafLibClassDef
.getLibraryClassList().get(index
).getSupArchList() != null)
458 leafSupArchList
= leafLibClassDef
.getLibraryClassList().get(index
).getSupArchList()
461 String leafSupModuleList
= "";
462 if (leafLibClassDef
.getLibraryClassList().get(index
).getSupModuleList() != null)
463 leafSupModuleList
= leafLibClassDef
.getLibraryClassList().get(index
).getSupModuleList()
466 test
= checkDuplicateStrings(leafKeyword
, aLibClassDefs
);
467 if (test
.length() > 0) {
468 // The checkDuplicateStrings returns "" if a duplicate was found.
469 // Here, the Leaf LibraryClass gets entered because the Keyword was not found.
470 // No more testing is required, since this is the first instance of the LibraryClass
471 libClassDefs
.addNewLibraryClass();
472 libClassDefs
.setLibraryClassArray(libraryClassIndex
++,
473 leafLibClassDef
.getLibraryClassList().get(index
));
475 // The Merged Module has already specified the Library Class
476 // Check ATTRIBUTES, following the rules above.
477 // Since we cannot get the LibraryClass entry using the Keyword, we have to search
478 // all of the Merged Module's LibraryClass statements until we find a match.
479 // Also, we may have more than one LibraryClass with the same Keyword, but different
480 // Usage, SupArchList, FeatureFlag or SupModuleList
481 for (int nidx
= 0; nidx
< libraryClassIndex
; nidx
++) {
482 String mergeKeyword
= libClassDefs
.getLibraryClassList().get(nidx
).getKeyword()
485 if (leafKeyword
.contentEquals(mergeKeyword
)) {
486 // We have the FIRST match, let's check usage, remember, we can have more than one LibraryClass Keyword.
487 mergeUsage
= libClassDefs
.getLibraryClassList().get(nidx
).getUsage().toString()
489 // If the usage is identical, check the SupArchList next
490 if (!leafUsage
.contentEquals(mergeUsage
)) {
491 if (checkUsage().trim().contains("DIFFERENT")) {
492 // See if there is another entry for PRODUCED or CONSUME
493 int anotherLC
= NOTFOUND
;
494 for (int iidx
= nidx
+ 1; iidx
< libraryClassIndex
; iidx
++) {
495 String innerTestKeyword
= libClassDefs
.getLibraryClassList()
496 .get(iidx
).getKeyword()
498 if (leafKeyword
.contentEquals(innerTestKeyword
)) {
500 mergeUsage
= libClassDefs
.getLibraryClassList().get(iidx
)
501 .getUsage().toString().trim();
502 if (checkProduced()) {
504 .getLibraryClassList()
507 org
.tianocore
.UsageTypes
.ALWAYS_PRODUCED
);
509 // Both Usage types are CONSUMED
510 if (checkConsumed()) {
512 .getLibraryClassList()
515 org
.tianocore
.UsageTypes
.ALWAYS_CONSUMED
);
517 if (((mergeUsage
.contains("TO_START")) && (leafUsage
518 .contains("TO_START"))))
520 if (((mergeUsage
.contains("BY_START")) && (leafUsage
521 .contains("BY_START"))))
525 if (anotherLC
== NOTFOUND
) {
526 // we need to add the leaf Library Class
527 libClassDefs
.addNewLibraryClass();
529 .setLibraryClassArray(
532 .getLibraryClassList()
537 // Both Usage types are PRODUCED
538 if (checkUsage().trim().contains("PRODUCED")) {
539 libClassDefs
.getLibraryClassList().get(nidx
)
540 .setUsage(org
.tianocore
.UsageTypes
.ALWAYS_PRODUCED
);
542 // Both Usage types are CONSUMED
543 if (checkUsage().trim().contains("CONSUMED")) {
544 libClassDefs
.getLibraryClassList().get(nidx
)
545 .setUsage(org
.tianocore
.UsageTypes
.ALWAYS_CONSUMED
);
548 // Usage testing completed
550 String mergeSupArchList
= "";
551 if (libClassDefs
.getLibraryClassList().get(nidx
).getSupArchList() != null)
552 mergeSupArchList
= libClassDefs
.getLibraryClassList().get(nidx
)
553 .getSupArchList().toString().trim();
554 if (!mergeSupArchList
.equalsIgnoreCase(leafSupArchList
)) {
556 .println("ERROR: Library Class, keyword: " + leafKeyword
557 + " defines a different set of supported architectures.");
559 .println("Version 0.1 of the merge tool requires that they must be identical!");
560 System
.out
.println("First instance of the Library used: "
562 System
.out
.println("While this module, " + leafFilename
+ " uses: "
564 System
.out
.println("Merge ABORTED!");
567 // Architecture Testing completed
568 // Check SupModuleType
569 String mergeSupModuleList
= "";
570 if (libClassDefs
.getLibraryClassList().get(nidx
).getSupModuleList() != null)
571 mergeSupModuleList
= libClassDefs
.getLibraryClassList().get(nidx
)
572 .getSupModuleList().toString().trim();
573 if (!mergeSupModuleList
.equalsIgnoreCase(leafSupModuleList
)) {
574 System
.out
.println("ERROR: Library Class, keyword: " + leafKeyword
575 + " defines a different set of supported modules.");
577 .println("Version 0.1 of the merge tool requires that they must be identical!");
578 System
.out
.println("First instance of the Library used: "
579 + mergeSupModuleList
);
580 System
.out
.println("While this module, " + leafFilename
+ " uses: "
581 + leafSupModuleList
);
582 System
.out
.println("Merge ABORTED!");
585 // Supported Module Testing completed
586 // Check FeatureFlage
587 // Next version, not this one.
589 } // end of processing of duplicate Library Class entries
590 } // end duplicate entry
591 } // end of test loop for duplicates
592 } // endif Merge Module LibraryModuleDefinitions existed
593 } // endif of LibraryModuleDefinition Tests
595 if (leafMsa
.isSetSourceFiles()) {
596 // TODO: test for NULL settings
597 // Add Sourcefiles to the Merge Module. NOTE: ONLY MODIFY THE Filename, prepending the path to the MSA file.
598 // First get the path portion of the leafMSA file, which will be prepended to the filename
599 // everything else stays intact.
600 if (mergeSourceFiles
== null)
601 mergeSourceFiles
= SourceFilesDocument
.Factory
.newInstance().addNewSourceFiles();
603 String pathToMsa
= getPathPartOfLeafMsa(leafFilename
);
605 System
.out
.println("PATH TO SOURCE FILES: " + pathToMsa
);
606 if (leafMsa
.getSourceFiles().getFilenameList() != null) {
607 List
<FilenameDocument
.Filename
> leafSourceFiles
= leafMsa
.getSourceFiles().getFilenameList();
608 for (int index
= 0; index
< leafSourceFiles
.size(); index
++) {
609 String leafFile
= leafSourceFiles
.get(index
).getStringValue().toString();
610 leafFile
= pathToMsa
+ leafFile
;
611 leafSourceFiles
.get(index
).setStringValue(leafFile
);
612 mergeSourceFiles
.addNewFilename();
613 mergeSourceFiles
.setFilenameArray(sourceFileIndex
++, leafSourceFiles
.get(index
));
618 if (leafMsa
.isSetPackageDependencies()) {
620 // If mergePackageDependencies == null, create a new mergePackageDependencies and
621 // add the leaf module's Package Dependencies section to the merge Module's
622 // If mergePackageDependencies != null, test the leaf Package entries against
623 // what has already been added to the mergePackageDependencies data structure.
625 // Add Unique Package entries.
626 // For this Merge Tool a Package is defined as PackageGuid
628 // ABORT THE MERGE WITH FAIL if the PACKAGE VERSION NUMBERS ARE DIFFERENT
629 // between Leaf modules
631 // Version 0.1 of the tool
632 // SupArchList, if it exists, must be identical for all Leaf Modules
633 // Probable Enhancement
634 // Just specify the lowest common denominator
636 // Create the working copy if one does not exist!
637 // TODO: CODE GOES HERE
638 if (mergePackageDependencies
== null)
639 mergePackageDependencies
= PackageDependenciesDocument
.Factory
.newInstance()
640 .addNewPackageDependencies();
642 PackageDependencies leafPackageDependencies
= leafMsa
.getPackageDependencies();
643 if (leafPackageDependencies
.sizeOfPackageArray() > 0) {
644 for (int index
= 0; index
< leafPackageDependencies
.sizeOfPackageArray(); index
++) {
645 String packageGuid
= leafPackageDependencies
.getPackageArray(index
).getPackageGuid();
646 String test
= checkDuplicateStrings(packageGuid
, aPackageList
);
647 if (test
.length() > 0) {
648 mergePackageDependencies
.addNewPackage();
649 mergePackageDependencies
650 .setPackageArray(packageDependenciesIndex
++,
651 leafPackageDependencies
.getPackageArray(index
));
655 } // endif PackageDependencies
657 if (leafMsa
.isSetProtocols()) {
659 // TEST FOR NULL SETTINGS so we don't get an error!
660 // Add Usage Merging routines
662 // If mergeProtocols == null, create a new mergeProtocols and add
663 // leaf module's Protocols section to the merge Module's
665 // Keep ALL Protocol entries before ProtocolNotify entries!
667 // If mergeProtocols != null, check that we have only unique Protocol and ProtocolNotify entries
668 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
669 // Mark the Protocol or ProtocolNotify as ALWAYS_PRODUCED
670 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
671 // Mark the Protocol or ProtocolNotify as ALWAYS_CONSUMED
672 // It is permissable to have one PRODUCED and one CONSUMED entry
673 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
674 // and another Leaf uses BY_START, create two entries, one for each.
676 // First PASS of the TOOL
677 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
679 // Probable Enhancement
680 // The SupArchList, if set, must be for the "Lowest Common Denominator"
682 // First PASS of the TOOL
683 // Ignore the FeatureFlag - we are not using it now.
684 // Probable Enhancement
685 // FeatureFlags must be identical for each unique Protocol or ProtocolNotify Entry, otherwise fail the Merge
688 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
689 // is the leaf Module's path and filename to the MSA file!
691 // Create the working copy if one does not exist!
693 if (mergeProtocols
== null)
694 mergeProtocols
= ProtocolsDocument
.Factory
.newInstance().addNewProtocols();
696 Protocols leafProtocols
= leafMsa
.getProtocols();
697 // Handle Protocol Entries First
698 if (leafProtocols
.sizeOfProtocolArray() > 0) {
699 for (int index
= 0; index
< leafProtocols
.sizeOfProtocolArray(); index
++) {
700 String protocolCName
= leafProtocols
.getProtocolArray(index
).getProtocolCName();
701 String test
= checkDuplicateStrings(protocolCName
, aProtocolList
);
702 if (test
.length() > 0) {
704 mergeProtocols
.addNewProtocol();
705 mergeProtocols
.setProtocolArray(protocolIndex
++, leafProtocols
.getProtocolArray(index
));
707 // Found an existing protocol
708 leafUsage
= leafProtocols
.getProtocolArray(index
).getUsage().toString().trim();
709 for (int nidx
= 0; nidx
< protocolIndex
; nidx
++) {
710 if (mergeProtocols
.getProtocolArray(nidx
).getProtocolCName()
711 .contains(protocolCName
)) {
712 // Found one entry that matches.
713 mergeUsage
= mergeProtocols
.getProtocolArray(nidx
).getUsage().toString().trim();
714 if (!mergeUsage
.contentEquals(leafUsage
)) {
715 // Usages are different
716 if (checkUsage().trim().contains("DIFFERENT")) {
717 // We need to check to see if there's another entry
718 int anotherProtocol
= NOTFOUND
;
719 for (int iidx
= nidx
+ 1; iidx
< protocolIndex
; iidx
++) {
721 if (mergeProtocols
.getProtocolArray(iidx
).getUsage().toString()
722 .trim().contains(protocolCName
)) {
723 anotherProtocol
= FOUND
;
724 mergeUsage
= libClassDefs
.getLibraryClassList().get(iidx
)
725 .getUsage().toString().trim();
726 if (checkProduced()) {
728 .getProtocolArray(nidx
)
730 org
.tianocore
.UsageTypes
.ALWAYS_PRODUCED
);
731 anotherProtocol
= FOUND
;
733 // Both Usage types are CONSUMED
734 if (checkConsumed()) {
736 .getProtocolArray(nidx
)
738 org
.tianocore
.UsageTypes
.ALWAYS_CONSUMED
);
739 anotherProtocol
= FOUND
;
741 if (((mergeUsage
.contains("TO_START")) && (leafUsage
742 .contains("TO_START"))))
743 anotherProtocol
= FOUND
;
744 if (((mergeUsage
.contains("BY_START")) && (leafUsage
745 .contains("BY_START"))))
746 anotherProtocol
= FOUND
;
749 if (anotherProtocol
== NOTFOUND
) {
750 mergeProtocols
.addNewProtocol();
755 .getProtocolArray(index
));
758 // usage types are either both PRODUCED or CONSUMED
760 mergeProtocols
.getProtocolArray(nidx
)
761 .setUsage(org
.tianocore
.UsageTypes
.ALWAYS_PRODUCED
);
763 mergeProtocols
.getProtocolArray(nidx
)
764 .setUsage(org
.tianocore
.UsageTypes
.ALWAYS_CONSUMED
);
768 } // end of Usage Test
773 // Handle ProtocolNotify Entries Second
774 if (leafProtocols
.sizeOfProtocolNotifyArray() > 0) {
775 for (int index
= 0; index
< leafProtocols
.sizeOfProtocolNotifyArray(); index
++) {
776 String protocolNotifyCName
= leafProtocols
.getProtocolNotifyArray(index
)
777 .getProtocolNotifyCName();
778 String test
= checkDuplicateStrings(protocolNotifyCName
, aProtocolNotifyList
);
779 if (test
.length() > 0) {
780 mergeProtocols
.addNewProtocolNotify();
781 mergeProtocols
.setProtocolNotifyArray(protocolNotifyIndex
++,
782 leafProtocols
.getProtocolNotifyArray(index
));
784 // We have an existing ProtocolNotify Entry
785 leafUsage
= leafProtocols
.getProtocolNotifyArray(index
).getUsage().toString().trim();
786 for (int nidx
= 0; nidx
< protocolIndex
; nidx
++) {
787 if (mergeProtocols
.getProtocolNotifyArray(nidx
).getProtocolNotifyCName()
788 .contains(protocolNotifyCName
)) {
789 // Found one entry that matches.
790 mergeUsage
= mergeProtocols
.getProtocolNotifyArray(nidx
).getUsage().toString().trim();
791 if (!mergeUsage
.contentEquals(leafUsage
)) {
792 // Usages are different
793 if (checkUsage().trim().contains("DIFFERENT")) {
794 // We need to check to see if there's another entry
795 int anotherProtocol
= NOTFOUND
;
796 for (int iidx
= nidx
+ 1; iidx
< protocolIndex
; iidx
++) {
798 if (mergeProtocols
.getProtocolNotifyArray(iidx
).getUsage().toString()
799 .trim().contains(protocolNotifyCName
)) {
800 anotherProtocol
= FOUND
;
801 mergeUsage
= libClassDefs
.getLibraryClassList().get(iidx
)
802 .getUsage().toString().trim();
803 if (checkProduced()) {
805 .getProtocolNotifyArray(nidx
)
807 org
.tianocore
.UsageTypes
.ALWAYS_PRODUCED
);
808 anotherProtocol
= FOUND
;
810 // Both Usage types are CONSUMED
811 if (checkConsumed()) {
813 .getProtocolNotifyArray(nidx
)
815 org
.tianocore
.UsageTypes
.ALWAYS_CONSUMED
);
816 anotherProtocol
= FOUND
;
818 if (((mergeUsage
.contains("TO_START")) && (leafUsage
819 .contains("TO_START"))))
820 anotherProtocol
= FOUND
;
821 if (((mergeUsage
.contains("BY_START")) && (leafUsage
822 .contains("BY_START"))))
823 anotherProtocol
= FOUND
;
826 if (anotherProtocol
== NOTFOUND
) {
827 mergeProtocols
.addNewProtocolNotify();
829 .setProtocolNotifyArray(
830 protocolNotifyIndex
++,
832 .getProtocolNotifyArray(index
));
835 // usage types are either both PRODUCED or CONSUMED
837 mergeProtocols
.getProtocolNotifyArray(nidx
)
838 .setUsage(org
.tianocore
.UsageTypes
.ALWAYS_PRODUCED
);
840 mergeProtocols
.getProtocolNotifyArray(nidx
)
841 .setUsage(org
.tianocore
.UsageTypes
.ALWAYS_CONSUMED
);
845 } // end of Usage Test
846 } // end of Usage test
852 if (leafMsa
.isSetEvents()) {
853 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
855 // "Unique" Entries are based on EventsTypes:EventGuidCName attributes
856 // NOTE: The EventGuidCName can appear once and only once in a CreateEvents Section
857 // The SAME EventGuidCName can appear once and only once in the SignalEvents Section
858 // Two EventGuidCName entries, one in CreateEvents the other in SignalEvents IS PERMITTED!
860 // If mergeEvents == null, create a new mergeEvents and add
861 // leaf module's Events section to the merge Module's
863 // Keep ALL CreateEvents entries before SignalEvents entries!
865 // If mergeEvents != null, check that we have only unique CreateEvents and SignalEvents entries
866 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
867 // Mark the CreateEvents.EventTypes or SignalEvents.EventTypes as ALWAYS_PRODUCED
868 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
869 // Mark the CreateEvents.EventTypes or SignalEvents.EventTypes as ALWAYS_CONSUMED
870 // It is permissable to have one PRODUCED and one CONSUMED entry
871 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
872 // and another Leaf uses BY_START, create two entries, one for each.
874 // First PASS of the TOOL
875 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
877 // Probable Enhancement
878 // The SupArchList, if set, must be for the "Lowest Common Denominator"
880 // First PASS of the TOOL
881 // Ignore the FeatureFlag - we are not using it now.
882 // Probable Enhancement
883 // FeatureFlags must be identical for each unique EventTypes, otherwise fail the Merge
885 // The EventTypes.EventType elements must be identical for all instances of
886 // the EventGuidCName FAIL THE MERGE WITH ERROR indicating the Leaf file name that
891 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
892 // is the leaf Module's path and filename to the MSA file!
894 // Create the working copy if one does not exist!
895 // TODO: Code goes here
897 if (mergeCreateEvents
== null)
898 mergeCreateEvents
= EventsDocument
.Events
.CreateEvents
.Factory
.newInstance();
900 Events leafEvents
= leafMsa
.getEvents();
901 if (leafEvents
.getCreateEvents() != null) {
902 Events
.CreateEvents leafCreateEvents
= leafEvents
.getCreateEvents();
903 if (leafCreateEvents
.sizeOfEventTypesArray() > 0) {
904 for (int index
= 0; index
< leafCreateEvents
.sizeOfEventTypesArray(); index
++) {
905 String EventGuidCName
= leafCreateEvents
.getEventTypesArray(index
).getEventGuidCName();
906 String test
= checkDuplicateStrings(EventGuidCName
, aCreateEventsList
);
907 if (test
.length() > 0) {
908 mergeCreateEvents
.addNewEventTypes();
909 mergeCreateEvents
.setEventTypesArray(createEventIndex
++,
910 leafEvents
.getCreateEvents()
911 .getEventTypesArray(index
));
918 if (mergeSignalEvents
== null)
919 mergeSignalEvents
= EventsDocument
.Events
.SignalEvents
.Factory
.newInstance();
921 if (leafEvents
.getSignalEvents() != null) {
922 Events
.SignalEvents leafSignalEvents
= leafEvents
.getSignalEvents();
923 if (leafSignalEvents
.sizeOfEventTypesArray() > 0) {
924 for (int index
= 0; index
< leafSignalEvents
.sizeOfEventTypesArray(); index
++) {
925 String EventGuidCName
= leafSignalEvents
.getEventTypesArray(index
).getEventGuidCName();
926 String test
= checkDuplicateStrings(EventGuidCName
, aSignalEventsList
);
927 if (test
.length() > 0) {
928 mergeSignalEvents
.addNewEventTypes();
929 mergeSignalEvents
.setEventTypesArray(signalEventIndex
++,
930 leafEvents
.getSignalEvents()
931 .getEventTypesArray(index
));
938 if (leafMsa
.isSetHobs()) {
939 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
941 // "Unique" Entries are based on Hobs.HobTypes:HobGuidCName attribute
943 // If mergeHobs == null, create a new mergeHobs and add
944 // leaf module's Hobs section to the merge Module's
947 // If mergeHobs != null, check that we have only unique Hobs.HobTypes entries
948 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
949 // Mark the Hobs.HobTypes as ALWAYS_PRODUCED
950 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
951 // Mark the Hobs.HobTypes as ALWAYS_CONSUMED
952 // It is permissable to have one PRODUCED and one CONSUMED entry
953 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
954 // and another Leaf uses BY_START, create two entries, one for each.
956 // First PASS of the TOOL
957 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
959 // Probable Enhancement
960 // The SupArchList, if set, must be for the "Lowest Common Denominator"
962 // First PASS of the TOOL
963 // Ignore the FeatureFlag - we are not using it now.
964 // Probable Enhancement
965 // FeatureFlags must be identical for each unique HobTypes element, otherwise fail the Merge
967 // The HobTypes.HobType elements must be identical for all instances of
968 // the HobGuidCName FAIL THE MERGE WITH ERROR indicating the Leaf file name that
973 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
974 // is the leaf Module's path and filename to the MSA file!
976 // Create the working copy if one does not exist!
977 // TODO: Code goes here
978 if (mergeHobs
== null)
979 mergeHobs
= HobsDocument
.Factory
.newInstance().addNewHobs();
981 Hobs leafHobs
= leafMsa
.getHobs();
982 if (leafHobs
.sizeOfHobTypesArray() > 0) {
983 for (int index
= 0; index
< leafHobs
.sizeOfHobTypesArray(); index
++) {
984 String hobGuidCName
= leafHobs
.getHobTypesArray(index
).getHobType().toString();
985 String test
= checkDuplicateStrings(hobGuidCName
, aHobsList
);
986 if (test
.length() > 0) {
987 mergeHobs
.addNewHobTypes();
988 mergeHobs
.setHobTypesArray(hobsIndex
++, leafHobs
.getHobTypesArray(index
));
994 if (leafMsa
.isSetPPIs()) {
995 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
997 // Keep only Unique Ppi or PpiNotify elements, based on the PpiCName and PpiNotifyCName respectively.
999 // If mergePpi == null, create a new mergePpi and add
1000 // leaf module's PPIs section to the merge Module's
1002 // Keep ALL Ppi entries before PpiNotify entries!
1004 // If mergePpi != null, check that we have only unique Ppi and PpiNotify entries
1005 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
1006 // Mark the Ppi or PpiNotify as ALWAYS_PRODUCED
1007 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
1008 // Mark the Ppi or PpiNotify as ALWAYS_CONSUMED
1009 // It is permissable to have one PRODUCED and one CONSUMED entry
1010 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
1011 // and another Leaf uses BY_START, create two entries, one for each.
1013 // First PASS of the TOOL
1014 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1015 // this as an error!
1016 // Probable Enhancement
1017 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1019 // First PASS of the TOOL
1020 // Ignore the FeatureFlag - we are not using it now.
1021 // Probable Enhancement
1022 // FeatureFlags must be identical for each unique Ppi or PpiNotify Entry, otherwise fail the Merge
1025 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
1026 // is the leaf Module's path and filename to the MSA file!
1028 // Create the working copy if one does not exist!
1029 // TODO: Code Goes Here!
1030 if (mergePpis
== null)
1031 mergePpis
= PPIsDocument
.Factory
.newInstance().addNewPPIs();
1033 PPIs leafPPIs
= leafMsa
.getPPIs();
1034 // Handle the PPI Entries First
1035 if (leafPPIs
.sizeOfPpiArray() > 0) {
1036 for (int index
= 0; index
< leafPPIs
.sizeOfPpiArray(); index
++) {
1037 String ppiCName
= leafPPIs
.getPpiArray(index
).getPpiCName();
1038 String test
= checkDuplicateStrings(ppiCName
, aPpiList
);
1039 if (test
.length() > 0) {
1040 mergePpis
.addNewPpi();
1041 mergePpis
.setPpiArray(ppiIndex
++, leafPPIs
.getPpiArray(index
));
1046 // Handle the PpiNotify Second
1047 if (leafPPIs
.sizeOfPpiNotifyArray() > 0) {
1048 for (int index
= 0; index
< leafPPIs
.sizeOfPpiNotifyArray(); index
++) {
1049 String ppiNotifyCName
= leafPPIs
.getPpiNotifyArray(index
).getPpiNotifyCName();
1050 String test
= checkDuplicateStrings(ppiNotifyCName
, aPpiNotifyList
);
1051 if (test
.length() > 0) {
1052 mergePpis
.addNewPpiNotify();
1053 mergePpis
.setPpiNotifyArray(ppiNotifyIndex
++, leafPPIs
.getPpiNotifyArray(index
));
1060 if (leafMsa
.isSetVariables()) {
1061 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1063 // Keep only Unique Variable elements, based on the VariableName element.
1065 // If mergeVariables == null, create a new mergeVariables and add
1066 // leaf module's Variables section to the merge Module's
1068 // If mergeVariables != null, check that we have only unique Variable entries
1069 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
1070 // Mark the Variable as ALWAYS_PRODUCED
1071 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
1072 // Mark the Variable as ALWAYS_CONSUMED
1073 // It is permissable to have one PRODUCED and one CONSUMED entry
1074 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
1075 // and another Leaf uses BY_START, create two entries, one for each.
1077 // First PASS of the TOOL
1078 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1079 // this as an error!
1080 // Probable Enhancement
1081 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1083 // First PASS of the TOOL
1084 // Ignore the FeatureFlag - we are not using it now.
1085 // Probable Enhancement
1086 // FeatureFlags must be identical for each unique Variable entry, otherwise fail the Merge
1089 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
1090 // is the leaf Module's path and filename to the MSA file!
1092 // Create the working copy if one does not exist!
1093 // TODO: Code Goes Here!
1094 if (mergeVariables
== null)
1095 mergeVariables
= VariablesDocument
.Factory
.newInstance().addNewVariables();
1097 Variables leafVariables
= leafMsa
.getVariables();
1098 if (leafVariables
.sizeOfVariableArray() > 0) {
1099 for (int index
= 0; index
< leafVariables
.sizeOfVariableArray(); index
++) {
1100 String variableGuidCName
= leafVariables
.getVariableArray(index
).getGuidCName();
1101 String test
= checkDuplicateStrings(variableGuidCName
, aVariablesList
);
1102 if (test
.length() > 0) {
1103 mergeVariables
.addNewVariable();
1105 .setVariableArray(variablesIndex
++, leafVariables
.getVariableArray(index
));
1112 if (leafMsa
.isSetBootModes()) {
1113 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1115 // Keep only Unique BootMode elements, based on the BootModeName Attribute.
1117 // If mergeBootModes == null, create a new mergeBootModes and add
1118 // leaf module's BootModes section to the merge Module's
1120 // If mergeBootModes != null, check that we have only unique BootMode entries
1121 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
1122 // Mark the BootMode as ALWAYS_PRODUCED
1123 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
1124 // Mark the BootMode as ALWAYS_CONSUMED
1125 // It is permissable to have one PRODUCED and one CONSUMED entry
1126 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
1127 // and another Leaf uses BY_START, create two entries, one for each.
1129 // First PASS of the TOOL
1130 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1131 // this as an error!
1132 // Probable Enhancement
1133 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1135 // First PASS of the TOOL
1136 // Ignore the FeatureFlag - we are not using it now.
1137 // Probable Enhancement
1138 // FeatureFlags must be identical for each unique BootMode entry, otherwise fail the Merge
1141 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
1142 // is the leaf Module's path and filename to the MSA file!
1144 // Create the working copy if one does not exist!
1145 // TODO: Code Goes Here!
1146 if (mergeBootModes
== null)
1147 mergeBootModes
= BootModesDocument
.Factory
.newInstance().addNewBootModes();
1149 BootModes leafBootModes
= leafMsa
.getBootModes();
1150 if (leafBootModes
.sizeOfBootModeArray() > 0) {
1151 for (int index
= 0; index
< leafBootModes
.sizeOfBootModeArray(); index
++) {
1152 String bootModeName
= leafBootModes
.getBootModeArray(index
).getBootModeName().toString();
1153 String test
= checkDuplicateStrings(bootModeName
, aBootModesList
);
1154 if (test
.length() > 0) {
1155 mergeBootModes
.addNewBootMode();
1157 .setBootModeArray(bootModesIndex
++, leafBootModes
.getBootModeArray(index
));
1164 if (leafMsa
.isSetSystemTables()) {
1165 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1167 // Keep only Unique SystemTableCNames elements, based on the SystemTableCName element.
1169 // If mergeSystemTables == null, create a new mergeSystemTables and add
1170 // leaf module's Variables section to the merge Module's
1172 // If mergeSystemTables != null, check that we have only unique SystemTableCNames entries
1173 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
1174 // Mark the SystemTableCName as ALWAYS_PRODUCED
1175 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
1176 // Mark the SystemTableCName as ALWAYS_CONSUMED
1177 // It is permissable to have one PRODUCED and one CONSUMED entry
1178 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
1179 // and another Leaf uses BY_START, create two entries, one for each.
1181 // First PASS of the TOOL
1182 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1183 // this as an error!
1184 // Probable Enhancement
1185 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1187 // First PASS of the TOOL
1188 // Ignore the FeatureFlag - we are not using it now.
1189 // Probable Enhancement
1190 // FeatureFlags must be identical for each unique SystemTableCNames entry, otherwise fail the Merge
1193 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
1194 // is the leaf Module's path and filename to the MSA file!
1196 // Create the working copy if one does not exist!
1197 // TODO: Code Goes Here!
1198 if (mergeSystemTables
== null)
1199 mergeSystemTables
= SystemTablesDocument
.Factory
.newInstance().addNewSystemTables();
1201 SystemTables leafSystemTables
= leafMsa
.getSystemTables();
1202 if (leafSystemTables
.sizeOfSystemTableCNamesArray() > 0) {
1203 for (int index
= 0; index
< leafSystemTables
.sizeOfSystemTableCNamesArray(); index
++) {
1204 String systemTableCName
= leafSystemTables
.getSystemTableCNamesArray(index
)
1205 .getSystemTableCName();
1206 String test
= checkDuplicateStrings(systemTableCName
, aSystemTablesList
);
1207 if (test
.length() > 0) {
1208 mergeSystemTables
.addNewSystemTableCNames();
1210 .setSystemTableCNamesArray(
1213 .getSystemTableCNamesArray(index
));
1218 }// endif SystemTables
1220 if (leafMsa
.isSetDataHubs()) {
1221 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1223 // Keep only Unique DataHubs elements, based on the DataHubRecord.DataHubCName element.
1225 // If mergeDataHubs == null, create a new mergeDataHubs and add
1226 // leaf module's DataHubs section to the merge Module's
1228 // If mergeDataHubs != null, check that we have only unique DataHubRecord entries
1229 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
1230 // Mark the DataHubCName as ALWAYS_PRODUCED
1231 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
1232 // Mark the DataHubCName as ALWAYS_CONSUMED
1233 // It is permissable to have one PRODUCED and one CONSUMED entry
1234 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
1235 // and another Leaf uses BY_START, create two entries, one for each.
1237 // First PASS of the TOOL
1238 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1239 // this as an error!
1240 // Probable Enhancement
1241 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1243 // First PASS of the TOOL
1244 // Ignore the FeatureFlag - we are not using it now.
1245 // Probable Enhancement
1246 // FeatureFlags must be identical for each unique DataHubRecord entry, otherwise fail the Merge
1249 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
1250 // is the leaf Module's path and filename to the MSA file!
1252 // Create the working copy if one does not exist!
1253 // TODO: Code Goes Here!
1254 if (mergeDataHubs
== null)
1255 mergeDataHubs
= DataHubsDocument
.Factory
.newInstance().addNewDataHubs();
1257 DataHubs leafDataHubs
= leafMsa
.getDataHubs();
1258 if (leafDataHubs
.sizeOfDataHubRecordArray() > 0) {
1259 for (int index
= 0; index
< leafDataHubs
.sizeOfDataHubRecordArray(); index
++) {
1260 String dataHubCName
= leafDataHubs
.getDataHubRecordArray(index
).getDataHubCName();
1261 String test
= checkDuplicateStrings(dataHubCName
, aDataHubsList
);
1262 if (test
.length() > 0) {
1263 mergeDataHubs
.addNewDataHubRecord();
1264 mergeDataHubs
.setDataHubRecordArray(dataHubsIndex
++,
1265 leafDataHubs
.getDataHubRecordArray(index
));
1272 if (leafMsa
.isSetHiiPackages()) {
1273 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1275 // Keep only Unique HiiPackage elements, based on the HiiPackage.HiiCName element.
1277 // If mergeHiiPackages == null, create a new mergeHiiPackages and add
1278 // leaf module's DataHubs section to the merge Module's
1280 // If mergeHiiPackages != null, check that we have only unique HiiPackage entries
1281 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
1282 // Mark the HiiPackage as ALWAYS_PRODUCED
1283 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
1284 // Mark the HiiPackage as ALWAYS_CONSUMED
1285 // It is permissable to have one PRODUCED and one CONSUMED entry
1286 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
1287 // and another Leaf uses BY_START, create two entries, one for each.
1289 // First PASS of the TOOL
1290 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1291 // this as an error!
1292 // Probable Enhancement
1293 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1295 // First PASS of the TOOL
1296 // Ignore the FeatureFlag - we are not using it now.
1297 // Probable Enhancement
1298 // FeatureFlags must be identical for each unique HiiPackage entry, otherwise fail the Merge
1301 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
1302 // is the leaf Module's path and filename to the MSA file!
1304 // Create the working copy if one does not exist!
1305 // TODO: Code Goes Here!
1306 if (mergeHiiPackages
== null)
1307 mergeHiiPackages
= HiiPackagesDocument
.Factory
.newInstance().addNewHiiPackages();
1309 HiiPackages leafHiiPackages
= leafMsa
.getHiiPackages();
1310 if (leafHiiPackages
.sizeOfHiiPackageArray() > 0) {
1311 for (int index
= 0; index
< leafHiiPackages
.sizeOfHiiPackageArray(); index
++) {
1312 String hiiCName
= leafHiiPackages
.getHiiPackageArray(index
).getHiiCName();
1313 String test
= checkDuplicateStrings(hiiCName
, aHiiPackagesList
);
1314 if (test
.length() > 0) {
1315 mergeHiiPackages
.addNewHiiPackage();
1316 mergeHiiPackages
.setHiiPackageArray(hiiPackageIndex
++,
1317 leafHiiPackages
.getHiiPackageArray(index
));
1322 }// endif HiiPackage
1324 if (leafMsa
.isSetGuids()) {
1325 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1327 // Keep only Unique Guids elements, based on the GuidCNames.GuidCName element.
1329 // If mergeGuids == null, create a new mergeGuids and add
1330 // leaf module's Guids section to the merge Module's
1332 // If mergeGuids != null, check that we have only unique GuidCNames entries
1333 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
1334 // Mark the GuidCNames as ALWAYS_PRODUCED
1335 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
1336 // Mark the GuidCNames as ALWAYS_CONSUMED
1337 // It is permissable to have one PRODUCED and one CONSUMED entry
1338 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
1339 // and another Leaf uses BY_START, create two entries, one for each.
1341 // First PASS of the TOOL
1342 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1343 // this as an error!
1344 // Probable Enhancement
1345 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1347 // First PASS of the TOOL
1348 // Ignore the FeatureFlag - we are not using it now.
1349 // Probable Enhancement
1350 // FeatureFlags must be identical for each unique GuidCNames entry, otherwise fail the Merge
1353 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
1354 // is the leaf Module's path and filename to the MSA file!
1356 // Create the working copy if one does not exist!
1357 // TODO: Code Goes Here!
1358 if (mergeGuids
== null)
1359 mergeGuids
= GuidsDocument
.Factory
.newInstance().addNewGuids();
1361 Guids leafGuids
= leafMsa
.getGuids();
1362 if (leafGuids
.sizeOfGuidCNamesArray() > 0) {
1363 for (int index
= 0; index
< leafGuids
.sizeOfGuidCNamesArray(); index
++) {
1364 String hiiCName
= leafGuids
.getGuidCNamesArray(index
).getGuidCName();
1365 String test
= checkDuplicateStrings(hiiCName
, aGuidsList
);
1366 if (test
.length() > 0) {
1367 mergeGuids
.addNewGuidCNames();
1368 mergeGuids
.setGuidCNamesArray(guidsIndex
++, leafGuids
.getGuidCNamesArray(index
));
1373 }// endif GuidCNames
1375 if (leafMsa
.isSetExterns()) {
1376 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1378 // FAIL THE MERGE if Externs.PcdIsDriver is present
1379 // FAIL THE MERGE if Externs.TianoR8FlashMap_h is TRUE
1381 // Keep only Unique Extern elements, based on the Extern.* elements.
1383 // If mergeExterns == null, create a new mergeExterns and add
1384 // leaf module's Extern section to the merge Module's
1386 // If mergeExterns != null, check that we have only unique Extern.* entries
1388 // After storing the initial LEAF MODULE'S SPECIFICATION SECTION
1389 // ALL other Leaf Modules must declare the exact same specifications
1390 // If they do not, FAIL the MERGE with an error message, printing the
1391 // name of the leaf MSA that did not match, along with
1392 // Expected: from the merge module's specification list
1393 // Got: from the leaf file that fails!
1395 // For Each <Extern>
1396 // For each pair of <ModuleEntryPoint> and/or <ModuleUnloadImage>
1397 // The ModuleUnloadImage value must be identical for an identical pair of ModuleEntryPoint values
1398 // If not, FAIL THE MERGE, giving the current leaf MSA filename as the failure, along with the
1399 // additional error information as follows:
1400 // -- leafFilename --
1401 // ModuleEntryPoint:
1402 // Expected ModuleUnloadImage: fromMergeModule
1403 // Got ModuleUnloadImage: fromLeaf
1405 // More than one <Extern> Section with a pair of <ModuleEntryPoint><ModuleUnloadImage> is allowed
1407 // For each pair of one <Constructor> and/or one <Destructor> elements
1408 // The <Extern> section containing the <Constructor> <Destructor> pairs
1409 // The Destructor value in all leaf modules must be identical for all Constructor elements that are identical.
1410 // More than one <Extern> Section with Constructor/Destructor pair is permitted.
1412 // For each Set four elements, DriverBinding, ComponentName, DriverConfig and DriverDiag,
1413 // 1 DriverBinding and
1414 // 0 or 1 ComponentName and/or
1415 // 0 or 1 DriverConfig and/or
1416 // 0 or 1 DriverDiag
1417 // elements must appear in 1 <Extern> Section.
1419 // A ComponentName cannot be used without a DriverBinding element.
1420 // A DriverConfig element cannot appear without a DriverBinding element.
1421 // A DriverDiag element cannot appear without a DriverBinding element
1422 // These elements are matched within a single <Extern> Section uniquely defined by the DriverBinding element.
1423 // Multiple <Extern> sections of this type are permitted.
1425 // Each pair of SetVirtualAddressMapCallBack and ExitBootServiceCallBack elements MUST
1426 // BE in one Extern Section. ONE AND ONLY ONE of this section is permitted.
1428 // First PASS of the TOOL
1429 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1430 // this as an error!
1431 // Probable Enhancement
1432 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1434 // First PASS of the TOOL
1435 // Ignore the FeatureFlag - we are not using it now.
1436 // Probable Enhancement
1437 // FeatureFlags must be identical for each unique Extern entry, otherwise fail the Merge
1439 // Create the working copy if one does not exist!
1440 // TODO: Code Goes Here!
1441 if (mergeExterns
== null)
1442 mergeExterns
= ExternsDocument
.Factory
.newInstance().addNewExterns();
1444 Externs leafExterns
= leafMsa
.getExterns();
1445 // PCD IS DRIVER NOT ALLOWED IN A MERGED Module
1446 if (leafExterns
.isSetPcdIsDriver()) {
1447 System
.out
.println("The Module: " + leafFilename
+ " is a PCD Driver and CANNOT BE MERGED!");
1448 System
.out
.println("Merge Aborted");
1453 // TIANO R8 FLASHMAP.H NOT ALLOWED IN A MERGED Module
1454 if (leafExterns
.isSetTianoR8FlashMapH()) {
1455 System
.out
.println("The Module: " + leafFilename
1456 + " set the Tiano R8 FlashMap.h Flag and CANNOT BE MERGED!");
1457 System
.out
.println("Merge Aborted");
1462 // Add the Specification Array, one time only.
1463 if (leafExterns
.sizeOfSpecificationArray() > 0) {
1464 for (int index
= 0; index
< leafExterns
.sizeOfSpecificationArray(); index
++) {
1465 String spec
= leafExterns
.getSpecificationArray(index
);
1466 String test
= checkSpecs(spec
, leafFilename
, aSpecArray
);
1467 if (test
.length() > 0) {
1468 mergeExterns
.addNewSpecification();
1469 mergeExterns
.setSpecificationArray(specIndex
++, test
);
1474 if (leafExterns
.sizeOfExternArray() > 0) {
1475 for (int index
= 0; index
< leafExterns
.sizeOfExternArray(); index
++) {
1477 if (leafExterns
.getExternArray(index
).isSetModuleEntryPoint()) {
1478 // ModuleEntryPoint, if an Unload Image is paired with
1479 // the Module Entry point, it will piggy back on the
1480 // Module Entry Point Extern
1481 String moduleEntryPoint
= leafExterns
.getExternArray(index
).getModuleEntryPoint();
1482 test
= checkDuplicateStrings(moduleEntryPoint
, aEntryPointList
);
1484 } else if (leafExterns
.getExternArray(index
).isSetModuleUnloadImage()) {
1485 // Module Unload Image is here in case there is no
1486 // Entry Point - not very typical
1487 String moduleUnloadImage
= leafExterns
.getExternArray(index
).getModuleUnloadImage();
1488 test
= checkDuplicateStrings(moduleUnloadImage
, aUnloadImageList
);
1490 } else if (leafExterns
.getExternArray(index
).isSetConstructor()) {
1491 // Constructors must be unique, if a Destructor is
1492 // paired with a constructor, it will pigback on
1494 String constructor
= leafExterns
.getExternArray(index
).getConstructor();
1495 test
= checkDuplicateStrings(constructor
, aConstructorList
);
1497 } else if (leafExterns
.getExternArray(index
).isSetDestructor()) {
1498 // Destructors must be unique
1499 String destructor
= leafExterns
.getExternArray(index
).getDestructor();
1500 test
= checkDuplicateStrings(destructor
, aDestructorList
);
1502 } else if (leafExterns
.getExternArray(index
).isSetDriverBinding()) {
1503 // Driver Bindings must be unique
1504 // Fixed the MSA files - ComponentName, Driver Config and
1505 // Driver Diag statments must be inside of an Extern that
1506 // has a Driver Binding
1507 String driverBinding
= leafExterns
.getExternArray(index
).getDriverBinding();
1508 test
= checkDuplicateStrings(driverBinding
, aDriverBindingList
);
1510 } else if (leafExterns
.getExternArray(index
).isSetSetVirtualAddressMapCallBack()) {
1511 // Handle Virtual Address Map and Exit Boot Services Call Backs
1512 // in a single Extern if they are present
1513 String virtualAddressMap
= leafExterns
.getExternArray(index
)
1514 .getSetVirtualAddressMapCallBack();
1515 test
= checkDuplicateStrings(virtualAddressMap
, aVirtualAddressMapList
);
1517 } else if (leafExterns
.getExternArray(index
).isSetExitBootServicesCallBack()) {
1518 // Handle a stand alone Exit Boot Services Call Back
1519 String exitBootServices
= leafExterns
.getExternArray(index
)
1520 .getExitBootServicesCallBack();
1521 test
= checkDuplicateStrings(exitBootServices
, aExitBootServicesList
);
1523 // Unknown Extern FAIL - May be an invalid Component Name in it's own Extern Statement
1524 System
.out
.println("Unknown EXTERN defined in Module: " + leafFilename
);
1525 System
.out
.println("Value: " + leafExterns
.getExternArray(index
).toString());
1526 System
.out
.println("Merge Aborted!");
1531 if (test
.length() > 0) {
1532 mergeExterns
.addNewExtern();
1533 mergeExterns
.setExternArray(externsIndex
++, leafExterns
.getExternArray(index
));
1537 }// endif mergeExterns
1539 if (leafMsa
.isSetPcdCoded()) {
1540 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1542 // Keep only Unique PcdCoded elements, based on the PcdCoded.PcdEntry.C_Name element.
1544 // If mergePcdCoded == null, create a new mergePcdCoded and add
1545 // leaf module's PcdCoded section to the merge Module's
1547 // If mergePcdCoded != null, check that we have only unique PcdEntry entries
1548 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,
1549 // Mark the PcdEntry as ALWAYS_PRODUCED
1550 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,
1551 // Mark the PcdEntry as ALWAYS_CONSUMED
1552 // It is permissable to have one PRODUCED and one CONSUMED entry
1553 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START
1554 // and another Leaf uses BY_START, create two entries, one for each.
1556 // First PASS of the TOOL
1557 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting
1558 // this as an error!
1559 // Probable Enhancement
1560 // The SupArchList, if set, must be for the "Lowest Common Denominator"
1562 // First PASS of the TOOL
1563 // Ignore the FeatureFlag - we are not using it now.
1564 // Probable Enhancement
1565 // FeatureFlags must be identical for each unique HiiPackage entry, otherwise fail the Merge
1567 // First PASS of the TOOL
1568 // Ignore the PcdEntry:Usage Attribute
1569 // Probable Enhancment
1570 // Have Usage Combined like was done for the Library Class
1572 // First PASS of the TOOL
1573 // If Different PcdItemTypes, Abort The MERGE
1575 // Probably Enhancement
1576 // The PcdItemType Should be checked using the following rules
1577 // Feature Flag MUST ALWAYS BE A FEATURE FLAG
1578 // If different Item Types occur, mark the PCD as DYNAMIC
1581 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename
1582 // is the leaf Module's path and filename to the MSA file!
1584 // Create the working copy if one does not exist!
1585 // TODO: Code Goes Here!
1586 if (mergePcdCoded
== null)
1587 mergePcdCoded
= PcdCodedDocument
.Factory
.newInstance().addNewPcdCoded();
1589 PcdCoded leafPcdCoded
= leafMsa
.getPcdCoded();
1590 if (leafPcdCoded
.sizeOfPcdEntryArray() > 0) {
1591 for (int index
= 0; index
< leafPcdCoded
.sizeOfPcdEntryArray(); index
++) {
1592 String pcdCName
= leafPcdCoded
.getPcdEntryArray(index
).getCName();
1593 String pcdItemType
= leafPcdCoded
.getPcdEntryArray(index
).getPcdItemType().toString();
1594 String test
= checkPcd(pcdCName
, pcdItemType
, leafFilename
, aPcdCNameList
);
1595 if (test
.length() > 0) {
1596 mergePcdCoded
.addNewPcdEntry();
1597 mergePcdCoded
.setPcdEntryArray(pcdIndex
++, leafPcdCoded
.getPcdEntryArray(index
));
1604 if (leafMsa
.isSetModuleBuildOptions()) {
1605 // TODO: TEST FOR NULL SETTINGS so we don't get an error!
1607 // Any element that appear within a leaf's ModuleBuildOptions should be appended to
1608 // the Merge Module's BuildOptions section.
1610 // NO ATTEMPT IS MADE TO VERIFY UNIQUENESS ON ANYTHING WITHIN THIS SECTION!
1612 // Create the working copy if one does not exist!
1613 // if (mergeBuildOptions == null)
1614 // mergeBuildOptions = ModuleBuildOptionsDocument.Factory.newInstance().addNewModuleBuildOptions();
1616 // ModuleBuildOptions leafModuleBuildOptions = leafMsa.getModuleBuildOptions();
1618 // mergeBuildOptions.addNewModuleBuildOptions();
1619 // mergeBuildOptions.setModuleBuildOptions(leafModuleBuildOptions);
1622 // TODO: Code Goes Here!
1623 } // endif ModuleBuildOptions
1625 // Need to process any UserExtensions here too.
1626 if (leafMsa
.getUserExtensionsList() != null) {
1628 if (mergeUserExtensions
== null)
1629 mergeUserExtensions
= UserExtensionsDocument
.Factory
.newInstance().addNewUserExtensions();
1631 // for (int index = 0; index < leafMsa.getUserExtensionsList().size(); index++)
1635 } // Completed parsing all leaf files.
1637 header
.setAbstract(Abstract
);
1638 header
.setCopyright(Copyright
);
1639 header
.setDescription(Description
);
1640 License mLicense
= License
.Factory
.newInstance();
1641 mLicense
.setStringValue(licenseTxt
);
1642 header
.setLicense(mLicense
);
1643 if ((DEBUG
> 0) || (VERBOSE
> 0))
1644 System
.out
.println("Merged Module supports: " + sArchitectures
+ " architectures.");
1645 List
<String
> lArchitectures
= new ArrayList
<String
>();
1646 String s
[] = sArchitectures
.replace(" ", " ").trim().split(" ");
1647 for (int idx
= 0; idx
< s
.length
; idx
++) {
1648 lArchitectures
.add(s
[idx
]);
1650 System
.out
.println("Adding architecture: " + s
[idx
]);
1652 moduleDefs
.setSupportedArchitectures(lArchitectures
);
1654 } // endif mergeMsaFile == null
1656 if ((uiName
!= null) && (uiName
.length() > 0) && (result
== PASS
)) {
1657 // TODO: Stub for replacing the msaFile UiName
1658 if ((DEBUG
> 0) || (VERBOSE
> 0))
1659 System
.out
.println("Updating the uiName: " + uiName
);
1660 header
.setModuleName(uiName
);
1663 if ((baseName
!= null) && (baseName
.length() > 0) && (result
== PASS
)) {
1664 if ((DEBUG
> 0) || (VERBOSE
> 0))
1665 System
.out
.println("Setting the Output Filename:" + baseName
);
1666 moduleDefs
.setOutputFileBasename(baseName
);
1669 if (result
== PASS
) {
1670 // TODO: Stub to write out the new MSA file
1671 File outMsa
= new File(msaFilename
);
1674 System
.out
.println("SAVING new MSA FILE: " + msaFilename
);
1676 mergeMsaFile
.setMsaHeader(header
);
1677 mergeMsaFile
.setModuleDefinitions(moduleDefs
);
1678 // ALL THE REST OF THE SECTIONS ARE OPTIONAL
1679 // SO check that they are not null before adding them to the merged MSA file!
1680 if (libClassDefs
!= null)
1681 mergeMsaFile
.setLibraryClassDefinitions(libClassDefs
);
1682 if (mergeSourceFiles
!= null)
1683 mergeMsaFile
.setSourceFiles(mergeSourceFiles
);
1684 if (mergePackageDependencies
!= null)
1685 mergeMsaFile
.setPackageDependencies(mergePackageDependencies
);
1686 if (mergeProtocols
!= null)
1687 mergeMsaFile
.setProtocols(mergeProtocols
);
1689 if ((mergeCreateEvents
!= null) || (mergeSignalEvents
!= null)) {
1690 if (mergeEvents
== null)
1691 mergeEvents
= EventsDocument
.Factory
.newInstance().addNewEvents();
1693 if (mergeCreateEvents
.getEventTypesList().size() > 0) {
1694 mergeEvents
.addNewCreateEvents();
1695 mergeEvents
.setCreateEvents(mergeCreateEvents
);
1697 if (mergeSignalEvents
.getEventTypesList().size() > 0) {
1698 mergeEvents
.addNewSignalEvents();
1699 mergeEvents
.setSignalEvents(mergeSignalEvents
);
1702 mergeMsaFile
.setEvents(mergeEvents
);
1705 if (mergeHobs
!= null)
1706 mergeMsaFile
.setHobs(mergeHobs
);
1708 if (mergePpis
!= null)
1709 mergeMsaFile
.setPPIs(mergePpis
);
1711 if (mergeVariables
!= null)
1712 mergeMsaFile
.setVariables(mergeVariables
);
1714 if (mergeBootModes
!= null)
1715 mergeMsaFile
.setBootModes(mergeBootModes
);
1717 if (mergeSystemTables
!= null)
1718 mergeMsaFile
.setSystemTables(mergeSystemTables
);
1720 if (mergeDataHubs
!= null)
1721 mergeMsaFile
.setDataHubs(mergeDataHubs
);
1723 if (mergeHiiPackages
!= null)
1724 mergeMsaFile
.setHiiPackages(mergeHiiPackages
);
1726 if (mergeGuids
!= null)
1727 mergeMsaFile
.setGuids(mergeGuids
);
1729 if (mergeExterns
!= null)
1730 mergeMsaFile
.setExterns(mergeExterns
);
1732 if (mergePcdCoded
!= null)
1733 mergeMsaFile
.setPcdCoded(mergePcdCoded
);
1735 XmlCursor cursor
= XmlConfig
.setupXmlCursor(mergeMsaFile
.newCursor());
1736 XmlOptions options
= XmlConfig
.setupXmlOptions();
1737 ModuleSurfaceAreaDocument msaDoc
= ModuleSurfaceAreaDocument
.Factory
.newInstance();
1738 msaDoc
.addNewModuleSurfaceArea();
1739 msaDoc
.setModuleSurfaceArea(mergeMsaFile
);
1740 msaDoc
.save(outMsa
, options
);
1741 System
.out
.println("The Merged MSA file: " + msaFilename
+ ", has been created!");
1742 } catch (IOException e
) {
1743 System
.out
.println("Problem writing the output file: " + msaFilename
+ " " + e
);
1748 if ((spdFilename
!= null) && (result
== PASS
)) {
1749 // TODO: Stub for adding the msaFile to the <MsaFiles><Filename> in the spdFile
1750 String msaLine
= getPathFromSpd(spdFilename
, msaFilename
);
1751 System
.out
.println("Updating the SPD file (" + spdFilename
+ ") with: " + msaLine
);
1753 File spdFile
= new File(spdFilename
);
1754 PackageSurfaceAreaDocument spdDoc
= PackageSurfaceAreaDocument
.Factory
.parse(spdFile
);
1755 PackageSurfaceArea spd
= spdDoc
.getPackageSurfaceArea();
1757 // MsaFiles mergeMsaFilesForSpd = MsaFilesDocument.Factory.newInstance().addNewMsaFiles();
1758 List
<String
> msaFilenames
= spd
.getMsaFiles().getFilenameList();
1759 msaFilenames
.add(msaLine
);
1760 XmlCursor cursor
= XmlConfig
.setupXmlCursor(spd
.newCursor());
1761 XmlOptions options
= XmlConfig
.setupXmlOptions();
1762 spdDoc
.save(spdFile
, options
);
1763 } catch (IOException e
) {
1764 System
.out
.println("I/O Exception on spd file: " + spdFilename
+ " " + e
);
1765 } catch (XmlException x
) {
1766 System
.out
.println("XML Exception on SPD file: " + spdFilename
+ " " + x
);
1768 } else if ((spdFilename
== null) && (result
== PASS
)) {
1770 System
.out
.println("The file: " + msaFilename
+ ", must be added to a package file before it can be used!");
1775 public ModuleSurfaceArea
getLeafFile(String filename
) {
1776 File leafMsaFile
= new File(filename
);
1777 if ((DEBUG
> 1) || (VERBOSE
> 1))
1778 System
.out
.println("Processing MSA File: " + filename
);
1780 leafMsa
= ModuleSurfaceAreaDocument
.Factory
.parse(leafMsaFile
).getModuleSurfaceArea();
1781 if ((DEBUG
> 4) || (VERBOSE
> 4))
1782 System
.out
.println("Binary: " + leafMsa
.getModuleDefinitions().getBinaryModule());
1783 if (leafMsa
.getModuleDefinitions().getBinaryModule()) {
1784 System
.out
.println("ERROR: Binary Module was specified in MSA: " + filename
);
1785 System
.out
.println("Merge Aborted!");
1789 } catch (IOException e
) {
1790 System
.out
.println("I/O Exception on filename: " + filename
+ " " + e
);
1791 System
.out
.println("Merge Aborted!");
1794 } catch (XmlException x
) {
1795 System
.out
.println("XML Exception reading file: " + filename
+ " " + x
);
1796 System
.out
.println("Merge Aborted!");
1803 private String
getPathFromSpd(String spdFn
, String msaFn
) {
1804 String path2Msa
= null;
1806 spdFn
= spdFn
.replace("\\", "/").trim();
1807 String s
[] = spdFn
.split("/");
1808 String justSpdFilename
= s
[s
.length
- 1];
1810 String Cwd
= System
.getProperty("user.dir");
1811 Cwd
= Cwd
.replace("\\", "/").trim();
1812 if ((DEBUG
> 10) || (VERBOSE
> 10)) {
1813 System
.out
.println("Current directory = " + Cwd
);
1815 String sp
[] = Cwd
.split("/");
1816 int theDirectory
= sp
.length
- (s
.length
- 1);
1818 System
.out
.println("The Directory length: " + theDirectory
+ " s.length: " + s
.length
+ " sp.length: "
1821 String path2Spd
= "";
1822 for (int ictr
= 0; ictr
< theDirectory
; ictr
++) {
1823 path2Spd
+= sp
[ictr
] + "/";
1825 System
.out
.println("Creating path to SPD file: " + path2Spd
);
1828 String testPath2Spd
= path2Spd
+ justSpdFilename
;
1830 File tFile
= new File(testPath2Spd
);
1831 if (!tFile
.exists()) {
1832 System
.out
.println("The specified SPD file, " + spdFn
+ " does not exist at: " + testPath2Spd
);
1833 System
.out
.println("Please use the FrameworkWizard to add this MSA file to the package.");
1836 path2Msa
= Cwd
.replace(path2Spd
, "");
1837 path2Msa
= path2Msa
+ "/" + msaFn
;
1841 private String
checkDuplicateStrings(String aString
, ArrayList
<String
> aList
) {
1843 for (int lctr
= 0; lctr
< aList
.size(); lctr
++) {
1845 System
.out
.println("Comparing: \n" + aString
.replace(" ", "").replace("\n", "") + "\nTo: \n"
1846 + aList
.get(lctr
).replace(" ", "").replace("\n", "").toString().trim());
1847 if (aString
.replace(" ", "").replace("\n", "").contains(
1848 aList
.get(lctr
).replace(" ", "").replace("\n", "")
1849 .toString().trim())) {
1850 if ((DEBUG
> 3) || (VERBOSE
> 3))
1851 System
.out
.println("Found a duplicate String, skipping!");
1855 if ((DEBUG
> 3) || (VERBOSE
> 3))
1856 System
.out
.println("Returning UNIQUE String!\n " + aString
);
1861 private String
checkSpecs(String specName
, String filename
, ArrayList
<String
> aList
) {
1862 // Check Specifications
1863 // Skip of Specs are identical
1864 String spec
[] = new String
[2];
1865 spec
= specName
.replace(" ", " ").trim().split(" ");
1866 String specInMem
[] = new String
[2];
1867 if ((DEBUG
> 10) || (VERBOSE
> 10))
1868 System
.out
.println("Specification: " + specName
);
1870 for (int lctr
= 0; lctr
< aList
.size(); lctr
++) {
1872 System
.out
.println("Comparing: \n" + specName
.replace(" ", "").replace("\n", "") + "\nTo: \n"
1873 + aList
.get(lctr
).replace(" ", "").replace("\n", "").toString().trim());
1874 if (specName
.replace(" ", "").replace("\n", "").contains(
1875 aList
.get(lctr
).replace(" ", "").replace("\n", "")
1876 .toString().trim())) {
1877 if ((DEBUG
> 3) || (VERBOSE
> 3))
1878 System
.out
.println("Found a duplicate String, skipping!");
1881 specInMem
= aList
.get(lctr
).replace(" ", " ").trim().split(" ");
1882 if (spec
[0].contentEquals(specInMem
[0])) {
1883 if (!spec
[1].contains(specInMem
[1])) {
1884 System
.out
.println("Module: " + filename
+ " is coded to " + specName
);
1885 System
.out
.println("Merge needs to be coded to: " + aList
.get(lctr
));
1886 System
.out
.println("Merge Aborted!");
1893 if ((DEBUG
> 3) || (VERBOSE
> 3))
1894 System
.out
.println("Returning Specification: " + specName
);
1895 aList
.add(specName
);
1899 private String
checkPcd(String pcdName
, String itemType
, String filename
, ArrayList
<String
> aList
) {
1901 for (int lctr
= 0; lctr
< aList
.size(); lctr
++) {
1903 System
.out
.println("Comparing: \n" + pcdName
.replace(" ", "").replace("\n", "") + "\nTo: \n"
1904 + aList
.get(lctr
).replace(" ", "").replace("\n", "").toString().trim());
1905 if (pcdName
.replace(" ", "").replace("\n", "").contains(
1906 aList
.get(lctr
).replace(" ", "").replace("\n", "")
1907 .toString().trim())) {
1908 if (!aPcdItemTypeList
.get(lctr
).contains(itemType
)) {
1910 .println("The Pcd Item Type for " + pcdName
+ " in file: " + filename
+ "does not match!");
1911 System
.out
.println("Expected: " + aPcdItemTypeList
.get(lctr
));
1912 System
.out
.println("Was set to: " + itemType
);
1913 System
.out
.println("Merge Aborted!");
1917 if ((DEBUG
> 3) || (VERBOSE
> 3))
1918 System
.out
.println("Found a duplicate String, skipping!");
1922 if ((DEBUG
> 3) || (VERBOSE
> 3))
1923 System
.out
.println("Returning UNIQUE String!\n " + pcdName
);
1924 aPcdItemTypeList
.add(itemType
);
1929 private String
checkUsage() {
1931 // Usage types are different
1932 if (((mergeUsage
.contains("CONSUMED")) && (leafUsage
.contains("PRODUCED")))
1933 || ((mergeUsage
.contains("PRODUCED")) && (leafUsage
.contains("CONSUMED")))
1934 || ((mergeUsage
.contains("TO_START")) && (leafUsage
.contains("BY_START")))
1935 || ((mergeUsage
.contains("BY_START")) && (leafUsage
.contains("TO_START")))) {
1936 result
= "DIFFERENT";
1938 // Both Usage types are PRODUCED
1939 if (((mergeUsage
.contains("ALWAYS_PRODUCED")) && (leafUsage
.contains("SOMETIMES_PRODUCED")))
1940 || ((mergeUsage
.contains("SOMETIMES_PRODUCED")) && (leafUsage
.contains("ALWAYS_PRODUCED")))) {
1941 result
= "PRODUCED";
1944 // Both Usage types are CONSUMED
1945 if (((mergeUsage
.contains("ALWAYS_CONSUMED")) && (leafUsage
.contains("SOMETIMES_CONSUMED")))
1946 || ((mergeUsage
.contains("SOMETIMES_CONSUMED")) && (leafUsage
.contains("ALWAYS_CONSUMED")))) {
1947 result
= "CONSUMED";
1952 private boolean checkProduced() {
1953 boolean result
= false;
1955 if (((mergeUsage
.contains("ALWAYS_PRODUCED")) && (leafUsage
.contains("SOMETIMES_PRODUCED")))
1956 || ((mergeUsage
.contains("SOMETIMES_PRODUCED")) && (leafUsage
.contains("ALWAYS_PRODUCED")))) {
1962 private boolean checkConsumed() {
1963 boolean result
= false;
1965 if (((mergeUsage
.contains("ALWAYS_CONSUMED")) && (leafUsage
.contains("SOMETIMES_CONSUMED")))
1966 || ((mergeUsage
.contains("SOMETIMES_CONSUMED")) && (leafUsage
.contains("ALWAYS_CONSUMED")))) {
1972 private String
getPathPartOfLeafMsa(String sFilename
) {
1973 String pathName
= "";
1974 String s
[] = sFilename
.replace("\\", "/").trim().split("/");
1975 for (int j
= 0; j
< (s
.length
- 1); j
++) {
1976 pathName
+= s
[j
] + "/";
1981 private static class XmlConfig
{
1982 public static XmlCursor
setupXmlCursor(XmlCursor cursor
) {
1983 String uri
= "http://www.TianoCore.org/2006/Edk2.0";
1985 cursor
.toNextToken();
1986 cursor
.insertNamespace("", uri
);
1987 cursor
.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
1993 public static XmlOptions
setupXmlOptions() {
1994 XmlOptions options
= new XmlOptions();
1995 options
.setCharacterEncoding("UTF-8");
1996 options
.setSavePrettyPrint();
1997 options
.setSavePrettyPrintIndent(2);