+// @file\r
+// This Class processes multiple MSA files and merges them into a single, \r
+// merged MSA file. It will optionally add the merged MSA file into a package.\r
+//\r
+//\r
+// Copyright (c) 2006, Intel Corporation All rights reserved.\r
+//\r
+// This program and the accompanying materials are licensed and made\r
+// available under the terms and conditions of the BSD License which\r
+// accompanies this distribution. The full text of the license may \r
+// be found at http://opensource.org/licenses/bsd-license.php\r
+//\r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+//\r
+\r
+package org.tianocore.Merge;\r
+\r
+import java.io.*;\r
+import java.util.*;\r
+// import java.lang.*;\r
+// import java.lang.ExceptionInInitializerError;\r
+\r
+// import org.apache.xmlbeans.*;\r
+import org.apache.xmlbeans.XmlCursor;\r
+// import org.apache.xmlbeans.XmlObject;\r
+import org.apache.xmlbeans.XmlOptions;\r
+import org.apache.xmlbeans.XmlException;\r
+import org.tianocore.*;\r
+\r
+// import org.tianocore.*;\r
+import org.tianocore.ModuleSurfaceAreaDocument.*;\r
+import org.tianocore.MsaHeaderDocument.*;\r
+import org.tianocore.LicenseDocument.*;\r
+import org.tianocore.ModuleDefinitionsDocument.*;\r
+import org.tianocore.LibraryClassDefinitionsDocument.*;\r
+import org.tianocore.SourceFilesDocument.*;\r
+import org.tianocore.PackageDependenciesDocument.*;\r
+import org.tianocore.ProtocolsDocument.*;\r
+import org.tianocore.EventsDocument.*;\r
+import org.tianocore.HobsDocument.*;\r
+import org.tianocore.PPIsDocument.*;\r
+import org.tianocore.VariablesDocument.*;\r
+import org.tianocore.BootModesDocument.*;\r
+import org.tianocore.SystemTablesDocument.*;\r
+import org.tianocore.DataHubsDocument.*;\r
+import org.tianocore.HiiPackagesDocument.*;\r
+import org.tianocore.GuidsDocument.*;\r
+import org.tianocore.ExternsDocument.*;\r
+import org.tianocore.PcdCodedDocument.*;\r
+import org.tianocore.ModuleBuildOptionsDocument.*;\r
+import org.tianocore.UserExtensionsDocument.*;\r
+\r
+import org.tianocore.PackageSurfaceAreaDocument.*;\r
+import org.tianocore.MsaFilesDocument.*;\r
+\r
+public class CombineMsa {\r
+\r
+ private final int DEBUG = 0;\r
+\r
+ private final int PASS = 0;\r
+\r
+ private final int FAIL = 1;\r
+\r
+ private final int FOUND = 0;\r
+\r
+ private final int NOTFOUND = 1;\r
+\r
+ private int result = PASS;\r
+\r
+ private String licenseTxt = "";\r
+\r
+ private ArrayList<String> aLicenses = new ArrayList<String>();\r
+\r
+ private String Copyright = "";\r
+\r
+ private ArrayList<String> aCopyright = new ArrayList<String>();\r
+\r
+ private String Abstract = "\n Merged Modules: \n";\r
+\r
+ private String Description = "\n Merging Modules: \n";\r
+\r
+ private String sArchitectures = "";\r
+\r
+ private MsaHeader header = null;\r
+\r
+ private final String Specification = "FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052";\r
+\r
+ private ModuleSurfaceArea mergeMsaFile = null;\r
+\r
+ private ModuleSurfaceArea leafMsa = null;\r
+\r
+ private ModuleDefinitions moduleDefs = null;\r
+\r
+ private LibraryClassDefinitions libClassDefs = null;\r
+\r
+ private ArrayList<String> aLibClassDefs = new ArrayList<String>();\r
+\r
+ private int libraryClassIndex = 0;\r
+\r
+ private SourceFiles mergeSourceFiles = null;\r
+\r
+ private int sourceFileIndex = 0;\r
+\r
+ private PackageDependencies mergePackageDependencies = null;\r
+\r
+ private ArrayList<String> aPackageList = new ArrayList<String>();\r
+\r
+ private int packageDependenciesIndex = 0;\r
+\r
+ private Protocols mergeProtocols = null;\r
+\r
+ private ArrayList<String> aProtocolList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aProtocolNotifyList = new ArrayList<String>();\r
+\r
+ private int protocolIndex = 0;\r
+\r
+ private int protocolNotifyIndex = 0;\r
+\r
+ private Events mergeEvents = null;\r
+\r
+ private Events.CreateEvents mergeCreateEvents = null;\r
+\r
+ private Events.SignalEvents mergeSignalEvents = null;\r
+\r
+ private ArrayList<String> aCreateEventsList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aSignalEventsList = new ArrayList<String>();\r
+\r
+ private int createEventIndex = 0;\r
+\r
+ private int signalEventIndex = 0;\r
+\r
+ private Hobs mergeHobs = null;\r
+\r
+ private ArrayList<String> aHobsList = new ArrayList<String>();\r
+\r
+ private int hobsIndex = 0;\r
+\r
+ private PPIs mergePpis = null;\r
+\r
+ private ArrayList<String> aPpiList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aPpiNotifyList = new ArrayList<String>();\r
+\r
+ private int ppiIndex = 0;\r
+\r
+ private int ppiNotifyIndex = 0;\r
+\r
+ private Variables mergeVariables = null;\r
+\r
+ private ArrayList<String> aVariablesList = new ArrayList<String>();\r
+\r
+ private int variablesIndex = 0;\r
+\r
+ private BootModes mergeBootModes = null;\r
+\r
+ private ArrayList<String> aBootModesList = new ArrayList<String>();\r
+\r
+ private int bootModesIndex = 0;\r
+\r
+ private SystemTables mergeSystemTables = null;\r
+\r
+ private ArrayList<String> aSystemTablesList = new ArrayList<String>();\r
+\r
+ private int systemTableIndex = 0;\r
+\r
+ private DataHubs mergeDataHubs = null;\r
+\r
+ private ArrayList<String> aDataHubsList = new ArrayList<String>();\r
+\r
+ private int dataHubsIndex = 0;\r
+\r
+ private HiiPackages mergeHiiPackages = null;\r
+\r
+ private ArrayList<String> aHiiPackagesList = new ArrayList<String>();\r
+\r
+ private int hiiPackageIndex = 0;\r
+\r
+ private Guids mergeGuids = null;\r
+\r
+ private ArrayList<String> aGuidsList = new ArrayList<String>();\r
+\r
+ private int guidsIndex = 0;\r
+\r
+ private Externs mergeExterns = null;\r
+\r
+ private ArrayList<String> aEntryPointList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aUnloadImageList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aDriverBindingList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aConstructorList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aDestructorList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aVirtualAddressMapList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aExitBootServicesList = new ArrayList<String>();\r
+\r
+ private int externsIndex = 0;\r
+\r
+ private ArrayList<String> aSpecArray = new ArrayList<String>();\r
+\r
+ private int specIndex = 0;\r
+\r
+ private PcdCoded mergePcdCoded = null;\r
+\r
+ private ArrayList<String> aPcdCNameList = new ArrayList<String>();\r
+\r
+ private ArrayList<String> aPcdItemTypeList = new ArrayList<String>();\r
+\r
+ private int pcdIndex = 0;\r
+\r
+ private ModuleBuildOptions mergeBuildOptions = null;\r
+\r
+ private UserExtensions mergeUserExtensions = null;\r
+\r
+ private XmlCursor cursor = null;\r
+\r
+ private String mergeUsage = "";\r
+\r
+ private String leafUsage = "";\r
+\r
+ private int VERBOSE = 0;\r
+\r
+ // The combineMsaFiles routine is the primary routine for creating a \r
+ // Merged MSA file.\r
+\r
+ public int combineMsaFiles(String msaFilename, ArrayList<String> msaFiles, String uiName, String spdFilename,\r
+ String baseName, int Flags) {\r
+ // msaFile has been verified to either not exist, or, if it does exist, \r
+ // it will be over written.\r
+ // All files in the msaFiles ArrayList have been verifed to exist.\r
+ // If the uiName is not null, we will have a new UI Name for the merged \r
+ // module.\r
+ // If the uiName is null, we will use the module name from the first \r
+ // Leaf module.\r
+ // If the spdFile is not null, the Package (SPD) file has been verified \r
+ // to exist.\r
+ // If the spdFile is null, don't attempt to add the new msa file.\r
+\r
+ if (Flags > 0)\r
+ VERBOSE = 1;\r
+ if (mergeMsaFile == null) {\r
+ //\r
+ // create the data structure for the merged Module\r
+ //\r
+ mergeMsaFile = ModuleSurfaceArea.Factory.newInstance();\r
+\r
+ System.out.println("Merging " + msaFiles.size() + " Modules");\r
+ //\r
+ // we always require a Header and a Module Definition section.\r
+ // These will be added to the mergeMsaFile after we have completed \r
+ // all processing of the Leaf MSA files.\r
+ //\r
+ header = MsaHeaderDocument.Factory.newInstance().addNewMsaHeader();\r
+ moduleDefs = ModuleDefinitionsDocument.Factory.newInstance().addNewModuleDefinitions();\r
+ //\r
+ // A merged module cannot be created from binary modules - we force \r
+ // the new module to be source here, however we will test every \r
+ // module to make sure that none are binary; exiting the program if\r
+ // a module is binary\r
+ //\r
+ moduleDefs.setBinaryModule(false);\r
+\r
+ for (int i = 0; i < msaFiles.size(); i++) {\r
+ String leafFilename = msaFiles.get(i).toString();\r
+ leafMsa = getLeafFile(leafFilename);\r
+ if (leafMsa == null) {\r
+ System.out.println("Could not read Leaf MSA file: " + leafFilename);\r
+ System.exit(FAIL);\r
+ }\r
+ if (i == 0) {\r
+ //\r
+ // Special code for first file, since this file is used \r
+ // to initialize some of the data in the mergeMsaFile. \r
+ // Set the Merge module's ModuleName to the name in the \r
+ // first Leaf Module. If a new module name is given, \r
+ // over write it later, just before writing the Merge \r
+ // Module MSA file.\r
+ header.setModuleName(leafMsa.getMsaHeader().getModuleName().toString());\r
+ //\r
+ // All modules must be of the same module type, we set it \r
+ // here, and test the other Leaf modules' type later.\r
+ header.setModuleType(leafMsa.getMsaHeader().getModuleType());\r
+ //\r
+ // This is a new Module, so we need a new GUID\r
+ header.setGuidValue(UUID.randomUUID().toString());\r
+ //\r
+ // Use the version from the first Leaf module as the \r
+ // Merge Module version number.\r
+ header.setVersion(leafMsa.getMsaHeader().getVersion().toString());\r
+ //\r
+ // There is no special requirement for processing the \r
+ // following, so we just fall through on these elements \r
+ // of the header.\r
+ // Abstract will be added after parsing all leaf MSA files.\r
+ // Description will be added after parsing all leaf MSA files.\r
+ // Copyright will be added after parsing all leaf MSA files.\r
+ // License will be added after parsing all leaf MSA files.\r
+ //\r
+ // Force the specification to match this tool's spec version.\r
+ header.setSpecification(Specification);\r
+ //\r
+ // Set the Merged Module's Output Basename to match the first \r
+ // leaf module\r
+ String OutputFileName = leafMsa.getModuleDefinitions().getOutputFileBasename().toString();\r
+ //\r
+ // Just in case someone put a space character in the first\r
+ // leaf module's output filename, replace the spaces with\r
+ // an underscore.\r
+ OutputFileName.replace(" ", "_");\r
+ moduleDefs.setOutputFileBasename(OutputFileName);\r
+ //\r
+ // We start with the first module's list of supported \r
+ // architectures. As we process the additional leaf modules,\r
+ // we may have to remove some supported architectures from \r
+ // the list, as we can only build for the "least common \r
+ // denominator" subset of architectures.\r
+ sArchitectures = leafMsa.getModuleDefinitions().getSupportedArchitectures().toString();\r
+ if ((DEBUG > 5) || (VERBOSE > 5))\r
+ System.out.println("New Header: \"" + header.getModuleName().toString() + "\"");\r
+ }\r
+ //\r
+ // We test the license in each leaf module, and will only print\r
+ // licenses that are may be different in wording (white spaces \r
+ // and line feeds are ignored in this test.)\r
+ if (leafMsa.getMsaHeader().getLicense() != null)\r
+ licenseTxt += checkDuplicateStrings(leafMsa.getMsaHeader().getLicense().getStringValue().trim(),\r
+ aLicenses);\r
+ if ((DEBUG > 10) || (VERBOSE > 10))\r
+ System.out.println("License: " + licenseTxt);\r
+ //\r
+ // We test the copyright line from each leaf module, and will \r
+ // add additional copyright lines only if they are different \r
+ // in wording (white spaces and line feeds are ignored in this\r
+ // test.)\r
+ if (leafMsa.getMsaHeader().getCopyright() != null)\r
+ Copyright += checkDuplicateStrings(leafMsa.getMsaHeader().getCopyright().toString().trim(),\r
+ aCopyright);\r
+ if ((DEBUG > 10) || (VERBOSE > 10))\r
+ System.out.println("Copyright: " + Copyright);\r
+ //\r
+ // ALL leaf modules must be of the same Module Type, if not, \r
+ // print an error and exit.\r
+ if (header.getModuleType() != leafMsa.getMsaHeader().getModuleType()) {\r
+ System.out.println("ERROR: Module Types different!");\r
+ System.out.println(" Expected: " + header.getModuleType());\r
+ System.out.println(" " + leafFilename + " ModuleType: " + leafMsa.getMsaHeader().getModuleType());\r
+ System.out.println("Merge ABORTED!");\r
+ System.exit(FAIL);\r
+ }\r
+ //\r
+ // Combine the Abstract and Descriptions into a single \r
+ // description entry, prefixing each with the Leaf MSA filename,\r
+ // so you know which description is from which Leaf module.\r
+ Description += " -- " + leafFilename + " -- \n Abstract: "\r
+ + leafMsa.getMsaHeader().getAbstract().toString() + "\n Description: "\r
+ + leafMsa.getMsaHeader().getDescription().toString() + "\n";\r
+ //\r
+ // Use the Abstract of the Merged Module to list the Leaf \r
+ // Module's MSA files.\r
+ Abstract += " -- " + leafFilename + " -- \n";\r
+ //\r
+ // Ignore ClonedFrom right now\r
+ //\r
+\r
+ // Process Supported Architectures\r
+ // A merged module supports the lowest common set of \r
+ // architectures\r
+ String testArch = "";\r
+ if (leafMsa.getModuleDefinitions().getSupportedArchitectures() == null) {\r
+ System.out\r
+ .println("Module " + leafFilename + " does not have the Supported Architectures defined!");\r
+ System.out.println("Supported Architectures is a required element!");\r
+ System.out.println("Merge ABORTED!");\r
+ System.exit(FAIL);\r
+ }\r
+ testArch = leafMsa.getModuleDefinitions().getSupportedArchitectures().toString();\r
+ String aArch[] = sArchitectures.split(" ");\r
+ for (int ictr = 0; ictr < aArch.length; ictr++) {\r
+ if (!testArch.contains(aArch[ictr])) {\r
+ sArchitectures = sArchitectures.replace(aArch[ictr], "");\r
+ }\r
+ }\r
+ if (sArchitectures.length() < 2) {\r
+ System.out.println("ERROR: The Leaf Modules' Supported Architectures are mutually exclusive.");\r
+ System.out.println("At least one architecture must be common to all Leaf Modules!");\r
+ System.out.println("Merge Aborting!");\r
+ System.exit(FAIL);\r
+ }\r
+ //\r
+ // Now start to process the rest of the Leaf Module's MSA files.\r
+ // We will only test a Leaf module's section if it has data, skipping\r
+ // empty sections\r
+ // As part of this process, we will only create a Library Class Definition\r
+ // if one was defined, and we will only do it one time.\r
+ if (leafMsa.isSetLibraryClassDefinitions()) {\r
+ // \r
+ // If libClassDefs == null, create a new libClassDefs and add\r
+ // this module's libClassDefs to the merge Module's\r
+ // If libClassDefs != null, check that we have only unique LibraryClass entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the LibraryClass as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the LibraryClass as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // The RecommendedInstance attributes can be ignored!\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // The SupModuleList must be identical for all Leaf Modules!\r
+ // Probable Enhancement\r
+ // The SupModuleList should be combined to include all possible supported module types.\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each LibraryClass, otherwize fail the Merge\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ if (libClassDefs == null)\r
+ libClassDefs = LibraryClassDefinitionsDocument.Factory.newInstance()\r
+ .addNewLibraryClassDefinitions();\r
+ //\r
+ // Get the Leaf LibraryClassDefinitions Section\r
+ LibraryClassDefinitions leafLibClassDef = leafMsa.getLibraryClassDefinitions();\r
+ //\r
+ // We only need to test there are entries in the Leaf LibraryClassDefinitions section!\r
+ if (leafLibClassDef.getLibraryClassList().size() > 0) {\r
+ for (int index = 0; index < leafLibClassDef.getLibraryClassList().size(); index++) {\r
+ //\r
+ // We can use the Keyword to search to see if the Leaf's Library Class was already\r
+ // added to the Merge Module.\r
+ String test = "";\r
+ String leafKeyword = leafLibClassDef.getLibraryClassList().get(index).getKeyword()\r
+ .toString().trim();\r
+\r
+ leafUsage = "";\r
+ if (leafLibClassDef.getLibraryClassList().get(index).getUsage() != null)\r
+ leafUsage = leafLibClassDef.getLibraryClassList().get(index).getUsage().toString()\r
+ .trim();\r
+\r
+ String leafSupArchList = "";\r
+ if (leafLibClassDef.getLibraryClassList().get(index).getSupArchList() != null)\r
+ leafSupArchList = leafLibClassDef.getLibraryClassList().get(index).getSupArchList()\r
+ .toString().trim();\r
+\r
+ String leafSupModuleList = "";\r
+ if (leafLibClassDef.getLibraryClassList().get(index).getSupModuleList() != null)\r
+ leafSupModuleList = leafLibClassDef.getLibraryClassList().get(index).getSupModuleList()\r
+ .toString().trim();\r
+\r
+ test = checkDuplicateStrings(leafKeyword, aLibClassDefs);\r
+ if (test.length() > 0) {\r
+ // The checkDuplicateStrings returns "" if a duplicate was found.\r
+ // Here, the Leaf LibraryClass gets entered because the Keyword was not found.\r
+ // No more testing is required, since this is the first instance of the LibraryClass\r
+ libClassDefs.addNewLibraryClass();\r
+ libClassDefs.setLibraryClassArray(libraryClassIndex++,\r
+ leafLibClassDef.getLibraryClassList().get(index));\r
+ } else {\r
+ // The Merged Module has already specified the Library Class\r
+ // Check ATTRIBUTES, following the rules above.\r
+ // Since we cannot get the LibraryClass entry using the Keyword, we have to search\r
+ // all of the Merged Module's LibraryClass statements until we find a match.\r
+ // Also, we may have more than one LibraryClass with the same Keyword, but different\r
+ // Usage, SupArchList, FeatureFlag or SupModuleList\r
+ for (int nidx = 0; nidx < libraryClassIndex; nidx++) {\r
+ String mergeKeyword = libClassDefs.getLibraryClassList().get(nidx).getKeyword()\r
+ .trim();\r
+\r
+ if (leafKeyword.contentEquals(mergeKeyword)) {\r
+ // We have the FIRST match, let's check usage, remember, we can have more than one LibraryClass Keyword.\r
+ mergeUsage = libClassDefs.getLibraryClassList().get(nidx).getUsage().toString()\r
+ .trim();\r
+ // If the usage is identical, check the SupArchList next\r
+ if (!leafUsage.contentEquals(mergeUsage)) {\r
+ if (checkUsage().trim().contains("DIFFERENT")) {\r
+ // See if there is another entry for PRODUCED or CONSUME\r
+ int anotherLC = NOTFOUND;\r
+ for (int iidx = nidx + 1; iidx < libraryClassIndex; iidx++) {\r
+ String innerTestKeyword = libClassDefs.getLibraryClassList()\r
+ .get(iidx).getKeyword()\r
+ .toString().trim();\r
+ if (leafKeyword.contentEquals(innerTestKeyword)) {\r
+ anotherLC = FOUND;\r
+ mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
+ .getUsage().toString().trim();\r
+ if (checkProduced()) {\r
+ libClassDefs\r
+ .getLibraryClassList()\r
+ .get(iidx)\r
+ .setUsage(\r
+ org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
+ }\r
+ // Both Usage types are CONSUMED\r
+ if (checkConsumed()) {\r
+ libClassDefs\r
+ .getLibraryClassList()\r
+ .get(iidx)\r
+ .setUsage(\r
+ org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
+ }\r
+ if (((mergeUsage.contains("TO_START")) && (leafUsage\r
+ .contains("TO_START"))))\r
+ anotherLC = FOUND;\r
+ if (((mergeUsage.contains("BY_START")) && (leafUsage\r
+ .contains("BY_START"))))\r
+ anotherLC = FOUND;\r
+ }\r
+ }\r
+ if (anotherLC == NOTFOUND) {\r
+ // we need to add the leaf Library Class\r
+ libClassDefs.addNewLibraryClass();\r
+ libClassDefs\r
+ .setLibraryClassArray(\r
+ libraryClassIndex++,\r
+ leafLibClassDef\r
+ .getLibraryClassList()\r
+ .get(index));\r
+ }\r
+ }\r
+\r
+ // Both Usage types are PRODUCED\r
+ if (checkUsage().trim().contains("PRODUCED")) {\r
+ libClassDefs.getLibraryClassList().get(nidx)\r
+ .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
+ }\r
+ // Both Usage types are CONSUMED\r
+ if (checkUsage().trim().contains("CONSUMED")) {\r
+ libClassDefs.getLibraryClassList().get(nidx)\r
+ .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
+ }\r
+ }\r
+ // Usage testing completed\r
+ // Check SupArchList\r
+ String mergeSupArchList = "";\r
+ if (libClassDefs.getLibraryClassList().get(nidx).getSupArchList() != null)\r
+ mergeSupArchList = libClassDefs.getLibraryClassList().get(nidx)\r
+ .getSupArchList().toString().trim();\r
+ if (!mergeSupArchList.equalsIgnoreCase(leafSupArchList)) {\r
+ System.out\r
+ .println("ERROR: Library Class, keyword: " + leafKeyword\r
+ + " defines a different set of supported architectures.");\r
+ System.out\r
+ .println("Version 0.1 of the merge tool requires that they must be identical!");\r
+ System.out.println("First instance of the Library used: "\r
+ + mergeSupArchList);\r
+ System.out.println("While this module, " + leafFilename + " uses: "\r
+ + leafSupArchList);\r
+ System.out.println("Merge ABORTED!");\r
+ System.exit(FAIL);\r
+ }\r
+ // Architecture Testing completed\r
+ // Check SupModuleType\r
+ String mergeSupModuleList = "";\r
+ if (libClassDefs.getLibraryClassList().get(nidx).getSupModuleList() != null)\r
+ mergeSupModuleList = libClassDefs.getLibraryClassList().get(nidx)\r
+ .getSupModuleList().toString().trim();\r
+ if (!mergeSupModuleList.equalsIgnoreCase(leafSupModuleList)) {\r
+ System.out.println("ERROR: Library Class, keyword: " + leafKeyword\r
+ + " defines a different set of supported modules.");\r
+ System.out\r
+ .println("Version 0.1 of the merge tool requires that they must be identical!");\r
+ System.out.println("First instance of the Library used: "\r
+ + mergeSupModuleList);\r
+ System.out.println("While this module, " + leafFilename + " uses: "\r
+ + leafSupModuleList);\r
+ System.out.println("Merge ABORTED!");\r
+ System.exit(FAIL);\r
+ }\r
+ // Supported Module Testing completed\r
+ // Check FeatureFlage\r
+ // Next version, not this one.\r
+ }\r
+ } // end of processing of duplicate Library Class entries\r
+ } // end duplicate entry\r
+ } // end of test loop for duplicates \r
+ } // endif Merge Module LibraryModuleDefinitions existed\r
+ } // endif of LibraryModuleDefinition Tests\r
+\r
+ if (leafMsa.isSetSourceFiles()) {\r
+ // TODO: test for NULL settings\r
+ // Add Sourcefiles to the Merge Module. NOTE: ONLY MODIFY THE Filename, prepending the path to the MSA file.\r
+ // First get the path portion of the leafMSA file, which will be prepended to the filename\r
+ // everything else stays intact.\r
+ if (mergeSourceFiles == null)\r
+ mergeSourceFiles = SourceFilesDocument.Factory.newInstance().addNewSourceFiles();\r
+\r
+ String pathToMsa = getPathPartOfLeafMsa(leafFilename);\r
+ if (DEBUG > 10)\r
+ System.out.println("PATH TO SOURCE FILES: " + pathToMsa);\r
+ if (leafMsa.getSourceFiles().getFilenameList() != null) {\r
+ List<FilenameDocument.Filename> leafSourceFiles = leafMsa.getSourceFiles().getFilenameList();\r
+ for (int index = 0; index < leafSourceFiles.size(); index++) {\r
+ String leafFile = leafSourceFiles.get(index).getStringValue().toString();\r
+ leafFile = pathToMsa + leafFile;\r
+ leafSourceFiles.get(index).setStringValue(leafFile);\r
+ mergeSourceFiles.addNewFilename();\r
+ mergeSourceFiles.setFilenameArray(sourceFileIndex++, leafSourceFiles.get(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ if (leafMsa.isSetPackageDependencies()) {\r
+ //\r
+ // If mergePackageDependencies == null, create a new mergePackageDependencies and\r
+ // add the leaf module's Package Dependencies section to the merge Module's\r
+ // If mergePackageDependencies != null, test the leaf Package entries against\r
+ // what has already been added to the mergePackageDependencies data structure.\r
+ //\r
+ // Add Unique Package entries.\r
+ // For this Merge Tool a Package is defined as PackageGuid\r
+ //\r
+ // ABORT THE MERGE WITH FAIL if the PACKAGE VERSION NUMBERS ARE DIFFERENT\r
+ // between Leaf modules\r
+ //\r
+ // Version 0.1 of the tool\r
+ // SupArchList, if it exists, must be identical for all Leaf Modules\r
+ // Probable Enhancement\r
+ // Just specify the lowest common denominator\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: CODE GOES HERE\r
+ if (mergePackageDependencies == null)\r
+ mergePackageDependencies = PackageDependenciesDocument.Factory.newInstance()\r
+ .addNewPackageDependencies();\r
+\r
+ PackageDependencies leafPackageDependencies = leafMsa.getPackageDependencies();\r
+ if (leafPackageDependencies.sizeOfPackageArray() > 0) {\r
+ for (int index = 0; index < leafPackageDependencies.sizeOfPackageArray(); index++) {\r
+ String packageGuid = leafPackageDependencies.getPackageArray(index).getPackageGuid();\r
+ String test = checkDuplicateStrings(packageGuid, aPackageList);\r
+ if (test.length() > 0) {\r
+ mergePackageDependencies.addNewPackage();\r
+ mergePackageDependencies\r
+ .setPackageArray(packageDependenciesIndex++,\r
+ leafPackageDependencies.getPackageArray(index));\r
+ }\r
+ }\r
+ }\r
+ } // endif PackageDependencies\r
+\r
+ if (leafMsa.isSetProtocols()) {\r
+ // TODO: \r
+ // TEST FOR NULL SETTINGS so we don't get an error!\r
+ // Add Usage Merging routines\r
+ // \r
+ // If mergeProtocols == null, create a new mergeProtocols and add\r
+ // leaf module's Protocols section to the merge Module's\r
+ //\r
+ // Keep ALL Protocol entries before ProtocolNotify entries!\r
+ //\r
+ // If mergeProtocols != null, check that we have only unique Protocol and ProtocolNotify entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the Protocol or ProtocolNotify as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the Protocol or ProtocolNotify as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique Protocol or ProtocolNotify Entry, otherwise fail the Merge\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+\r
+ if (mergeProtocols == null)\r
+ mergeProtocols = ProtocolsDocument.Factory.newInstance().addNewProtocols();\r
+\r
+ Protocols leafProtocols = leafMsa.getProtocols();\r
+ // Handle Protocol Entries First\r
+ if (leafProtocols.sizeOfProtocolArray() > 0) {\r
+ for (int index = 0; index < leafProtocols.sizeOfProtocolArray(); index++) {\r
+ String protocolCName = leafProtocols.getProtocolArray(index).getProtocolCName();\r
+ String test = checkDuplicateStrings(protocolCName, aProtocolList);\r
+ if (test.length() > 0) {\r
+ // new Protocol\r
+ mergeProtocols.addNewProtocol();\r
+ mergeProtocols.setProtocolArray(protocolIndex++, leafProtocols.getProtocolArray(index));\r
+ } else {\r
+ // Found an existing protocol\r
+ leafUsage = leafProtocols.getProtocolArray(index).getUsage().toString().trim();\r
+ for (int nidx = 0; nidx < protocolIndex; nidx++) {\r
+ if (mergeProtocols.getProtocolArray(nidx).getProtocolCName()\r
+ .contains(protocolCName)) {\r
+ // Found one entry that matches.\r
+ mergeUsage = mergeProtocols.getProtocolArray(nidx).getUsage().toString().trim();\r
+ if (!mergeUsage.contentEquals(leafUsage)) {\r
+ // Usages are different\r
+ if (checkUsage().trim().contains("DIFFERENT")) {\r
+ // We need to check to see if there's another entry\r
+ int anotherProtocol = NOTFOUND;\r
+ for (int iidx = nidx + 1; iidx < protocolIndex; iidx++) {\r
+\r
+ if (mergeProtocols.getProtocolArray(iidx).getUsage().toString()\r
+ .trim().contains(protocolCName)) {\r
+ anotherProtocol = FOUND;\r
+ mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
+ .getUsage().toString().trim();\r
+ if (checkProduced()) {\r
+ mergeProtocols\r
+ .getProtocolArray(nidx)\r
+ .setUsage(\r
+ org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
+ anotherProtocol = FOUND;\r
+ }\r
+ // Both Usage types are CONSUMED\r
+ if (checkConsumed()) {\r
+ mergeProtocols\r
+ .getProtocolArray(nidx)\r
+ .setUsage(\r
+ org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
+ anotherProtocol = FOUND;\r
+ }\r
+ if (((mergeUsage.contains("TO_START")) && (leafUsage\r
+ .contains("TO_START"))))\r
+ anotherProtocol = FOUND;\r
+ if (((mergeUsage.contains("BY_START")) && (leafUsage\r
+ .contains("BY_START"))))\r
+ anotherProtocol = FOUND;\r
+ }\r
+ }\r
+ if (anotherProtocol == NOTFOUND) {\r
+ mergeProtocols.addNewProtocol();\r
+ mergeProtocols\r
+ .setProtocolArray(\r
+ protocolIndex++,\r
+ leafProtocols\r
+ .getProtocolArray(index));\r
+ }\r
+ } else {\r
+ // usage types are either both PRODUCED or CONSUMED\r
+ if (checkProduced())\r
+ mergeProtocols.getProtocolArray(nidx)\r
+ .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
+ if (checkConsumed())\r
+ mergeProtocols.getProtocolArray(nidx)\r
+ .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
+ }\r
+ }\r
+ }\r
+ } // end of Usage Test\r
+ }\r
+ }\r
+ }\r
+\r
+ // Handle ProtocolNotify Entries Second\r
+ if (leafProtocols.sizeOfProtocolNotifyArray() > 0) {\r
+ for (int index = 0; index < leafProtocols.sizeOfProtocolNotifyArray(); index++) {\r
+ String protocolNotifyCName = leafProtocols.getProtocolNotifyArray(index)\r
+ .getProtocolNotifyCName();\r
+ String test = checkDuplicateStrings(protocolNotifyCName, aProtocolNotifyList);\r
+ if (test.length() > 0) {\r
+ mergeProtocols.addNewProtocolNotify();\r
+ mergeProtocols.setProtocolNotifyArray(protocolNotifyIndex++,\r
+ leafProtocols.getProtocolNotifyArray(index));\r
+ } else {\r
+ // We have an existing ProtocolNotify Entry\r
+ leafUsage = leafProtocols.getProtocolNotifyArray(index).getUsage().toString().trim();\r
+ for (int nidx = 0; nidx < protocolIndex; nidx++) {\r
+ if (mergeProtocols.getProtocolNotifyArray(nidx).getProtocolNotifyCName()\r
+ .contains(protocolNotifyCName)) {\r
+ // Found one entry that matches.\r
+ mergeUsage = mergeProtocols.getProtocolNotifyArray(nidx).getUsage().toString().trim();\r
+ if (!mergeUsage.contentEquals(leafUsage)) {\r
+ // Usages are different\r
+ if (checkUsage().trim().contains("DIFFERENT")) {\r
+ // We need to check to see if there's another entry\r
+ int anotherProtocol = NOTFOUND;\r
+ for (int iidx = nidx + 1; iidx < protocolIndex; iidx++) {\r
+\r
+ if (mergeProtocols.getProtocolNotifyArray(iidx).getUsage().toString()\r
+ .trim().contains(protocolNotifyCName)) {\r
+ anotherProtocol = FOUND;\r
+ mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
+ .getUsage().toString().trim();\r
+ if (checkProduced()) {\r
+ mergeProtocols\r
+ .getProtocolNotifyArray(nidx)\r
+ .setUsage(\r
+ org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
+ anotherProtocol = FOUND;\r
+ }\r
+ // Both Usage types are CONSUMED\r
+ if (checkConsumed()) {\r
+ mergeProtocols\r
+ .getProtocolNotifyArray(nidx)\r
+ .setUsage(\r
+ org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
+ anotherProtocol = FOUND;\r
+ }\r
+ if (((mergeUsage.contains("TO_START")) && (leafUsage\r
+ .contains("TO_START"))))\r
+ anotherProtocol = FOUND;\r
+ if (((mergeUsage.contains("BY_START")) && (leafUsage\r
+ .contains("BY_START"))))\r
+ anotherProtocol = FOUND;\r
+ }\r
+ }\r
+ if (anotherProtocol == NOTFOUND) {\r
+ mergeProtocols.addNewProtocolNotify();\r
+ mergeProtocols\r
+ .setProtocolNotifyArray(\r
+ protocolNotifyIndex++,\r
+ leafProtocols\r
+ .getProtocolNotifyArray(index));\r
+ }\r
+ } else {\r
+ // usage types are either both PRODUCED or CONSUMED\r
+ if (checkProduced())\r
+ mergeProtocols.getProtocolNotifyArray(nidx)\r
+ .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
+ if (checkConsumed())\r
+ mergeProtocols.getProtocolNotifyArray(nidx)\r
+ .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
+ }\r
+ }\r
+ }\r
+ } // end of Usage Test\r
+ } // end of Usage test\r
+ }\r
+ }\r
+\r
+ } // endif Protocols\r
+\r
+ if (leafMsa.isSetEvents()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // "Unique" Entries are based on EventsTypes:EventGuidCName attributes\r
+ // NOTE: The EventGuidCName can appear once and only once in a CreateEvents Section\r
+ // The SAME EventGuidCName can appear once and only once in the SignalEvents Section\r
+ // Two EventGuidCName entries, one in CreateEvents the other in SignalEvents IS PERMITTED!\r
+ //\r
+ // If mergeEvents == null, create a new mergeEvents and add\r
+ // leaf module's Events section to the merge Module's\r
+ //\r
+ // Keep ALL CreateEvents entries before SignalEvents entries!\r
+ //\r
+ // If mergeEvents != null, check that we have only unique CreateEvents and SignalEvents entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the CreateEvents.EventTypes or SignalEvents.EventTypes as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the CreateEvents.EventTypes or SignalEvents.EventTypes as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique EventTypes, otherwise fail the Merge\r
+ //\r
+ // The EventTypes.EventType elements must be identical for all instances of\r
+ // the EventGuidCName FAIL THE MERGE WITH ERROR indicating the Leaf file name that \r
+ // was different.\r
+ //\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code goes here\r
+\r
+ if (mergeCreateEvents == null)\r
+ mergeCreateEvents = EventsDocument.Events.CreateEvents.Factory.newInstance();\r
+\r
+ Events leafEvents = leafMsa.getEvents();\r
+ if (leafEvents.getCreateEvents() != null) {\r
+ Events.CreateEvents leafCreateEvents = leafEvents.getCreateEvents();\r
+ if (leafCreateEvents.sizeOfEventTypesArray() > 0) {\r
+ for (int index = 0; index < leafCreateEvents.sizeOfEventTypesArray(); index++) {\r
+ String EventGuidCName = leafCreateEvents.getEventTypesArray(index).getEventGuidCName();\r
+ String test = checkDuplicateStrings(EventGuidCName, aCreateEventsList);\r
+ if (test.length() > 0) {\r
+ mergeCreateEvents.addNewEventTypes();\r
+ mergeCreateEvents.setEventTypesArray(createEventIndex++,\r
+ leafEvents.getCreateEvents()\r
+ .getEventTypesArray(index));\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (mergeSignalEvents == null)\r
+ mergeSignalEvents = EventsDocument.Events.SignalEvents.Factory.newInstance();\r
+\r
+ if (leafEvents.getSignalEvents() != null) {\r
+ Events.SignalEvents leafSignalEvents = leafEvents.getSignalEvents();\r
+ if (leafSignalEvents.sizeOfEventTypesArray() > 0) {\r
+ for (int index = 0; index < leafSignalEvents.sizeOfEventTypesArray(); index++) {\r
+ String EventGuidCName = leafSignalEvents.getEventTypesArray(index).getEventGuidCName();\r
+ String test = checkDuplicateStrings(EventGuidCName, aSignalEventsList);\r
+ if (test.length() > 0) {\r
+ mergeSignalEvents.addNewEventTypes();\r
+ mergeSignalEvents.setEventTypesArray(signalEventIndex++,\r
+ leafEvents.getSignalEvents()\r
+ .getEventTypesArray(index));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } // endif Events \r
+\r
+ if (leafMsa.isSetHobs()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // "Unique" Entries are based on Hobs.HobTypes:HobGuidCName attribute\r
+ //\r
+ // If mergeHobs == null, create a new mergeHobs and add\r
+ // leaf module's Hobs section to the merge Module's\r
+ //\r
+ // \r
+ // If mergeHobs != null, check that we have only unique Hobs.HobTypes entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the Hobs.HobTypes as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the Hobs.HobTypes as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique HobTypes element, otherwise fail the Merge\r
+ //\r
+ // The HobTypes.HobType elements must be identical for all instances of\r
+ // the HobGuidCName FAIL THE MERGE WITH ERROR indicating the Leaf file name that \r
+ // was different.\r
+ //\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code goes here\r
+ if (mergeHobs == null)\r
+ mergeHobs = HobsDocument.Factory.newInstance().addNewHobs();\r
+\r
+ Hobs leafHobs = leafMsa.getHobs();\r
+ if (leafHobs.sizeOfHobTypesArray() > 0) {\r
+ for (int index = 0; index < leafHobs.sizeOfHobTypesArray(); index++) {\r
+ String hobGuidCName = leafHobs.getHobTypesArray(index).getHobType().toString();\r
+ String test = checkDuplicateStrings(hobGuidCName, aHobsList);\r
+ if (test.length() > 0) {\r
+ mergeHobs.addNewHobTypes();\r
+ mergeHobs.setHobTypesArray(hobsIndex++, leafHobs.getHobTypesArray(index));\r
+ }\r
+ }\r
+ }\r
+ } // endif Hobs \r
+\r
+ if (leafMsa.isSetPPIs()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Keep only Unique Ppi or PpiNotify elements, based on the PpiCName and PpiNotifyCName respectively.\r
+\r
+ // If mergePpi == null, create a new mergePpi and add\r
+ // leaf module's PPIs section to the merge Module's\r
+ //\r
+ // Keep ALL Ppi entries before PpiNotify entries!\r
+ //\r
+ // If mergePpi != null, check that we have only unique Ppi and PpiNotify entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the Ppi or PpiNotify as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the Ppi or PpiNotify as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique Ppi or PpiNotify Entry, otherwise fail the Merge\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergePpis == null)\r
+ mergePpis = PPIsDocument.Factory.newInstance().addNewPPIs();\r
+\r
+ PPIs leafPPIs = leafMsa.getPPIs();\r
+ // Handle the PPI Entries First\r
+ if (leafPPIs.sizeOfPpiArray() > 0) {\r
+ for (int index = 0; index < leafPPIs.sizeOfPpiArray(); index++) {\r
+ String ppiCName = leafPPIs.getPpiArray(index).getPpiCName();\r
+ String test = checkDuplicateStrings(ppiCName, aPpiList);\r
+ if (test.length() > 0) {\r
+ mergePpis.addNewPpi();\r
+ mergePpis.setPpiArray(ppiIndex++, leafPPIs.getPpiArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ // Handle the PpiNotify Second\r
+ if (leafPPIs.sizeOfPpiNotifyArray() > 0) {\r
+ for (int index = 0; index < leafPPIs.sizeOfPpiNotifyArray(); index++) {\r
+ String ppiNotifyCName = leafPPIs.getPpiNotifyArray(index).getPpiNotifyCName();\r
+ String test = checkDuplicateStrings(ppiNotifyCName, aPpiNotifyList);\r
+ if (test.length() > 0) {\r
+ mergePpis.addNewPpiNotify();\r
+ mergePpis.setPpiNotifyArray(ppiNotifyIndex++, leafPPIs.getPpiNotifyArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ } // endif Ppis\r
+\r
+ if (leafMsa.isSetVariables()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Keep only Unique Variable elements, based on the VariableName element.\r
+ //\r
+ // If mergeVariables == null, create a new mergeVariables and add\r
+ // leaf module's Variables section to the merge Module's\r
+ //\r
+ // If mergeVariables != null, check that we have only unique Variable entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the Variable as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the Variable as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique Variable entry, otherwise fail the Merge\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergeVariables == null)\r
+ mergeVariables = VariablesDocument.Factory.newInstance().addNewVariables();\r
+\r
+ Variables leafVariables = leafMsa.getVariables();\r
+ if (leafVariables.sizeOfVariableArray() > 0) {\r
+ for (int index = 0; index < leafVariables.sizeOfVariableArray(); index++) {\r
+ String variableGuidCName = leafVariables.getVariableArray(index).getGuidCName();\r
+ String test = checkDuplicateStrings(variableGuidCName, aVariablesList);\r
+ if (test.length() > 0) {\r
+ mergeVariables.addNewVariable();\r
+ mergeVariables\r
+ .setVariableArray(variablesIndex++, leafVariables.getVariableArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ }// endif Variables\r
+\r
+ if (leafMsa.isSetBootModes()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Keep only Unique BootMode elements, based on the BootModeName Attribute.\r
+ //\r
+ // If mergeBootModes == null, create a new mergeBootModes and add\r
+ // leaf module's BootModes section to the merge Module's\r
+ //\r
+ // If mergeBootModes != null, check that we have only unique BootMode entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the BootMode as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the BootMode as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique BootMode entry, otherwise fail the Merge\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergeBootModes == null)\r
+ mergeBootModes = BootModesDocument.Factory.newInstance().addNewBootModes();\r
+\r
+ BootModes leafBootModes = leafMsa.getBootModes();\r
+ if (leafBootModes.sizeOfBootModeArray() > 0) {\r
+ for (int index = 0; index < leafBootModes.sizeOfBootModeArray(); index++) {\r
+ String bootModeName = leafBootModes.getBootModeArray(index).getBootModeName().toString();\r
+ String test = checkDuplicateStrings(bootModeName, aBootModesList);\r
+ if (test.length() > 0) {\r
+ mergeBootModes.addNewBootMode();\r
+ mergeBootModes\r
+ .setBootModeArray(bootModesIndex++, leafBootModes.getBootModeArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ }// endif BootMode\r
+\r
+ if (leafMsa.isSetSystemTables()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Keep only Unique SystemTableCNames elements, based on the SystemTableCName element.\r
+ //\r
+ // If mergeSystemTables == null, create a new mergeSystemTables and add\r
+ // leaf module's Variables section to the merge Module's\r
+ //\r
+ // If mergeSystemTables != null, check that we have only unique SystemTableCNames entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the SystemTableCName as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the SystemTableCName as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique SystemTableCNames entry, otherwise fail the Merge\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergeSystemTables == null)\r
+ mergeSystemTables = SystemTablesDocument.Factory.newInstance().addNewSystemTables();\r
+\r
+ SystemTables leafSystemTables = leafMsa.getSystemTables();\r
+ if (leafSystemTables.sizeOfSystemTableCNamesArray() > 0) {\r
+ for (int index = 0; index < leafSystemTables.sizeOfSystemTableCNamesArray(); index++) {\r
+ String systemTableCName = leafSystemTables.getSystemTableCNamesArray(index)\r
+ .getSystemTableCName();\r
+ String test = checkDuplicateStrings(systemTableCName, aSystemTablesList);\r
+ if (test.length() > 0) {\r
+ mergeSystemTables.addNewSystemTableCNames();\r
+ mergeSystemTables\r
+ .setSystemTableCNamesArray(\r
+ systemTableIndex++,\r
+ leafSystemTables\r
+ .getSystemTableCNamesArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ }// endif SystemTables\r
+\r
+ if (leafMsa.isSetDataHubs()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Keep only Unique DataHubs elements, based on the DataHubRecord.DataHubCName element.\r
+ //\r
+ // If mergeDataHubs == null, create a new mergeDataHubs and add\r
+ // leaf module's DataHubs section to the merge Module's\r
+ //\r
+ // If mergeDataHubs != null, check that we have only unique DataHubRecord entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the DataHubCName as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the DataHubCName as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique DataHubRecord entry, otherwise fail the Merge\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergeDataHubs == null)\r
+ mergeDataHubs = DataHubsDocument.Factory.newInstance().addNewDataHubs();\r
+\r
+ DataHubs leafDataHubs = leafMsa.getDataHubs();\r
+ if (leafDataHubs.sizeOfDataHubRecordArray() > 0) {\r
+ for (int index = 0; index < leafDataHubs.sizeOfDataHubRecordArray(); index++) {\r
+ String dataHubCName = leafDataHubs.getDataHubRecordArray(index).getDataHubCName();\r
+ String test = checkDuplicateStrings(dataHubCName, aDataHubsList);\r
+ if (test.length() > 0) {\r
+ mergeDataHubs.addNewDataHubRecord();\r
+ mergeDataHubs.setDataHubRecordArray(dataHubsIndex++,\r
+ leafDataHubs.getDataHubRecordArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ }// endif DataHubs\r
+\r
+ if (leafMsa.isSetHiiPackages()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Keep only Unique HiiPackage elements, based on the HiiPackage.HiiCName element.\r
+ //\r
+ // If mergeHiiPackages == null, create a new mergeHiiPackages and add\r
+ // leaf module's DataHubs section to the merge Module's\r
+ //\r
+ // If mergeHiiPackages != null, check that we have only unique HiiPackage entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the HiiPackage as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the HiiPackage as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique HiiPackage entry, otherwise fail the Merge\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergeHiiPackages == null)\r
+ mergeHiiPackages = HiiPackagesDocument.Factory.newInstance().addNewHiiPackages();\r
+\r
+ HiiPackages leafHiiPackages = leafMsa.getHiiPackages();\r
+ if (leafHiiPackages.sizeOfHiiPackageArray() > 0) {\r
+ for (int index = 0; index < leafHiiPackages.sizeOfHiiPackageArray(); index++) {\r
+ String hiiCName = leafHiiPackages.getHiiPackageArray(index).getHiiCName();\r
+ String test = checkDuplicateStrings(hiiCName, aHiiPackagesList);\r
+ if (test.length() > 0) {\r
+ mergeHiiPackages.addNewHiiPackage();\r
+ mergeHiiPackages.setHiiPackageArray(hiiPackageIndex++,\r
+ leafHiiPackages.getHiiPackageArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ }// endif HiiPackage\r
+\r
+ if (leafMsa.isSetGuids()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Keep only Unique Guids elements, based on the GuidCNames.GuidCName element.\r
+ //\r
+ // If mergeGuids == null, create a new mergeGuids and add\r
+ // leaf module's Guids section to the merge Module's\r
+ //\r
+ // If mergeGuids != null, check that we have only unique GuidCNames entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the GuidCNames as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the GuidCNames as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique GuidCNames entry, otherwise fail the Merge\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergeGuids == null)\r
+ mergeGuids = GuidsDocument.Factory.newInstance().addNewGuids();\r
+\r
+ Guids leafGuids = leafMsa.getGuids();\r
+ if (leafGuids.sizeOfGuidCNamesArray() > 0) {\r
+ for (int index = 0; index < leafGuids.sizeOfGuidCNamesArray(); index++) {\r
+ String hiiCName = leafGuids.getGuidCNamesArray(index).getGuidCName();\r
+ String test = checkDuplicateStrings(hiiCName, aGuidsList);\r
+ if (test.length() > 0) {\r
+ mergeGuids.addNewGuidCNames();\r
+ mergeGuids.setGuidCNamesArray(guidsIndex++, leafGuids.getGuidCNamesArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ }// endif GuidCNames\r
+\r
+ if (leafMsa.isSetExterns()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // FAIL THE MERGE if Externs.PcdIsDriver is present\r
+ // FAIL THE MERGE if Externs.TianoR8FlashMap_h is TRUE\r
+ //\r
+ // Keep only Unique Extern elements, based on the Extern.* elements.\r
+ //\r
+ // If mergeExterns == null, create a new mergeExterns and add\r
+ // leaf module's Extern section to the merge Module's\r
+ //\r
+ // If mergeExterns != null, check that we have only unique Extern.* entries\r
+ //\r
+ // After storing the initial LEAF MODULE'S SPECIFICATION SECTION\r
+ // ALL other Leaf Modules must declare the exact same specifications\r
+ // If they do not, FAIL the MERGE with an error message, printing the\r
+ // name of the leaf MSA that did not match, along with\r
+ // Expected: from the merge module's specification list\r
+ // Got: from the leaf file that fails!\r
+ //\r
+ // For Each <Extern>\r
+ // For each pair of <ModuleEntryPoint> and/or <ModuleUnloadImage>\r
+ // The ModuleUnloadImage value must be identical for an identical pair of ModuleEntryPoint values\r
+ // If not, FAIL THE MERGE, giving the current leaf MSA filename as the failure, along with the\r
+ // additional error information as follows:\r
+ // -- leafFilename --\r
+ // ModuleEntryPoint: \r
+ // Expected ModuleUnloadImage: fromMergeModule\r
+ // Got ModuleUnloadImage: fromLeaf\r
+ // Merge Aborted!\r
+ // More than one <Extern> Section with a pair of <ModuleEntryPoint><ModuleUnloadImage> is allowed\r
+ //\r
+ // For each pair of one <Constructor> and/or one <Destructor> elements\r
+ // The <Extern> section containing the <Constructor> <Destructor> pairs \r
+ // The Destructor value in all leaf modules must be identical for all Constructor elements that are identical.\r
+ // More than one <Extern> Section with Constructor/Destructor pair is permitted.\r
+ //\r
+ // For each Set four elements, DriverBinding, ComponentName, DriverConfig and DriverDiag,\r
+ // 1 DriverBinding and\r
+ // 0 or 1 ComponentName and/or\r
+ // 0 or 1 DriverConfig and/or\r
+ // 0 or 1 DriverDiag \r
+ // elements must appear in 1 <Extern> Section.\r
+ //\r
+ // A ComponentName cannot be used without a DriverBinding element.\r
+ // A DriverConfig element cannot appear without a DriverBinding element. \r
+ // A DriverDiag element cannot appear without a DriverBinding element\r
+ // These elements are matched within a single <Extern> Section uniquely defined by the DriverBinding element. \r
+ // Multiple <Extern> sections of this type are permitted.\r
+ //\r
+ // Each pair of SetVirtualAddressMapCallBack and ExitBootServiceCallBack elements MUST \r
+ // BE in one Extern Section. ONE AND ONLY ONE of this section is permitted.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique Extern entry, otherwise fail the Merge\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergeExterns == null)\r
+ mergeExterns = ExternsDocument.Factory.newInstance().addNewExterns();\r
+\r
+ Externs leafExterns = leafMsa.getExterns();\r
+ // PCD IS DRIVER NOT ALLOWED IN A MERGED Module\r
+ if (leafExterns.isSetPcdIsDriver()) {\r
+ System.out.println("The Module: " + leafFilename + " is a PCD Driver and CANNOT BE MERGED!");\r
+ System.out.println("Merge Aborted");\r
+ System.err.flush();\r
+ System.exit(FAIL);\r
+ }\r
+\r
+ // TIANO R8 FLASHMAP.H NOT ALLOWED IN A MERGED Module\r
+ if (leafExterns.isSetTianoR8FlashMapH()) {\r
+ System.out.println("The Module: " + leafFilename\r
+ + " set the Tiano R8 FlashMap.h Flag and CANNOT BE MERGED!");\r
+ System.out.println("Merge Aborted");\r
+ System.err.flush();\r
+ System.exit(FAIL);\r
+ }\r
+\r
+ // Add the Specification Array, one time only.\r
+ if (leafExterns.sizeOfSpecificationArray() > 0) {\r
+ for (int index = 0; index < leafExterns.sizeOfSpecificationArray(); index++) {\r
+ String spec = leafExterns.getSpecificationArray(index);\r
+ String test = checkSpecs(spec, leafFilename, aSpecArray);\r
+ if (test.length() > 0) {\r
+ mergeExterns.addNewSpecification();\r
+ mergeExterns.setSpecificationArray(specIndex++, test);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (leafExterns.sizeOfExternArray() > 0) {\r
+ for (int index = 0; index < leafExterns.sizeOfExternArray(); index++) {\r
+ String test = "";\r
+ if (leafExterns.getExternArray(index).isSetModuleEntryPoint()) {\r
+ // ModuleEntryPoint, if an Unload Image is paired with\r
+ // the Module Entry point, it will piggy back on the\r
+ // Module Entry Point Extern\r
+ String moduleEntryPoint = leafExterns.getExternArray(index).getModuleEntryPoint();\r
+ test = checkDuplicateStrings(moduleEntryPoint, aEntryPointList);\r
+\r
+ } else if (leafExterns.getExternArray(index).isSetModuleUnloadImage()) {\r
+ // Module Unload Image is here in case there is no\r
+ // Entry Point - not very typical\r
+ String moduleUnloadImage = leafExterns.getExternArray(index).getModuleUnloadImage();\r
+ test = checkDuplicateStrings(moduleUnloadImage, aUnloadImageList);\r
+\r
+ } else if (leafExterns.getExternArray(index).isSetConstructor()) {\r
+ // Constructors must be unique, if a Destructor is\r
+ // paired with a constructor, it will pigback on\r
+ // the constructor\r
+ String constructor = leafExterns.getExternArray(index).getConstructor();\r
+ test = checkDuplicateStrings(constructor, aConstructorList);\r
+\r
+ } else if (leafExterns.getExternArray(index).isSetDestructor()) {\r
+ // Destructors must be unique\r
+ String destructor = leafExterns.getExternArray(index).getDestructor();\r
+ test = checkDuplicateStrings(destructor, aDestructorList);\r
+\r
+ } else if (leafExterns.getExternArray(index).isSetDriverBinding()) {\r
+ // Driver Bindings must be unique\r
+ // Fixed the MSA files - ComponentName, Driver Config and\r
+ // Driver Diag statments must be inside of an Extern that \r
+ // has a Driver Binding\r
+ String driverBinding = leafExterns.getExternArray(index).getDriverBinding();\r
+ test = checkDuplicateStrings(driverBinding, aDriverBindingList);\r
+\r
+ } else if (leafExterns.getExternArray(index).isSetSetVirtualAddressMapCallBack()) {\r
+ // Handle Virtual Address Map and Exit Boot Services Call Backs\r
+ // in a single Extern if they are present\r
+ String virtualAddressMap = leafExterns.getExternArray(index)\r
+ .getSetVirtualAddressMapCallBack();\r
+ test = checkDuplicateStrings(virtualAddressMap, aVirtualAddressMapList);\r
+\r
+ } else if (leafExterns.getExternArray(index).isSetExitBootServicesCallBack()) {\r
+ // Handle a stand alone Exit Boot Services Call Back\r
+ String exitBootServices = leafExterns.getExternArray(index)\r
+ .getExitBootServicesCallBack();\r
+ test = checkDuplicateStrings(exitBootServices, aExitBootServicesList);\r
+ } else {\r
+ // Unknown Extern FAIL - May be an invalid Component Name in it's own Extern Statement\r
+ System.out.println("Unknown EXTERN defined in Module: " + leafFilename);\r
+ System.out.println("Value: " + leafExterns.getExternArray(index).toString());\r
+ System.out.println("Merge Aborted!");\r
+ System.err.flush();\r
+ System.exit(FAIL);\r
+ }\r
+\r
+ if (test.length() > 0) {\r
+ mergeExterns.addNewExtern();\r
+ mergeExterns.setExternArray(externsIndex++, leafExterns.getExternArray(index));\r
+ }\r
+ }\r
+ }\r
+ }// endif mergeExterns\r
+\r
+ if (leafMsa.isSetPcdCoded()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Keep only Unique PcdCoded elements, based on the PcdCoded.PcdEntry.C_Name element.\r
+ //\r
+ // If mergePcdCoded == null, create a new mergePcdCoded and add\r
+ // leaf module's PcdCoded section to the merge Module's\r
+ //\r
+ // If mergePcdCoded != null, check that we have only unique PcdEntry entries\r
+ // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
+ // Mark the PcdEntry as ALWAYS_PRODUCED\r
+ // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
+ // Mark the PcdEntry as ALWAYS_CONSUMED\r
+ // It is permissable to have one PRODUCED and one CONSUMED entry\r
+ // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
+ // and another Leaf uses BY_START, create two entries, one for each.\r
+ //\r
+ // First PASS of the TOOL \r
+ // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
+ // this as an error!\r
+ // Probable Enhancement\r
+ // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the FeatureFlag - we are not using it now.\r
+ // Probable Enhancement\r
+ // FeatureFlags must be identical for each unique HiiPackage entry, otherwise fail the Merge\r
+ //\r
+ // First PASS of the TOOL\r
+ // Ignore the PcdEntry:Usage Attribute\r
+ // Probable Enhancment\r
+ // Have Usage Combined like was done for the Library Class\r
+ //\r
+ // First PASS of the TOOL\r
+ // If Different PcdItemTypes, Abort The MERGE\r
+ //\r
+ // Probably Enhancement\r
+ // The PcdItemType Should be checked using the following rules\r
+ // Feature Flag MUST ALWAYS BE A FEATURE FLAG\r
+ // If different Item Types occur, mark the PCD as DYNAMIC\r
+ //\r
+ // HelpText RULE:\r
+ // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
+ // is the leaf Module's path and filename to the MSA file!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // TODO: Code Goes Here!\r
+ if (mergePcdCoded == null)\r
+ mergePcdCoded = PcdCodedDocument.Factory.newInstance().addNewPcdCoded();\r
+\r
+ PcdCoded leafPcdCoded = leafMsa.getPcdCoded();\r
+ if (leafPcdCoded.sizeOfPcdEntryArray() > 0) {\r
+ for (int index = 0; index < leafPcdCoded.sizeOfPcdEntryArray(); index++) {\r
+ String pcdCName = leafPcdCoded.getPcdEntryArray(index).getCName();\r
+ String pcdItemType = leafPcdCoded.getPcdEntryArray(index).getPcdItemType().toString();\r
+ String test = checkPcd(pcdCName, pcdItemType, leafFilename, aPcdCNameList);\r
+ if (test.length() > 0) {\r
+ mergePcdCoded.addNewPcdEntry();\r
+ mergePcdCoded.setPcdEntryArray(pcdIndex++, leafPcdCoded.getPcdEntryArray(index));\r
+ }\r
+ }\r
+ }\r
+\r
+ }// endif PcdCoded\r
+\r
+ if (leafMsa.isSetModuleBuildOptions()) {\r
+ // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
+ //\r
+ // Any element that appear within a leaf's ModuleBuildOptions should be appended to\r
+ // the Merge Module's BuildOptions section.\r
+ //\r
+ // NO ATTEMPT IS MADE TO VERIFY UNIQUENESS ON ANYTHING WITHIN THIS SECTION!\r
+ //\r
+ // Create the working copy if one does not exist!\r
+ // if (mergeBuildOptions == null)\r
+ // mergeBuildOptions = ModuleBuildOptionsDocument.Factory.newInstance().addNewModuleBuildOptions();\r
+\r
+ // ModuleBuildOptions leafModuleBuildOptions = leafMsa.getModuleBuildOptions();\r
+\r
+ // mergeBuildOptions.addNewModuleBuildOptions();\r
+ // mergeBuildOptions.setModuleBuildOptions(leafModuleBuildOptions);\r
+\r
+ //\r
+ // TODO: Code Goes Here!\r
+ } // endif ModuleBuildOptions\r
+\r
+ // Need to process any UserExtensions here too.\r
+ if (leafMsa.getUserExtensionsList() != null) {\r
+\r
+ if (mergeUserExtensions == null)\r
+ mergeUserExtensions = UserExtensionsDocument.Factory.newInstance().addNewUserExtensions();\r
+\r
+ // for (int index = 0; index < leafMsa.getUserExtensionsList().size(); index++)\r
+\r
+ }\r
+\r
+ } // Completed parsing all leaf files.\r
+\r
+ header.setAbstract(Abstract);\r
+ header.setCopyright(Copyright);\r
+ header.setDescription(Description);\r
+ License mLicense = License.Factory.newInstance();\r
+ mLicense.setStringValue(licenseTxt);\r
+ header.setLicense(mLicense);\r
+ if ((DEBUG > 0) || (VERBOSE > 0))\r
+ System.out.println("Merged Module supports: " + sArchitectures + " architectures.");\r
+ List<String> lArchitectures = new ArrayList<String>();\r
+ String s[] = sArchitectures.replace(" ", " ").trim().split(" ");\r
+ for (int idx = 0; idx < s.length; idx++) {\r
+ lArchitectures.add(s[idx]);\r
+ if (DEBUG > 7)\r
+ System.out.println("Adding architecture: " + s[idx]);\r
+ }\r
+ moduleDefs.setSupportedArchitectures(lArchitectures);\r
+\r
+ } // endif mergeMsaFile == null\r
+\r
+ if ((uiName != null) && (uiName.length() > 0) && (result == PASS)) {\r
+ // TODO: Stub for replacing the msaFile UiName\r
+ if ((DEBUG > 0) || (VERBOSE > 0))\r
+ System.out.println("Updating the uiName: " + uiName);\r
+ header.setModuleName(uiName);\r
+ }\r
+\r
+ if ((baseName != null) && (baseName.length() > 0) && (result == PASS)) {\r
+ if ((DEBUG > 0) || (VERBOSE > 0))\r
+ System.out.println("Setting the Output Filename:" + baseName);\r
+ moduleDefs.setOutputFileBasename(baseName);\r
+ }\r
+\r
+ if (result == PASS) {\r
+ // TODO: Stub to write out the new MSA file\r
+ File outMsa = new File(msaFilename);\r
+ try {\r
+ if (DEBUG > 2)\r
+ System.out.println("SAVING new MSA FILE: " + msaFilename);\r
+\r
+ mergeMsaFile.setMsaHeader(header);\r
+ mergeMsaFile.setModuleDefinitions(moduleDefs);\r
+ // ALL THE REST OF THE SECTIONS ARE OPTIONAL\r
+ // SO check that they are not null before adding them to the merged MSA file!\r
+ if (libClassDefs != null)\r
+ mergeMsaFile.setLibraryClassDefinitions(libClassDefs);\r
+ if (mergeSourceFiles != null)\r
+ mergeMsaFile.setSourceFiles(mergeSourceFiles);\r
+ if (mergePackageDependencies != null)\r
+ mergeMsaFile.setPackageDependencies(mergePackageDependencies);\r
+ if (mergeProtocols != null)\r
+ mergeMsaFile.setProtocols(mergeProtocols);\r
+\r
+ if ((mergeCreateEvents != null) || (mergeSignalEvents != null)) {\r
+ if (mergeEvents == null)\r
+ mergeEvents = EventsDocument.Factory.newInstance().addNewEvents();\r
+\r
+ if (mergeCreateEvents.getEventTypesList().size() > 0) {\r
+ mergeEvents.addNewCreateEvents();\r
+ mergeEvents.setCreateEvents(mergeCreateEvents);\r
+ }\r
+ if (mergeSignalEvents.getEventTypesList().size() > 0) {\r
+ mergeEvents.addNewSignalEvents();\r
+ mergeEvents.setSignalEvents(mergeSignalEvents);\r
+ }\r
+\r
+ mergeMsaFile.setEvents(mergeEvents);\r
+ }\r
+\r
+ if (mergeHobs != null)\r
+ mergeMsaFile.setHobs(mergeHobs);\r
+\r
+ if (mergePpis != null)\r
+ mergeMsaFile.setPPIs(mergePpis);\r
+\r
+ if (mergeVariables != null)\r
+ mergeMsaFile.setVariables(mergeVariables);\r
+\r
+ if (mergeBootModes != null)\r
+ mergeMsaFile.setBootModes(mergeBootModes);\r
+\r
+ if (mergeSystemTables != null)\r
+ mergeMsaFile.setSystemTables(mergeSystemTables);\r
+\r
+ if (mergeDataHubs != null)\r
+ mergeMsaFile.setDataHubs(mergeDataHubs);\r
+\r
+ if (mergeHiiPackages != null)\r
+ mergeMsaFile.setHiiPackages(mergeHiiPackages);\r
+\r
+ if (mergeGuids != null)\r
+ mergeMsaFile.setGuids(mergeGuids);\r
+\r
+ if (mergeExterns != null)\r
+ mergeMsaFile.setExterns(mergeExterns);\r
+\r
+ if (mergePcdCoded != null)\r
+ mergeMsaFile.setPcdCoded(mergePcdCoded);\r
+\r
+ XmlCursor cursor = XmlConfig.setupXmlCursor(mergeMsaFile.newCursor());\r
+ XmlOptions options = XmlConfig.setupXmlOptions();\r
+ ModuleSurfaceAreaDocument msaDoc = ModuleSurfaceAreaDocument.Factory.newInstance();\r
+ msaDoc.addNewModuleSurfaceArea();\r
+ msaDoc.setModuleSurfaceArea(mergeMsaFile);\r
+ msaDoc.save(outMsa, options);\r
+ System.out.println("The Merged MSA file: " + msaFilename + ", has been created!");\r
+ } catch (IOException e) {\r
+ System.out.println("Problem writing the output file: " + msaFilename + " " + e);\r
+ result = FAIL;\r
+ }\r
+ }\r
+\r
+ if ((spdFilename != null) && (result == PASS)) {\r
+ // TODO: Stub for adding the msaFile to the <MsaFiles><Filename> in the spdFile\r
+ String msaLine = getPathFromSpd(spdFilename, msaFilename);\r
+ System.out.println("Updating the SPD file (" + spdFilename + ") with: " + msaLine);\r
+ try {\r
+ File spdFile = new File(spdFilename);\r
+ PackageSurfaceAreaDocument spdDoc = PackageSurfaceAreaDocument.Factory.parse(spdFile);\r
+ PackageSurfaceArea spd = spdDoc.getPackageSurfaceArea();\r
+\r
+ // MsaFiles mergeMsaFilesForSpd = MsaFilesDocument.Factory.newInstance().addNewMsaFiles();\r
+ List<String> msaFilenames = spd.getMsaFiles().getFilenameList();\r
+ msaFilenames.add(msaLine);\r
+ XmlCursor cursor = XmlConfig.setupXmlCursor(spd.newCursor());\r
+ XmlOptions options = XmlConfig.setupXmlOptions();\r
+ spdDoc.save(spdFile, options);\r
+ } catch (IOException e) {\r
+ System.out.println("I/O Exception on spd file: " + spdFilename + " " + e);\r
+ } catch (XmlException x) {\r
+ System.out.println("XML Exception on SPD file: " + spdFilename + " " + x);\r
+ }\r
+ } else if ((spdFilename == null) && (result == PASS)) {\r
+\r
+ System.out.println("The file: " + msaFilename + ", must be added to a package file before it can be used!");\r
+ }\r
+ return result;\r
+ }\r
+\r
+ public ModuleSurfaceArea getLeafFile(String filename) {\r
+ File leafMsaFile = new File(filename);\r
+ if ((DEBUG > 1) || (VERBOSE > 1))\r
+ System.out.println("Processing MSA File: " + filename);\r
+ try {\r
+ leafMsa = ModuleSurfaceAreaDocument.Factory.parse(leafMsaFile).getModuleSurfaceArea();\r
+ if ((DEBUG > 4) || (VERBOSE > 4))\r
+ System.out.println("Binary: " + leafMsa.getModuleDefinitions().getBinaryModule());\r
+ if (leafMsa.getModuleDefinitions().getBinaryModule()) {\r
+ System.out.println("ERROR: Binary Module was specified in MSA: " + filename);\r
+ System.out.println("Merge Aborted!");\r
+ System.err.flush();\r
+ return null;\r
+ }\r
+ } catch (IOException e) {\r
+ System.out.println("I/O Exception on filename: " + filename + " " + e);\r
+ System.out.println("Merge Aborted!");\r
+ System.err.flush();\r
+ System.exit(FAIL);\r
+ } catch (XmlException x) {\r
+ System.out.println("XML Exception reading file: " + filename + " " + x);\r
+ System.out.println("Merge Aborted!");\r
+ System.err.flush();\r
+ System.exit(FAIL);\r
+ }\r
+ return leafMsa;\r
+ }\r
+\r
+ private String getPathFromSpd(String spdFn, String msaFn) {\r
+ String path2Msa = null;\r
+\r
+ spdFn = spdFn.replace("\\", "/").trim();\r
+ String s[] = spdFn.split("/");\r
+ String justSpdFilename = s[s.length - 1];\r
+\r
+ String Cwd = System.getProperty("user.dir");\r
+ Cwd = Cwd.replace("\\", "/").trim();\r
+ if ((DEBUG > 10) || (VERBOSE > 10)) {\r
+ System.out.println("Current directory = " + Cwd);\r
+ }\r
+ String sp[] = Cwd.split("/");\r
+ int theDirectory = sp.length - (s.length - 1);\r
+ if (DEBUG > 10)\r
+ System.out.println("The Directory length: " + theDirectory + " s.length: " + s.length + " sp.length: "\r
+ + (sp.length - 1));\r
+\r
+ String path2Spd = "";\r
+ for (int ictr = 0; ictr < theDirectory; ictr++) {\r
+ path2Spd += sp[ictr] + "/";\r
+ if (DEBUG > 10)\r
+ System.out.println("Creating path to SPD file: " + path2Spd);\r
+ }\r
+\r
+ String testPath2Spd = path2Spd + justSpdFilename;\r
+\r
+ File tFile = new File(testPath2Spd);\r
+ if (!tFile.exists()) {\r
+ System.out.println("The specified SPD file, " + spdFn + " does not exist at: " + testPath2Spd);\r
+ System.out.println("Please use the FrameworkWizard to add this MSA file to the package.");\r
+ System.exit(FAIL);\r
+ }\r
+ path2Msa = Cwd.replace(path2Spd, "");\r
+ path2Msa = path2Msa + "/" + msaFn;\r
+ return path2Msa;\r
+ }\r
+\r
+ private String checkDuplicateStrings(String aString, ArrayList<String> aList) {\r
+\r
+ for (int lctr = 0; lctr < aList.size(); lctr++) {\r
+ if (DEBUG > 8)\r
+ System.out.println("Comparing: \n" + aString.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
+ + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
+ if (aString.replace(" ", "").replace("\n", "").contains(\r
+ aList.get(lctr).replace(" ", "").replace("\n", "")\r
+ .toString().trim())) {\r
+ if ((DEBUG > 3) || (VERBOSE > 3))\r
+ System.out.println("Found a duplicate String, skipping!");\r
+ return "";\r
+ }\r
+ }\r
+ if ((DEBUG > 3) || (VERBOSE > 3))\r
+ System.out.println("Returning UNIQUE String!\n " + aString);\r
+ aList.add(aString);\r
+ return aString;\r
+ }\r
+\r
+ private String checkSpecs(String specName, String filename, ArrayList<String> aList) {\r
+ // Check Specifications\r
+ // Skip of Specs are identical\r
+ String spec[] = new String[2];\r
+ spec = specName.replace(" ", " ").trim().split(" ");\r
+ String specInMem[] = new String[2];\r
+ if ((DEBUG > 10) || (VERBOSE > 10))\r
+ System.out.println("Specification: " + specName);\r
+\r
+ for (int lctr = 0; lctr < aList.size(); lctr++) {\r
+ if (DEBUG > 8)\r
+ System.out.println("Comparing: \n" + specName.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
+ + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
+ if (specName.replace(" ", "").replace("\n", "").contains(\r
+ aList.get(lctr).replace(" ", "").replace("\n", "")\r
+ .toString().trim())) {\r
+ if ((DEBUG > 3) || (VERBOSE > 3))\r
+ System.out.println("Found a duplicate String, skipping!");\r
+ return "";\r
+ }\r
+ specInMem = aList.get(lctr).replace(" ", " ").trim().split(" ");\r
+ if (spec[0].contentEquals(specInMem[0])) {\r
+ if (!spec[1].contains(specInMem[1])) {\r
+ System.out.println("Module: " + filename + " is coded to " + specName);\r
+ System.out.println("Merge needs to be coded to: " + aList.get(lctr));\r
+ System.out.println("Merge Aborted!");\r
+ System.err.flush();\r
+ System.exit(FAIL);\r
+ }\r
+ }\r
+\r
+ }\r
+ if ((DEBUG > 3) || (VERBOSE > 3))\r
+ System.out.println("Returning Specification: " + specName);\r
+ aList.add(specName);\r
+ return specName;\r
+ }\r
+\r
+ private String checkPcd(String pcdName, String itemType, String filename, ArrayList<String> aList) {\r
+\r
+ for (int lctr = 0; lctr < aList.size(); lctr++) {\r
+ if (DEBUG > 8)\r
+ System.out.println("Comparing: \n" + pcdName.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
+ + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
+ if (pcdName.replace(" ", "").replace("\n", "").contains(\r
+ aList.get(lctr).replace(" ", "").replace("\n", "")\r
+ .toString().trim())) {\r
+ if (!aPcdItemTypeList.get(lctr).contains(itemType)) {\r
+ System.out\r
+ .println("The Pcd Item Type for " + pcdName + " in file: " + filename + "does not match!");\r
+ System.out.println("Expected: " + aPcdItemTypeList.get(lctr));\r
+ System.out.println("Was set to: " + itemType);\r
+ System.out.println("Merge Aborted!");\r
+ System.err.flush();\r
+ System.exit(FAIL);\r
+ }\r
+ if ((DEBUG > 3) || (VERBOSE > 3))\r
+ System.out.println("Found a duplicate String, skipping!");\r
+ return "";\r
+ }\r
+ }\r
+ if ((DEBUG > 3) || (VERBOSE > 3))\r
+ System.out.println("Returning UNIQUE String!\n " + pcdName);\r
+ aPcdItemTypeList.add(itemType);\r
+ aList.add(pcdName);\r
+ return pcdName;\r
+ }\r
+\r
+ private String checkUsage() {\r
+ String result = "";\r
+ // Usage types are different\r
+ if (((mergeUsage.contains("CONSUMED")) && (leafUsage.contains("PRODUCED")))\r
+ || ((mergeUsage.contains("PRODUCED")) && (leafUsage.contains("CONSUMED")))\r
+ || ((mergeUsage.contains("TO_START")) && (leafUsage.contains("BY_START")))\r
+ || ((mergeUsage.contains("BY_START")) && (leafUsage.contains("TO_START")))) {\r
+ result = "DIFFERENT";\r
+ }\r
+ // Both Usage types are PRODUCED\r
+ if (((mergeUsage.contains("ALWAYS_PRODUCED")) && (leafUsage.contains("SOMETIMES_PRODUCED")))\r
+ || ((mergeUsage.contains("SOMETIMES_PRODUCED")) && (leafUsage.contains("ALWAYS_PRODUCED")))) {\r
+ result = "PRODUCED";\r
+ }\r
+\r
+ // Both Usage types are CONSUMED\r
+ if (((mergeUsage.contains("ALWAYS_CONSUMED")) && (leafUsage.contains("SOMETIMES_CONSUMED")))\r
+ || ((mergeUsage.contains("SOMETIMES_CONSUMED")) && (leafUsage.contains("ALWAYS_CONSUMED")))) {\r
+ result = "CONSUMED";\r
+ }\r
+ return result;\r
+ }\r
+\r
+ private boolean checkProduced() {\r
+ boolean result = false;\r
+\r
+ if (((mergeUsage.contains("ALWAYS_PRODUCED")) && (leafUsage.contains("SOMETIMES_PRODUCED")))\r
+ || ((mergeUsage.contains("SOMETIMES_PRODUCED")) && (leafUsage.contains("ALWAYS_PRODUCED")))) {\r
+ result = true;\r
+ }\r
+ return result;\r
+ }\r
+\r
+ private boolean checkConsumed() {\r
+ boolean result = false;\r
+\r
+ if (((mergeUsage.contains("ALWAYS_CONSUMED")) && (leafUsage.contains("SOMETIMES_CONSUMED")))\r
+ || ((mergeUsage.contains("SOMETIMES_CONSUMED")) && (leafUsage.contains("ALWAYS_CONSUMED")))) {\r
+ result = true;\r
+ }\r
+ return result;\r
+ }\r
+\r
+ private String getPathPartOfLeafMsa(String sFilename) {\r
+ String pathName = "";\r
+ String s[] = sFilename.replace("\\", "/").trim().split("/");\r
+ for (int j = 0; j < (s.length - 1); j++) {\r
+ pathName += s[j] + "/";\r
+ }\r
+ return pathName;\r
+ }\r
+\r
+ private static class XmlConfig {\r
+ public static XmlCursor setupXmlCursor(XmlCursor cursor) {\r
+ String uri = "http://www.TianoCore.org/2006/Edk2.0";\r
+ cursor.push();\r
+ cursor.toNextToken();\r
+ cursor.insertNamespace("", uri);\r
+ cursor.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");\r
+ cursor.pop();\r
+ return cursor;\r
+\r
+ }\r
+\r
+ public static XmlOptions setupXmlOptions() {\r
+ XmlOptions options = new XmlOptions();\r
+ options.setCharacterEncoding("UTF-8");\r
+ options.setSavePrettyPrint();\r
+ options.setSavePrettyPrintIndent(2);\r
+ return options;\r
+ }\r
+\r
+ }\r
+}\r