Removed dead lines that had been commented out.
[mirror_edk2.git] / Tools / Source / Merge / src / org / tianocore / Merge / CombineMsa.java
CommitLineData
0e771cd3 1// @file\r
2// This Class processes multiple MSA files and merges them into a single, \r
3// merged MSA file. It will optionally add the merged MSA file into a package.\r
4//\r
5//\r
6// Copyright (c) 2006, Intel Corporation All rights reserved.\r
7//\r
8// This program and the accompanying materials are licensed and made\r
9// available under the terms and conditions of the BSD License which\r
10// accompanies this distribution. The full text of the license may \r
11// be found at http://opensource.org/licenses/bsd-license.php\r
12//\r
13// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15//\r
16//\r
17\r
18package org.tianocore.Merge;\r
19\r
20import java.io.*;\r
21import java.util.*;\r
22// import java.lang.*;\r
23// import java.lang.ExceptionInInitializerError;\r
24\r
25// import org.apache.xmlbeans.*;\r
26import org.apache.xmlbeans.XmlCursor;\r
27// import org.apache.xmlbeans.XmlObject;\r
28import org.apache.xmlbeans.XmlOptions;\r
29import org.apache.xmlbeans.XmlException;\r
30import org.tianocore.*;\r
31\r
32// import org.tianocore.*;\r
33import org.tianocore.ModuleSurfaceAreaDocument.*;\r
34import org.tianocore.MsaHeaderDocument.*;\r
35import org.tianocore.LicenseDocument.*;\r
36import org.tianocore.ModuleDefinitionsDocument.*;\r
37import org.tianocore.LibraryClassDefinitionsDocument.*;\r
38import org.tianocore.SourceFilesDocument.*;\r
39import org.tianocore.PackageDependenciesDocument.*;\r
40import org.tianocore.ProtocolsDocument.*;\r
41import org.tianocore.EventsDocument.*;\r
42import org.tianocore.HobsDocument.*;\r
43import org.tianocore.PPIsDocument.*;\r
44import org.tianocore.VariablesDocument.*;\r
45import org.tianocore.BootModesDocument.*;\r
46import org.tianocore.SystemTablesDocument.*;\r
47import org.tianocore.DataHubsDocument.*;\r
48import org.tianocore.HiiPackagesDocument.*;\r
49import org.tianocore.GuidsDocument.*;\r
50import org.tianocore.ExternsDocument.*;\r
51import org.tianocore.PcdCodedDocument.*;\r
52import org.tianocore.ModuleBuildOptionsDocument.*;\r
53import org.tianocore.UserExtensionsDocument.*;\r
54\r
55import org.tianocore.PackageSurfaceAreaDocument.*;\r
0e771cd3 56\r
57public class CombineMsa {\r
58\r
59 private final int DEBUG = 0;\r
60\r
61 private final int PASS = 0;\r
62\r
63 private final int FAIL = 1;\r
64\r
65 private final int FOUND = 0;\r
66\r
67 private final int NOTFOUND = 1;\r
68\r
69 private int result = PASS;\r
70\r
71 private String licenseTxt = "";\r
72\r
73 private ArrayList<String> aLicenses = new ArrayList<String>();\r
74\r
75 private String Copyright = "";\r
76\r
77 private ArrayList<String> aCopyright = new ArrayList<String>();\r
78\r
79 private String Abstract = "\n Merged Modules: \n";\r
80\r
81 private String Description = "\n Merging Modules: \n";\r
82\r
83 private String sArchitectures = "";\r
84\r
85 private MsaHeader header = null;\r
86\r
87 private final String Specification = "FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052";\r
88\r
89 private ModuleSurfaceArea mergeMsaFile = null;\r
90\r
91 private ModuleSurfaceArea leafMsa = null;\r
92\r
93 private ModuleDefinitions moduleDefs = null;\r
94\r
95 private LibraryClassDefinitions libClassDefs = null;\r
96\r
97 private ArrayList<String> aLibClassDefs = new ArrayList<String>();\r
98\r
99 private int libraryClassIndex = 0;\r
100\r
101 private SourceFiles mergeSourceFiles = null;\r
102\r
103 private int sourceFileIndex = 0;\r
104\r
105 private PackageDependencies mergePackageDependencies = null;\r
106\r
107 private ArrayList<String> aPackageList = new ArrayList<String>();\r
108\r
109 private int packageDependenciesIndex = 0;\r
110\r
111 private Protocols mergeProtocols = null;\r
112\r
113 private ArrayList<String> aProtocolList = new ArrayList<String>();\r
114\r
115 private ArrayList<String> aProtocolNotifyList = new ArrayList<String>();\r
116\r
117 private int protocolIndex = 0;\r
118\r
119 private int protocolNotifyIndex = 0;\r
120\r
121 private Events mergeEvents = null;\r
122\r
123 private Events.CreateEvents mergeCreateEvents = null;\r
124\r
125 private Events.SignalEvents mergeSignalEvents = null;\r
126\r
127 private ArrayList<String> aCreateEventsList = new ArrayList<String>();\r
128\r
129 private ArrayList<String> aSignalEventsList = new ArrayList<String>();\r
130\r
131 private int createEventIndex = 0;\r
132\r
133 private int signalEventIndex = 0;\r
134\r
135 private Hobs mergeHobs = null;\r
136\r
137 private ArrayList<String> aHobsList = new ArrayList<String>();\r
138\r
139 private int hobsIndex = 0;\r
140\r
141 private PPIs mergePpis = null;\r
142\r
143 private ArrayList<String> aPpiList = new ArrayList<String>();\r
144\r
145 private ArrayList<String> aPpiNotifyList = new ArrayList<String>();\r
146\r
147 private int ppiIndex = 0;\r
148\r
149 private int ppiNotifyIndex = 0;\r
150\r
151 private Variables mergeVariables = null;\r
152\r
153 private ArrayList<String> aVariablesList = new ArrayList<String>();\r
154\r
155 private int variablesIndex = 0;\r
156\r
157 private BootModes mergeBootModes = null;\r
158\r
159 private ArrayList<String> aBootModesList = new ArrayList<String>();\r
160\r
161 private int bootModesIndex = 0;\r
162\r
163 private SystemTables mergeSystemTables = null;\r
164\r
165 private ArrayList<String> aSystemTablesList = new ArrayList<String>();\r
166\r
167 private int systemTableIndex = 0;\r
168\r
169 private DataHubs mergeDataHubs = null;\r
170\r
171 private ArrayList<String> aDataHubsList = new ArrayList<String>();\r
172\r
173 private int dataHubsIndex = 0;\r
174\r
175 private HiiPackages mergeHiiPackages = null;\r
176\r
177 private ArrayList<String> aHiiPackagesList = new ArrayList<String>();\r
178\r
179 private int hiiPackageIndex = 0;\r
180\r
181 private Guids mergeGuids = null;\r
182\r
183 private ArrayList<String> aGuidsList = new ArrayList<String>();\r
184\r
185 private int guidsIndex = 0;\r
186\r
187 private Externs mergeExterns = null;\r
188\r
189 private ArrayList<String> aEntryPointList = new ArrayList<String>();\r
190\r
191 private ArrayList<String> aUnloadImageList = new ArrayList<String>();\r
192\r
193 private ArrayList<String> aDriverBindingList = new ArrayList<String>();\r
194\r
195 private ArrayList<String> aConstructorList = new ArrayList<String>();\r
196\r
197 private ArrayList<String> aDestructorList = new ArrayList<String>();\r
198\r
199 private ArrayList<String> aVirtualAddressMapList = new ArrayList<String>();\r
200\r
201 private ArrayList<String> aExitBootServicesList = new ArrayList<String>();\r
202\r
203 private int externsIndex = 0;\r
204\r
205 private ArrayList<String> aSpecArray = new ArrayList<String>();\r
206\r
207 private int specIndex = 0;\r
208\r
209 private PcdCoded mergePcdCoded = null;\r
210\r
211 private ArrayList<String> aPcdCNameList = new ArrayList<String>();\r
212\r
213 private ArrayList<String> aPcdItemTypeList = new ArrayList<String>();\r
214\r
215 private int pcdIndex = 0;\r
216\r
217 private ModuleBuildOptions mergeBuildOptions = null;\r
218\r
219 private UserExtensions mergeUserExtensions = null;\r
220\r
0e771cd3 221 private String mergeUsage = "";\r
222\r
223 private String leafUsage = "";\r
224\r
225 private int VERBOSE = 0;\r
226\r
227 // The combineMsaFiles routine is the primary routine for creating a \r
228 // Merged MSA file.\r
229\r
230 public int combineMsaFiles(String msaFilename, ArrayList<String> msaFiles, String uiName, String spdFilename,\r
231 String baseName, int Flags) {\r
232 // msaFile has been verified to either not exist, or, if it does exist, \r
233 // it will be over written.\r
234 // All files in the msaFiles ArrayList have been verifed to exist.\r
235 // If the uiName is not null, we will have a new UI Name for the merged \r
236 // module.\r
237 // If the uiName is null, we will use the module name from the first \r
238 // Leaf module.\r
239 // If the spdFile is not null, the Package (SPD) file has been verified \r
240 // to exist.\r
241 // If the spdFile is null, don't attempt to add the new msa file.\r
242\r
243 if (Flags > 0)\r
244 VERBOSE = 1;\r
245 if (mergeMsaFile == null) {\r
246 //\r
247 // create the data structure for the merged Module\r
248 //\r
249 mergeMsaFile = ModuleSurfaceArea.Factory.newInstance();\r
250\r
251 System.out.println("Merging " + msaFiles.size() + " Modules");\r
252 //\r
253 // we always require a Header and a Module Definition section.\r
254 // These will be added to the mergeMsaFile after we have completed \r
255 // all processing of the Leaf MSA files.\r
256 //\r
257 header = MsaHeaderDocument.Factory.newInstance().addNewMsaHeader();\r
258 moduleDefs = ModuleDefinitionsDocument.Factory.newInstance().addNewModuleDefinitions();\r
259 //\r
260 // A merged module cannot be created from binary modules - we force \r
261 // the new module to be source here, however we will test every \r
262 // module to make sure that none are binary; exiting the program if\r
263 // a module is binary\r
264 //\r
265 moduleDefs.setBinaryModule(false);\r
266\r
267 for (int i = 0; i < msaFiles.size(); i++) {\r
268 String leafFilename = msaFiles.get(i).toString();\r
269 leafMsa = getLeafFile(leafFilename);\r
270 if (leafMsa == null) {\r
271 System.out.println("Could not read Leaf MSA file: " + leafFilename);\r
272 System.exit(FAIL);\r
273 }\r
274 if (i == 0) {\r
275 //\r
276 // Special code for first file, since this file is used \r
277 // to initialize some of the data in the mergeMsaFile. \r
278 // Set the Merge module's ModuleName to the name in the \r
279 // first Leaf Module. If a new module name is given, \r
280 // over write it later, just before writing the Merge \r
281 // Module MSA file.\r
282 header.setModuleName(leafMsa.getMsaHeader().getModuleName().toString());\r
283 //\r
284 // All modules must be of the same module type, we set it \r
285 // here, and test the other Leaf modules' type later.\r
286 header.setModuleType(leafMsa.getMsaHeader().getModuleType());\r
287 //\r
288 // This is a new Module, so we need a new GUID\r
289 header.setGuidValue(UUID.randomUUID().toString());\r
290 //\r
291 // Use the version from the first Leaf module as the \r
292 // Merge Module version number.\r
293 header.setVersion(leafMsa.getMsaHeader().getVersion().toString());\r
294 //\r
295 // There is no special requirement for processing the \r
296 // following, so we just fall through on these elements \r
297 // of the header.\r
298 // Abstract will be added after parsing all leaf MSA files.\r
299 // Description will be added after parsing all leaf MSA files.\r
300 // Copyright will be added after parsing all leaf MSA files.\r
301 // License will be added after parsing all leaf MSA files.\r
302 //\r
303 // Force the specification to match this tool's spec version.\r
304 header.setSpecification(Specification);\r
305 //\r
306 // Set the Merged Module's Output Basename to match the first \r
307 // leaf module\r
308 String OutputFileName = leafMsa.getModuleDefinitions().getOutputFileBasename().toString();\r
309 //\r
310 // Just in case someone put a space character in the first\r
311 // leaf module's output filename, replace the spaces with\r
312 // an underscore.\r
313 OutputFileName.replace(" ", "_");\r
314 moduleDefs.setOutputFileBasename(OutputFileName);\r
315 //\r
316 // We start with the first module's list of supported \r
317 // architectures. As we process the additional leaf modules,\r
318 // we may have to remove some supported architectures from \r
319 // the list, as we can only build for the "least common \r
320 // denominator" subset of architectures.\r
321 sArchitectures = leafMsa.getModuleDefinitions().getSupportedArchitectures().toString();\r
322 if ((DEBUG > 5) || (VERBOSE > 5))\r
323 System.out.println("New Header: \"" + header.getModuleName().toString() + "\"");\r
324 }\r
325 //\r
326 // We test the license in each leaf module, and will only print\r
327 // licenses that are may be different in wording (white spaces \r
328 // and line feeds are ignored in this test.)\r
329 if (leafMsa.getMsaHeader().getLicense() != null)\r
330 licenseTxt += checkDuplicateStrings(leafMsa.getMsaHeader().getLicense().getStringValue().trim(),\r
331 aLicenses);\r
332 if ((DEBUG > 10) || (VERBOSE > 10))\r
333 System.out.println("License: " + licenseTxt);\r
334 //\r
335 // We test the copyright line from each leaf module, and will \r
336 // add additional copyright lines only if they are different \r
337 // in wording (white spaces and line feeds are ignored in this\r
338 // test.)\r
339 if (leafMsa.getMsaHeader().getCopyright() != null)\r
340 Copyright += checkDuplicateStrings(leafMsa.getMsaHeader().getCopyright().toString().trim(),\r
341 aCopyright);\r
342 if ((DEBUG > 10) || (VERBOSE > 10))\r
343 System.out.println("Copyright: " + Copyright);\r
344 //\r
345 // ALL leaf modules must be of the same Module Type, if not, \r
346 // print an error and exit.\r
347 if (header.getModuleType() != leafMsa.getMsaHeader().getModuleType()) {\r
348 System.out.println("ERROR: Module Types different!");\r
349 System.out.println(" Expected: " + header.getModuleType());\r
350 System.out.println(" " + leafFilename + " ModuleType: " + leafMsa.getMsaHeader().getModuleType());\r
351 System.out.println("Merge ABORTED!");\r
352 System.exit(FAIL);\r
353 }\r
354 //\r
355 // Combine the Abstract and Descriptions into a single \r
356 // description entry, prefixing each with the Leaf MSA filename,\r
357 // so you know which description is from which Leaf module.\r
358 Description += " -- " + leafFilename + " -- \n Abstract: "\r
359 + leafMsa.getMsaHeader().getAbstract().toString() + "\n Description: "\r
360 + leafMsa.getMsaHeader().getDescription().toString() + "\n";\r
361 //\r
362 // Use the Abstract of the Merged Module to list the Leaf \r
363 // Module's MSA files.\r
364 Abstract += " -- " + leafFilename + " -- \n";\r
365 //\r
366 // Ignore ClonedFrom right now\r
367 //\r
368\r
369 // Process Supported Architectures\r
370 // A merged module supports the lowest common set of \r
371 // architectures\r
372 String testArch = "";\r
373 if (leafMsa.getModuleDefinitions().getSupportedArchitectures() == null) {\r
374 System.out\r
375 .println("Module " + leafFilename + " does not have the Supported Architectures defined!");\r
376 System.out.println("Supported Architectures is a required element!");\r
377 System.out.println("Merge ABORTED!");\r
378 System.exit(FAIL);\r
379 }\r
380 testArch = leafMsa.getModuleDefinitions().getSupportedArchitectures().toString();\r
381 String aArch[] = sArchitectures.split(" ");\r
382 for (int ictr = 0; ictr < aArch.length; ictr++) {\r
383 if (!testArch.contains(aArch[ictr])) {\r
384 sArchitectures = sArchitectures.replace(aArch[ictr], "");\r
385 }\r
386 }\r
387 if (sArchitectures.length() < 2) {\r
388 System.out.println("ERROR: The Leaf Modules' Supported Architectures are mutually exclusive.");\r
389 System.out.println("At least one architecture must be common to all Leaf Modules!");\r
390 System.out.println("Merge Aborting!");\r
391 System.exit(FAIL);\r
392 }\r
393 //\r
394 // Now start to process the rest of the Leaf Module's MSA files.\r
395 // We will only test a Leaf module's section if it has data, skipping\r
396 // empty sections\r
397 // As part of this process, we will only create a Library Class Definition\r
398 // if one was defined, and we will only do it one time.\r
399 if (leafMsa.isSetLibraryClassDefinitions()) {\r
400 // \r
401 // If libClassDefs == null, create a new libClassDefs and add\r
402 // this module's libClassDefs to the merge Module's\r
403 // If libClassDefs != null, check that we have only unique LibraryClass entries\r
404 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
405 // Mark the LibraryClass as ALWAYS_PRODUCED\r
406 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
407 // Mark the LibraryClass as ALWAYS_CONSUMED\r
408 // It is permissable to have one PRODUCED and one CONSUMED entry\r
409 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
410 // and another Leaf uses BY_START, create two entries, one for each.\r
411 //\r
412 // The RecommendedInstance attributes can be ignored!\r
413 //\r
414 // First PASS of the TOOL \r
415 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
416 // this as an error!\r
417 // Probable Enhancement\r
418 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
419 //\r
420 // First PASS of the TOOL\r
421 // The SupModuleList must be identical for all Leaf Modules!\r
422 // Probable Enhancement\r
423 // The SupModuleList should be combined to include all possible supported module types.\r
424 //\r
425 // First PASS of the TOOL\r
426 // Ignore the FeatureFlag - we are not using it now.\r
427 // Probable Enhancement\r
428 // FeatureFlags must be identical for each LibraryClass, otherwize fail the Merge\r
429 //\r
430 // Create the working copy if one does not exist!\r
431 if (libClassDefs == null)\r
432 libClassDefs = LibraryClassDefinitionsDocument.Factory.newInstance()\r
433 .addNewLibraryClassDefinitions();\r
434 //\r
435 // Get the Leaf LibraryClassDefinitions Section\r
436 LibraryClassDefinitions leafLibClassDef = leafMsa.getLibraryClassDefinitions();\r
437 //\r
438 // We only need to test there are entries in the Leaf LibraryClassDefinitions section!\r
439 if (leafLibClassDef.getLibraryClassList().size() > 0) {\r
440 for (int index = 0; index < leafLibClassDef.getLibraryClassList().size(); index++) {\r
441 //\r
442 // We can use the Keyword to search to see if the Leaf's Library Class was already\r
443 // added to the Merge Module.\r
444 String test = "";\r
445 String leafKeyword = leafLibClassDef.getLibraryClassList().get(index).getKeyword()\r
446 .toString().trim();\r
447\r
448 leafUsage = "";\r
449 if (leafLibClassDef.getLibraryClassList().get(index).getUsage() != null)\r
450 leafUsage = leafLibClassDef.getLibraryClassList().get(index).getUsage().toString()\r
451 .trim();\r
452\r
453 String leafSupArchList = "";\r
454 if (leafLibClassDef.getLibraryClassList().get(index).getSupArchList() != null)\r
455 leafSupArchList = leafLibClassDef.getLibraryClassList().get(index).getSupArchList()\r
456 .toString().trim();\r
457\r
458 String leafSupModuleList = "";\r
459 if (leafLibClassDef.getLibraryClassList().get(index).getSupModuleList() != null)\r
460 leafSupModuleList = leafLibClassDef.getLibraryClassList().get(index).getSupModuleList()\r
461 .toString().trim();\r
462\r
463 test = checkDuplicateStrings(leafKeyword, aLibClassDefs);\r
464 if (test.length() > 0) {\r
465 // The checkDuplicateStrings returns "" if a duplicate was found.\r
466 // Here, the Leaf LibraryClass gets entered because the Keyword was not found.\r
467 // No more testing is required, since this is the first instance of the LibraryClass\r
468 libClassDefs.addNewLibraryClass();\r
469 libClassDefs.setLibraryClassArray(libraryClassIndex++,\r
470 leafLibClassDef.getLibraryClassList().get(index));\r
471 } else {\r
472 // The Merged Module has already specified the Library Class\r
473 // Check ATTRIBUTES, following the rules above.\r
474 // Since we cannot get the LibraryClass entry using the Keyword, we have to search\r
475 // all of the Merged Module's LibraryClass statements until we find a match.\r
476 // Also, we may have more than one LibraryClass with the same Keyword, but different\r
477 // Usage, SupArchList, FeatureFlag or SupModuleList\r
478 for (int nidx = 0; nidx < libraryClassIndex; nidx++) {\r
479 String mergeKeyword = libClassDefs.getLibraryClassList().get(nidx).getKeyword()\r
480 .trim();\r
481\r
482 if (leafKeyword.contentEquals(mergeKeyword)) {\r
483 // We have the FIRST match, let's check usage, remember, we can have more than one LibraryClass Keyword.\r
484 mergeUsage = libClassDefs.getLibraryClassList().get(nidx).getUsage().toString()\r
485 .trim();\r
486 // If the usage is identical, check the SupArchList next\r
487 if (!leafUsage.contentEquals(mergeUsage)) {\r
488 if (checkUsage().trim().contains("DIFFERENT")) {\r
489 // See if there is another entry for PRODUCED or CONSUME\r
490 int anotherLC = NOTFOUND;\r
491 for (int iidx = nidx + 1; iidx < libraryClassIndex; iidx++) {\r
492 String innerTestKeyword = libClassDefs.getLibraryClassList()\r
493 .get(iidx).getKeyword()\r
494 .toString().trim();\r
495 if (leafKeyword.contentEquals(innerTestKeyword)) {\r
496 anotherLC = FOUND;\r
497 mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
498 .getUsage().toString().trim();\r
499 if (checkProduced()) {\r
500 libClassDefs\r
501 .getLibraryClassList()\r
502 .get(iidx)\r
503 .setUsage(\r
504 org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
505 }\r
506 // Both Usage types are CONSUMED\r
507 if (checkConsumed()) {\r
508 libClassDefs\r
509 .getLibraryClassList()\r
510 .get(iidx)\r
511 .setUsage(\r
512 org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
513 }\r
514 if (((mergeUsage.contains("TO_START")) && (leafUsage\r
515 .contains("TO_START"))))\r
516 anotherLC = FOUND;\r
517 if (((mergeUsage.contains("BY_START")) && (leafUsage\r
518 .contains("BY_START"))))\r
519 anotherLC = FOUND;\r
520 }\r
521 }\r
522 if (anotherLC == NOTFOUND) {\r
523 // we need to add the leaf Library Class\r
524 libClassDefs.addNewLibraryClass();\r
525 libClassDefs\r
526 .setLibraryClassArray(\r
527 libraryClassIndex++,\r
528 leafLibClassDef\r
529 .getLibraryClassList()\r
530 .get(index));\r
531 }\r
532 }\r
533\r
534 // Both Usage types are PRODUCED\r
535 if (checkUsage().trim().contains("PRODUCED")) {\r
536 libClassDefs.getLibraryClassList().get(nidx)\r
537 .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
538 }\r
539 // Both Usage types are CONSUMED\r
540 if (checkUsage().trim().contains("CONSUMED")) {\r
541 libClassDefs.getLibraryClassList().get(nidx)\r
542 .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
543 }\r
544 }\r
545 // Usage testing completed\r
546 // Check SupArchList\r
547 String mergeSupArchList = "";\r
548 if (libClassDefs.getLibraryClassList().get(nidx).getSupArchList() != null)\r
549 mergeSupArchList = libClassDefs.getLibraryClassList().get(nidx)\r
550 .getSupArchList().toString().trim();\r
551 if (!mergeSupArchList.equalsIgnoreCase(leafSupArchList)) {\r
552 System.out\r
553 .println("ERROR: Library Class, keyword: " + leafKeyword\r
554 + " defines a different set of supported architectures.");\r
555 System.out\r
556 .println("Version 0.1 of the merge tool requires that they must be identical!");\r
557 System.out.println("First instance of the Library used: "\r
558 + mergeSupArchList);\r
559 System.out.println("While this module, " + leafFilename + " uses: "\r
560 + leafSupArchList);\r
561 System.out.println("Merge ABORTED!");\r
562 System.exit(FAIL);\r
563 }\r
564 // Architecture Testing completed\r
565 // Check SupModuleType\r
566 String mergeSupModuleList = "";\r
567 if (libClassDefs.getLibraryClassList().get(nidx).getSupModuleList() != null)\r
568 mergeSupModuleList = libClassDefs.getLibraryClassList().get(nidx)\r
569 .getSupModuleList().toString().trim();\r
570 if (!mergeSupModuleList.equalsIgnoreCase(leafSupModuleList)) {\r
571 System.out.println("ERROR: Library Class, keyword: " + leafKeyword\r
572 + " defines a different set of supported modules.");\r
573 System.out\r
574 .println("Version 0.1 of the merge tool requires that they must be identical!");\r
575 System.out.println("First instance of the Library used: "\r
576 + mergeSupModuleList);\r
577 System.out.println("While this module, " + leafFilename + " uses: "\r
578 + leafSupModuleList);\r
579 System.out.println("Merge ABORTED!");\r
580 System.exit(FAIL);\r
581 }\r
582 // Supported Module Testing completed\r
583 // Check FeatureFlage\r
584 // Next version, not this one.\r
585 }\r
586 } // end of processing of duplicate Library Class entries\r
587 } // end duplicate entry\r
588 } // end of test loop for duplicates \r
589 } // endif Merge Module LibraryModuleDefinitions existed\r
590 } // endif of LibraryModuleDefinition Tests\r
591\r
592 if (leafMsa.isSetSourceFiles()) {\r
593 // TODO: test for NULL settings\r
594 // Add Sourcefiles to the Merge Module. NOTE: ONLY MODIFY THE Filename, prepending the path to the MSA file.\r
595 // First get the path portion of the leafMSA file, which will be prepended to the filename\r
596 // everything else stays intact.\r
597 if (mergeSourceFiles == null)\r
598 mergeSourceFiles = SourceFilesDocument.Factory.newInstance().addNewSourceFiles();\r
599\r
600 String pathToMsa = getPathPartOfLeafMsa(leafFilename);\r
601 if (DEBUG > 10)\r
602 System.out.println("PATH TO SOURCE FILES: " + pathToMsa);\r
603 if (leafMsa.getSourceFiles().getFilenameList() != null) {\r
604 List<FilenameDocument.Filename> leafSourceFiles = leafMsa.getSourceFiles().getFilenameList();\r
605 for (int index = 0; index < leafSourceFiles.size(); index++) {\r
606 String leafFile = leafSourceFiles.get(index).getStringValue().toString();\r
607 leafFile = pathToMsa + leafFile;\r
608 leafSourceFiles.get(index).setStringValue(leafFile);\r
609 mergeSourceFiles.addNewFilename();\r
610 mergeSourceFiles.setFilenameArray(sourceFileIndex++, leafSourceFiles.get(index));\r
611 }\r
612 }\r
613 }\r
614\r
615 if (leafMsa.isSetPackageDependencies()) {\r
616 //\r
617 // If mergePackageDependencies == null, create a new mergePackageDependencies and\r
618 // add the leaf module's Package Dependencies section to the merge Module's\r
619 // If mergePackageDependencies != null, test the leaf Package entries against\r
620 // what has already been added to the mergePackageDependencies data structure.\r
621 //\r
622 // Add Unique Package entries.\r
623 // For this Merge Tool a Package is defined as PackageGuid\r
624 //\r
625 // ABORT THE MERGE WITH FAIL if the PACKAGE VERSION NUMBERS ARE DIFFERENT\r
626 // between Leaf modules\r
627 //\r
628 // Version 0.1 of the tool\r
629 // SupArchList, if it exists, must be identical for all Leaf Modules\r
630 // Probable Enhancement\r
631 // Just specify the lowest common denominator\r
632 //\r
633 // Create the working copy if one does not exist!\r
634 // TODO: CODE GOES HERE\r
635 if (mergePackageDependencies == null)\r
636 mergePackageDependencies = PackageDependenciesDocument.Factory.newInstance()\r
637 .addNewPackageDependencies();\r
638\r
639 PackageDependencies leafPackageDependencies = leafMsa.getPackageDependencies();\r
640 if (leafPackageDependencies.sizeOfPackageArray() > 0) {\r
641 for (int index = 0; index < leafPackageDependencies.sizeOfPackageArray(); index++) {\r
642 String packageGuid = leafPackageDependencies.getPackageArray(index).getPackageGuid();\r
643 String test = checkDuplicateStrings(packageGuid, aPackageList);\r
644 if (test.length() > 0) {\r
645 mergePackageDependencies.addNewPackage();\r
646 mergePackageDependencies\r
647 .setPackageArray(packageDependenciesIndex++,\r
648 leafPackageDependencies.getPackageArray(index));\r
649 }\r
650 }\r
651 }\r
652 } // endif PackageDependencies\r
653\r
654 if (leafMsa.isSetProtocols()) {\r
655 // TODO: \r
656 // TEST FOR NULL SETTINGS so we don't get an error!\r
657 // Add Usage Merging routines\r
658 // \r
659 // If mergeProtocols == null, create a new mergeProtocols and add\r
660 // leaf module's Protocols section to the merge Module's\r
661 //\r
662 // Keep ALL Protocol entries before ProtocolNotify entries!\r
663 //\r
664 // If mergeProtocols != null, check that we have only unique Protocol and ProtocolNotify entries\r
665 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
666 // Mark the Protocol or ProtocolNotify as ALWAYS_PRODUCED\r
667 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
668 // Mark the Protocol or ProtocolNotify as ALWAYS_CONSUMED\r
669 // It is permissable to have one PRODUCED and one CONSUMED entry\r
670 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
671 // and another Leaf uses BY_START, create two entries, one for each.\r
672 //\r
673 // First PASS of the TOOL \r
674 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
675 // this as an error!\r
676 // Probable Enhancement\r
677 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
678 //\r
679 // First PASS of the TOOL\r
680 // Ignore the FeatureFlag - we are not using it now.\r
681 // Probable Enhancement\r
682 // FeatureFlags must be identical for each unique Protocol or ProtocolNotify Entry, otherwise fail the Merge\r
683 //\r
684 // HelpText RULE:\r
685 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
686 // is the leaf Module's path and filename to the MSA file!\r
687 //\r
688 // Create the working copy if one does not exist!\r
689\r
690 if (mergeProtocols == null)\r
691 mergeProtocols = ProtocolsDocument.Factory.newInstance().addNewProtocols();\r
692\r
693 Protocols leafProtocols = leafMsa.getProtocols();\r
694 // Handle Protocol Entries First\r
695 if (leafProtocols.sizeOfProtocolArray() > 0) {\r
696 for (int index = 0; index < leafProtocols.sizeOfProtocolArray(); index++) {\r
697 String protocolCName = leafProtocols.getProtocolArray(index).getProtocolCName();\r
698 String test = checkDuplicateStrings(protocolCName, aProtocolList);\r
699 if (test.length() > 0) {\r
700 // new Protocol\r
701 mergeProtocols.addNewProtocol();\r
702 mergeProtocols.setProtocolArray(protocolIndex++, leafProtocols.getProtocolArray(index));\r
703 } else {\r
704 // Found an existing protocol\r
705 leafUsage = leafProtocols.getProtocolArray(index).getUsage().toString().trim();\r
706 for (int nidx = 0; nidx < protocolIndex; nidx++) {\r
707 if (mergeProtocols.getProtocolArray(nidx).getProtocolCName()\r
708 .contains(protocolCName)) {\r
709 // Found one entry that matches.\r
710 mergeUsage = mergeProtocols.getProtocolArray(nidx).getUsage().toString().trim();\r
711 if (!mergeUsage.contentEquals(leafUsage)) {\r
712 // Usages are different\r
713 if (checkUsage().trim().contains("DIFFERENT")) {\r
714 // We need to check to see if there's another entry\r
715 int anotherProtocol = NOTFOUND;\r
716 for (int iidx = nidx + 1; iidx < protocolIndex; iidx++) {\r
717\r
718 if (mergeProtocols.getProtocolArray(iidx).getUsage().toString()\r
719 .trim().contains(protocolCName)) {\r
720 anotherProtocol = FOUND;\r
721 mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
722 .getUsage().toString().trim();\r
723 if (checkProduced()) {\r
724 mergeProtocols\r
725 .getProtocolArray(nidx)\r
726 .setUsage(\r
727 org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
728 anotherProtocol = FOUND;\r
729 }\r
730 // Both Usage types are CONSUMED\r
731 if (checkConsumed()) {\r
732 mergeProtocols\r
733 .getProtocolArray(nidx)\r
734 .setUsage(\r
735 org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
736 anotherProtocol = FOUND;\r
737 }\r
738 if (((mergeUsage.contains("TO_START")) && (leafUsage\r
739 .contains("TO_START"))))\r
740 anotherProtocol = FOUND;\r
741 if (((mergeUsage.contains("BY_START")) && (leafUsage\r
742 .contains("BY_START"))))\r
743 anotherProtocol = FOUND;\r
744 }\r
745 }\r
746 if (anotherProtocol == NOTFOUND) {\r
747 mergeProtocols.addNewProtocol();\r
748 mergeProtocols\r
749 .setProtocolArray(\r
750 protocolIndex++,\r
751 leafProtocols\r
752 .getProtocolArray(index));\r
753 }\r
754 } else {\r
755 // usage types are either both PRODUCED or CONSUMED\r
756 if (checkProduced())\r
757 mergeProtocols.getProtocolArray(nidx)\r
758 .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
759 if (checkConsumed())\r
760 mergeProtocols.getProtocolArray(nidx)\r
761 .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
762 }\r
763 }\r
764 }\r
765 } // end of Usage Test\r
766 }\r
767 }\r
768 }\r
769\r
770 // Handle ProtocolNotify Entries Second\r
771 if (leafProtocols.sizeOfProtocolNotifyArray() > 0) {\r
772 for (int index = 0; index < leafProtocols.sizeOfProtocolNotifyArray(); index++) {\r
773 String protocolNotifyCName = leafProtocols.getProtocolNotifyArray(index)\r
774 .getProtocolNotifyCName();\r
775 String test = checkDuplicateStrings(protocolNotifyCName, aProtocolNotifyList);\r
776 if (test.length() > 0) {\r
777 mergeProtocols.addNewProtocolNotify();\r
778 mergeProtocols.setProtocolNotifyArray(protocolNotifyIndex++,\r
779 leafProtocols.getProtocolNotifyArray(index));\r
780 } else {\r
781 // We have an existing ProtocolNotify Entry\r
782 leafUsage = leafProtocols.getProtocolNotifyArray(index).getUsage().toString().trim();\r
783 for (int nidx = 0; nidx < protocolIndex; nidx++) {\r
784 if (mergeProtocols.getProtocolNotifyArray(nidx).getProtocolNotifyCName()\r
785 .contains(protocolNotifyCName)) {\r
786 // Found one entry that matches.\r
787 mergeUsage = mergeProtocols.getProtocolNotifyArray(nidx).getUsage().toString().trim();\r
788 if (!mergeUsage.contentEquals(leafUsage)) {\r
789 // Usages are different\r
790 if (checkUsage().trim().contains("DIFFERENT")) {\r
791 // We need to check to see if there's another entry\r
792 int anotherProtocol = NOTFOUND;\r
793 for (int iidx = nidx + 1; iidx < protocolIndex; iidx++) {\r
794\r
795 if (mergeProtocols.getProtocolNotifyArray(iidx).getUsage().toString()\r
796 .trim().contains(protocolNotifyCName)) {\r
797 anotherProtocol = FOUND;\r
798 mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
799 .getUsage().toString().trim();\r
800 if (checkProduced()) {\r
801 mergeProtocols\r
802 .getProtocolNotifyArray(nidx)\r
803 .setUsage(\r
804 org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
805 anotherProtocol = FOUND;\r
806 }\r
807 // Both Usage types are CONSUMED\r
808 if (checkConsumed()) {\r
809 mergeProtocols\r
810 .getProtocolNotifyArray(nidx)\r
811 .setUsage(\r
812 org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
813 anotherProtocol = FOUND;\r
814 }\r
815 if (((mergeUsage.contains("TO_START")) && (leafUsage\r
816 .contains("TO_START"))))\r
817 anotherProtocol = FOUND;\r
818 if (((mergeUsage.contains("BY_START")) && (leafUsage\r
819 .contains("BY_START"))))\r
820 anotherProtocol = FOUND;\r
821 }\r
822 }\r
823 if (anotherProtocol == NOTFOUND) {\r
824 mergeProtocols.addNewProtocolNotify();\r
825 mergeProtocols\r
826 .setProtocolNotifyArray(\r
827 protocolNotifyIndex++,\r
828 leafProtocols\r
829 .getProtocolNotifyArray(index));\r
830 }\r
831 } else {\r
832 // usage types are either both PRODUCED or CONSUMED\r
833 if (checkProduced())\r
834 mergeProtocols.getProtocolNotifyArray(nidx)\r
835 .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
836 if (checkConsumed())\r
837 mergeProtocols.getProtocolNotifyArray(nidx)\r
838 .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
839 }\r
840 }\r
841 }\r
842 } // end of Usage Test\r
843 } // end of Usage test\r
844 }\r
845 }\r
846\r
847 } // endif Protocols\r
848\r
849 if (leafMsa.isSetEvents()) {\r
850 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
851 //\r
852 // "Unique" Entries are based on EventsTypes:EventGuidCName attributes\r
853 // NOTE: The EventGuidCName can appear once and only once in a CreateEvents Section\r
854 // The SAME EventGuidCName can appear once and only once in the SignalEvents Section\r
855 // Two EventGuidCName entries, one in CreateEvents the other in SignalEvents IS PERMITTED!\r
856 //\r
857 // If mergeEvents == null, create a new mergeEvents and add\r
858 // leaf module's Events section to the merge Module's\r
859 //\r
860 // Keep ALL CreateEvents entries before SignalEvents entries!\r
861 //\r
862 // If mergeEvents != null, check that we have only unique CreateEvents and SignalEvents entries\r
863 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
864 // Mark the CreateEvents.EventTypes or SignalEvents.EventTypes as ALWAYS_PRODUCED\r
865 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
866 // Mark the CreateEvents.EventTypes or SignalEvents.EventTypes as ALWAYS_CONSUMED\r
867 // It is permissable to have one PRODUCED and one CONSUMED entry\r
868 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
869 // and another Leaf uses BY_START, create two entries, one for each.\r
870 //\r
871 // First PASS of the TOOL \r
872 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
873 // this as an error!\r
874 // Probable Enhancement\r
875 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
876 //\r
877 // First PASS of the TOOL\r
878 // Ignore the FeatureFlag - we are not using it now.\r
879 // Probable Enhancement\r
880 // FeatureFlags must be identical for each unique EventTypes, otherwise fail the Merge\r
881 //\r
882 // The EventTypes.EventType elements must be identical for all instances of\r
883 // the EventGuidCName FAIL THE MERGE WITH ERROR indicating the Leaf file name that \r
884 // was different.\r
885 //\r
886 //\r
887 // HelpText RULE:\r
888 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
889 // is the leaf Module's path and filename to the MSA file!\r
890 //\r
891 // Create the working copy if one does not exist!\r
892 // TODO: Code goes here\r
893\r
894 if (mergeCreateEvents == null)\r
895 mergeCreateEvents = EventsDocument.Events.CreateEvents.Factory.newInstance();\r
896\r
897 Events leafEvents = leafMsa.getEvents();\r
898 if (leafEvents.getCreateEvents() != null) {\r
899 Events.CreateEvents leafCreateEvents = leafEvents.getCreateEvents();\r
900 if (leafCreateEvents.sizeOfEventTypesArray() > 0) {\r
901 for (int index = 0; index < leafCreateEvents.sizeOfEventTypesArray(); index++) {\r
902 String EventGuidCName = leafCreateEvents.getEventTypesArray(index).getEventGuidCName();\r
903 String test = checkDuplicateStrings(EventGuidCName, aCreateEventsList);\r
904 if (test.length() > 0) {\r
905 mergeCreateEvents.addNewEventTypes();\r
906 mergeCreateEvents.setEventTypesArray(createEventIndex++,\r
907 leafEvents.getCreateEvents()\r
908 .getEventTypesArray(index));\r
909\r
910 }\r
911 }\r
912 }\r
913 }\r
914\r
915 if (mergeSignalEvents == null)\r
916 mergeSignalEvents = EventsDocument.Events.SignalEvents.Factory.newInstance();\r
917\r
918 if (leafEvents.getSignalEvents() != null) {\r
919 Events.SignalEvents leafSignalEvents = leafEvents.getSignalEvents();\r
920 if (leafSignalEvents.sizeOfEventTypesArray() > 0) {\r
921 for (int index = 0; index < leafSignalEvents.sizeOfEventTypesArray(); index++) {\r
922 String EventGuidCName = leafSignalEvents.getEventTypesArray(index).getEventGuidCName();\r
923 String test = checkDuplicateStrings(EventGuidCName, aSignalEventsList);\r
924 if (test.length() > 0) {\r
925 mergeSignalEvents.addNewEventTypes();\r
926 mergeSignalEvents.setEventTypesArray(signalEventIndex++,\r
927 leafEvents.getSignalEvents()\r
928 .getEventTypesArray(index));\r
929 }\r
930 }\r
931 }\r
932 }\r
933 } // endif Events \r
934\r
935 if (leafMsa.isSetHobs()) {\r
936 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
937 //\r
938 // "Unique" Entries are based on Hobs.HobTypes:HobGuidCName attribute\r
939 //\r
940 // If mergeHobs == null, create a new mergeHobs and add\r
941 // leaf module's Hobs section to the merge Module's\r
942 //\r
943 // \r
944 // If mergeHobs != null, check that we have only unique Hobs.HobTypes entries\r
945 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
946 // Mark the Hobs.HobTypes as ALWAYS_PRODUCED\r
947 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
948 // Mark the Hobs.HobTypes as ALWAYS_CONSUMED\r
949 // It is permissable to have one PRODUCED and one CONSUMED entry\r
950 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
951 // and another Leaf uses BY_START, create two entries, one for each.\r
952 //\r
953 // First PASS of the TOOL \r
954 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
955 // this as an error!\r
956 // Probable Enhancement\r
957 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
958 //\r
959 // First PASS of the TOOL\r
960 // Ignore the FeatureFlag - we are not using it now.\r
961 // Probable Enhancement\r
962 // FeatureFlags must be identical for each unique HobTypes element, otherwise fail the Merge\r
963 //\r
964 // The HobTypes.HobType elements must be identical for all instances of\r
965 // the HobGuidCName FAIL THE MERGE WITH ERROR indicating the Leaf file name that \r
966 // was different.\r
967 //\r
968 //\r
969 // HelpText RULE:\r
970 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
971 // is the leaf Module's path and filename to the MSA file!\r
972 //\r
973 // Create the working copy if one does not exist!\r
974 // TODO: Code goes here\r
975 if (mergeHobs == null)\r
976 mergeHobs = HobsDocument.Factory.newInstance().addNewHobs();\r
977\r
978 Hobs leafHobs = leafMsa.getHobs();\r
979 if (leafHobs.sizeOfHobTypesArray() > 0) {\r
980 for (int index = 0; index < leafHobs.sizeOfHobTypesArray(); index++) {\r
981 String hobGuidCName = leafHobs.getHobTypesArray(index).getHobType().toString();\r
982 String test = checkDuplicateStrings(hobGuidCName, aHobsList);\r
983 if (test.length() > 0) {\r
984 mergeHobs.addNewHobTypes();\r
985 mergeHobs.setHobTypesArray(hobsIndex++, leafHobs.getHobTypesArray(index));\r
986 }\r
987 }\r
988 }\r
989 } // endif Hobs \r
990\r
991 if (leafMsa.isSetPPIs()) {\r
992 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
993 //\r
994 // Keep only Unique Ppi or PpiNotify elements, based on the PpiCName and PpiNotifyCName respectively.\r
995\r
996 // If mergePpi == null, create a new mergePpi and add\r
997 // leaf module's PPIs section to the merge Module's\r
998 //\r
999 // Keep ALL Ppi entries before PpiNotify entries!\r
1000 //\r
1001 // If mergePpi != null, check that we have only unique Ppi and PpiNotify entries\r
1002 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1003 // Mark the Ppi or PpiNotify as ALWAYS_PRODUCED\r
1004 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1005 // Mark the Ppi or PpiNotify as ALWAYS_CONSUMED\r
1006 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1007 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1008 // and another Leaf uses BY_START, create two entries, one for each.\r
1009 //\r
1010 // First PASS of the TOOL \r
1011 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1012 // this as an error!\r
1013 // Probable Enhancement\r
1014 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1015 //\r
1016 // First PASS of the TOOL\r
1017 // Ignore the FeatureFlag - we are not using it now.\r
1018 // Probable Enhancement\r
1019 // FeatureFlags must be identical for each unique Ppi or PpiNotify Entry, otherwise fail the Merge\r
1020 //\r
1021 // HelpText RULE:\r
1022 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1023 // is the leaf Module's path and filename to the MSA file!\r
1024 //\r
1025 // Create the working copy if one does not exist!\r
1026 // TODO: Code Goes Here!\r
1027 if (mergePpis == null)\r
1028 mergePpis = PPIsDocument.Factory.newInstance().addNewPPIs();\r
1029\r
1030 PPIs leafPPIs = leafMsa.getPPIs();\r
1031 // Handle the PPI Entries First\r
1032 if (leafPPIs.sizeOfPpiArray() > 0) {\r
1033 for (int index = 0; index < leafPPIs.sizeOfPpiArray(); index++) {\r
1034 String ppiCName = leafPPIs.getPpiArray(index).getPpiCName();\r
1035 String test = checkDuplicateStrings(ppiCName, aPpiList);\r
1036 if (test.length() > 0) {\r
1037 mergePpis.addNewPpi();\r
1038 mergePpis.setPpiArray(ppiIndex++, leafPPIs.getPpiArray(index));\r
1039 }\r
1040 }\r
1041 }\r
1042\r
1043 // Handle the PpiNotify Second\r
1044 if (leafPPIs.sizeOfPpiNotifyArray() > 0) {\r
1045 for (int index = 0; index < leafPPIs.sizeOfPpiNotifyArray(); index++) {\r
1046 String ppiNotifyCName = leafPPIs.getPpiNotifyArray(index).getPpiNotifyCName();\r
1047 String test = checkDuplicateStrings(ppiNotifyCName, aPpiNotifyList);\r
1048 if (test.length() > 0) {\r
1049 mergePpis.addNewPpiNotify();\r
1050 mergePpis.setPpiNotifyArray(ppiNotifyIndex++, leafPPIs.getPpiNotifyArray(index));\r
1051 }\r
1052 }\r
1053 }\r
1054\r
1055 } // endif Ppis\r
1056\r
1057 if (leafMsa.isSetVariables()) {\r
1058 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1059 //\r
1060 // Keep only Unique Variable elements, based on the VariableName element.\r
1061 //\r
1062 // If mergeVariables == null, create a new mergeVariables and add\r
1063 // leaf module's Variables section to the merge Module's\r
1064 //\r
1065 // If mergeVariables != null, check that we have only unique Variable entries\r
1066 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1067 // Mark the Variable as ALWAYS_PRODUCED\r
1068 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1069 // Mark the Variable as ALWAYS_CONSUMED\r
1070 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1071 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1072 // and another Leaf uses BY_START, create two entries, one for each.\r
1073 //\r
1074 // First PASS of the TOOL \r
1075 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1076 // this as an error!\r
1077 // Probable Enhancement\r
1078 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1079 //\r
1080 // First PASS of the TOOL\r
1081 // Ignore the FeatureFlag - we are not using it now.\r
1082 // Probable Enhancement\r
1083 // FeatureFlags must be identical for each unique Variable entry, otherwise fail the Merge\r
1084 //\r
1085 // HelpText RULE:\r
1086 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1087 // is the leaf Module's path and filename to the MSA file!\r
1088 //\r
1089 // Create the working copy if one does not exist!\r
1090 // TODO: Code Goes Here!\r
1091 if (mergeVariables == null)\r
1092 mergeVariables = VariablesDocument.Factory.newInstance().addNewVariables();\r
1093\r
1094 Variables leafVariables = leafMsa.getVariables();\r
1095 if (leafVariables.sizeOfVariableArray() > 0) {\r
1096 for (int index = 0; index < leafVariables.sizeOfVariableArray(); index++) {\r
1097 String variableGuidCName = leafVariables.getVariableArray(index).getGuidCName();\r
1098 String test = checkDuplicateStrings(variableGuidCName, aVariablesList);\r
1099 if (test.length() > 0) {\r
1100 mergeVariables.addNewVariable();\r
1101 mergeVariables\r
1102 .setVariableArray(variablesIndex++, leafVariables.getVariableArray(index));\r
1103 }\r
1104 }\r
1105 }\r
1106\r
1107 }// endif Variables\r
1108\r
1109 if (leafMsa.isSetBootModes()) {\r
1110 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1111 //\r
1112 // Keep only Unique BootMode elements, based on the BootModeName Attribute.\r
1113 //\r
1114 // If mergeBootModes == null, create a new mergeBootModes and add\r
1115 // leaf module's BootModes section to the merge Module's\r
1116 //\r
1117 // If mergeBootModes != null, check that we have only unique BootMode entries\r
1118 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1119 // Mark the BootMode as ALWAYS_PRODUCED\r
1120 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1121 // Mark the BootMode as ALWAYS_CONSUMED\r
1122 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1123 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1124 // and another Leaf uses BY_START, create two entries, one for each.\r
1125 //\r
1126 // First PASS of the TOOL \r
1127 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1128 // this as an error!\r
1129 // Probable Enhancement\r
1130 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1131 //\r
1132 // First PASS of the TOOL\r
1133 // Ignore the FeatureFlag - we are not using it now.\r
1134 // Probable Enhancement\r
1135 // FeatureFlags must be identical for each unique BootMode entry, otherwise fail the Merge\r
1136 //\r
1137 // HelpText RULE:\r
1138 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1139 // is the leaf Module's path and filename to the MSA file!\r
1140 //\r
1141 // Create the working copy if one does not exist!\r
1142 // TODO: Code Goes Here!\r
1143 if (mergeBootModes == null)\r
1144 mergeBootModes = BootModesDocument.Factory.newInstance().addNewBootModes();\r
1145\r
1146 BootModes leafBootModes = leafMsa.getBootModes();\r
1147 if (leafBootModes.sizeOfBootModeArray() > 0) {\r
1148 for (int index = 0; index < leafBootModes.sizeOfBootModeArray(); index++) {\r
1149 String bootModeName = leafBootModes.getBootModeArray(index).getBootModeName().toString();\r
1150 String test = checkDuplicateStrings(bootModeName, aBootModesList);\r
1151 if (test.length() > 0) {\r
1152 mergeBootModes.addNewBootMode();\r
1153 mergeBootModes\r
1154 .setBootModeArray(bootModesIndex++, leafBootModes.getBootModeArray(index));\r
1155 }\r
1156 }\r
1157 }\r
1158\r
1159 }// endif BootMode\r
1160\r
1161 if (leafMsa.isSetSystemTables()) {\r
1162 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1163 //\r
1164 // Keep only Unique SystemTableCNames elements, based on the SystemTableCName element.\r
1165 //\r
1166 // If mergeSystemTables == null, create a new mergeSystemTables and add\r
1167 // leaf module's Variables section to the merge Module's\r
1168 //\r
1169 // If mergeSystemTables != null, check that we have only unique SystemTableCNames entries\r
1170 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1171 // Mark the SystemTableCName as ALWAYS_PRODUCED\r
1172 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1173 // Mark the SystemTableCName as ALWAYS_CONSUMED\r
1174 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1175 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1176 // and another Leaf uses BY_START, create two entries, one for each.\r
1177 //\r
1178 // First PASS of the TOOL \r
1179 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1180 // this as an error!\r
1181 // Probable Enhancement\r
1182 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1183 //\r
1184 // First PASS of the TOOL\r
1185 // Ignore the FeatureFlag - we are not using it now.\r
1186 // Probable Enhancement\r
1187 // FeatureFlags must be identical for each unique SystemTableCNames entry, otherwise fail the Merge\r
1188 //\r
1189 // HelpText RULE:\r
1190 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1191 // is the leaf Module's path and filename to the MSA file!\r
1192 //\r
1193 // Create the working copy if one does not exist!\r
1194 // TODO: Code Goes Here!\r
1195 if (mergeSystemTables == null)\r
1196 mergeSystemTables = SystemTablesDocument.Factory.newInstance().addNewSystemTables();\r
1197\r
1198 SystemTables leafSystemTables = leafMsa.getSystemTables();\r
1199 if (leafSystemTables.sizeOfSystemTableCNamesArray() > 0) {\r
1200 for (int index = 0; index < leafSystemTables.sizeOfSystemTableCNamesArray(); index++) {\r
1201 String systemTableCName = leafSystemTables.getSystemTableCNamesArray(index)\r
1202 .getSystemTableCName();\r
1203 String test = checkDuplicateStrings(systemTableCName, aSystemTablesList);\r
1204 if (test.length() > 0) {\r
1205 mergeSystemTables.addNewSystemTableCNames();\r
1206 mergeSystemTables\r
1207 .setSystemTableCNamesArray(\r
1208 systemTableIndex++,\r
1209 leafSystemTables\r
1210 .getSystemTableCNamesArray(index));\r
1211 }\r
1212 }\r
1213 }\r
1214\r
1215 }// endif SystemTables\r
1216\r
1217 if (leafMsa.isSetDataHubs()) {\r
1218 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1219 //\r
1220 // Keep only Unique DataHubs elements, based on the DataHubRecord.DataHubCName element.\r
1221 //\r
1222 // If mergeDataHubs == null, create a new mergeDataHubs and add\r
1223 // leaf module's DataHubs section to the merge Module's\r
1224 //\r
1225 // If mergeDataHubs != null, check that we have only unique DataHubRecord entries\r
1226 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1227 // Mark the DataHubCName as ALWAYS_PRODUCED\r
1228 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1229 // Mark the DataHubCName as ALWAYS_CONSUMED\r
1230 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1231 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1232 // and another Leaf uses BY_START, create two entries, one for each.\r
1233 //\r
1234 // First PASS of the TOOL \r
1235 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1236 // this as an error!\r
1237 // Probable Enhancement\r
1238 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1239 //\r
1240 // First PASS of the TOOL\r
1241 // Ignore the FeatureFlag - we are not using it now.\r
1242 // Probable Enhancement\r
1243 // FeatureFlags must be identical for each unique DataHubRecord entry, otherwise fail the Merge\r
1244 //\r
1245 // HelpText RULE:\r
1246 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1247 // is the leaf Module's path and filename to the MSA file!\r
1248 //\r
1249 // Create the working copy if one does not exist!\r
1250 // TODO: Code Goes Here!\r
1251 if (mergeDataHubs == null)\r
1252 mergeDataHubs = DataHubsDocument.Factory.newInstance().addNewDataHubs();\r
1253\r
1254 DataHubs leafDataHubs = leafMsa.getDataHubs();\r
1255 if (leafDataHubs.sizeOfDataHubRecordArray() > 0) {\r
1256 for (int index = 0; index < leafDataHubs.sizeOfDataHubRecordArray(); index++) {\r
1257 String dataHubCName = leafDataHubs.getDataHubRecordArray(index).getDataHubCName();\r
1258 String test = checkDuplicateStrings(dataHubCName, aDataHubsList);\r
1259 if (test.length() > 0) {\r
1260 mergeDataHubs.addNewDataHubRecord();\r
1261 mergeDataHubs.setDataHubRecordArray(dataHubsIndex++,\r
1262 leafDataHubs.getDataHubRecordArray(index));\r
1263 }\r
1264 }\r
1265 }\r
1266\r
1267 }// endif DataHubs\r
1268\r
1269 if (leafMsa.isSetHiiPackages()) {\r
1270 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1271 //\r
1272 // Keep only Unique HiiPackage elements, based on the HiiPackage.HiiCName element.\r
1273 //\r
1274 // If mergeHiiPackages == null, create a new mergeHiiPackages and add\r
1275 // leaf module's DataHubs section to the merge Module's\r
1276 //\r
1277 // If mergeHiiPackages != null, check that we have only unique HiiPackage entries\r
1278 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1279 // Mark the HiiPackage as ALWAYS_PRODUCED\r
1280 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1281 // Mark the HiiPackage as ALWAYS_CONSUMED\r
1282 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1283 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1284 // and another Leaf uses BY_START, create two entries, one for each.\r
1285 //\r
1286 // First PASS of the TOOL \r
1287 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1288 // this as an error!\r
1289 // Probable Enhancement\r
1290 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1291 //\r
1292 // First PASS of the TOOL\r
1293 // Ignore the FeatureFlag - we are not using it now.\r
1294 // Probable Enhancement\r
1295 // FeatureFlags must be identical for each unique HiiPackage entry, otherwise fail the Merge\r
1296 //\r
1297 // HelpText RULE:\r
1298 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1299 // is the leaf Module's path and filename to the MSA file!\r
1300 //\r
1301 // Create the working copy if one does not exist!\r
1302 // TODO: Code Goes Here!\r
1303 if (mergeHiiPackages == null)\r
1304 mergeHiiPackages = HiiPackagesDocument.Factory.newInstance().addNewHiiPackages();\r
1305\r
1306 HiiPackages leafHiiPackages = leafMsa.getHiiPackages();\r
1307 if (leafHiiPackages.sizeOfHiiPackageArray() > 0) {\r
1308 for (int index = 0; index < leafHiiPackages.sizeOfHiiPackageArray(); index++) {\r
1309 String hiiCName = leafHiiPackages.getHiiPackageArray(index).getHiiCName();\r
1310 String test = checkDuplicateStrings(hiiCName, aHiiPackagesList);\r
1311 if (test.length() > 0) {\r
1312 mergeHiiPackages.addNewHiiPackage();\r
1313 mergeHiiPackages.setHiiPackageArray(hiiPackageIndex++,\r
1314 leafHiiPackages.getHiiPackageArray(index));\r
1315 }\r
1316 }\r
1317 }\r
1318\r
1319 }// endif HiiPackage\r
1320\r
1321 if (leafMsa.isSetGuids()) {\r
1322 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1323 //\r
1324 // Keep only Unique Guids elements, based on the GuidCNames.GuidCName element.\r
1325 //\r
1326 // If mergeGuids == null, create a new mergeGuids and add\r
1327 // leaf module's Guids section to the merge Module's\r
1328 //\r
1329 // If mergeGuids != null, check that we have only unique GuidCNames entries\r
1330 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1331 // Mark the GuidCNames as ALWAYS_PRODUCED\r
1332 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1333 // Mark the GuidCNames as ALWAYS_CONSUMED\r
1334 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1335 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1336 // and another Leaf uses BY_START, create two entries, one for each.\r
1337 //\r
1338 // First PASS of the TOOL \r
1339 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1340 // this as an error!\r
1341 // Probable Enhancement\r
1342 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1343 //\r
1344 // First PASS of the TOOL\r
1345 // Ignore the FeatureFlag - we are not using it now.\r
1346 // Probable Enhancement\r
1347 // FeatureFlags must be identical for each unique GuidCNames entry, otherwise fail the Merge\r
1348 //\r
1349 // HelpText RULE:\r
1350 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1351 // is the leaf Module's path and filename to the MSA file!\r
1352 //\r
1353 // Create the working copy if one does not exist!\r
1354 // TODO: Code Goes Here!\r
1355 if (mergeGuids == null)\r
1356 mergeGuids = GuidsDocument.Factory.newInstance().addNewGuids();\r
1357\r
1358 Guids leafGuids = leafMsa.getGuids();\r
1359 if (leafGuids.sizeOfGuidCNamesArray() > 0) {\r
1360 for (int index = 0; index < leafGuids.sizeOfGuidCNamesArray(); index++) {\r
1361 String hiiCName = leafGuids.getGuidCNamesArray(index).getGuidCName();\r
1362 String test = checkDuplicateStrings(hiiCName, aGuidsList);\r
1363 if (test.length() > 0) {\r
1364 mergeGuids.addNewGuidCNames();\r
1365 mergeGuids.setGuidCNamesArray(guidsIndex++, leafGuids.getGuidCNamesArray(index));\r
1366 }\r
1367 }\r
1368 }\r
1369\r
1370 }// endif GuidCNames\r
1371\r
1372 if (leafMsa.isSetExterns()) {\r
1373 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1374 //\r
1375 // FAIL THE MERGE if Externs.PcdIsDriver is present\r
1376 // FAIL THE MERGE if Externs.TianoR8FlashMap_h is TRUE\r
1377 //\r
1378 // Keep only Unique Extern elements, based on the Extern.* elements.\r
1379 //\r
1380 // If mergeExterns == null, create a new mergeExterns and add\r
1381 // leaf module's Extern section to the merge Module's\r
1382 //\r
1383 // If mergeExterns != null, check that we have only unique Extern.* entries\r
1384 //\r
1385 // After storing the initial LEAF MODULE'S SPECIFICATION SECTION\r
1386 // ALL other Leaf Modules must declare the exact same specifications\r
1387 // If they do not, FAIL the MERGE with an error message, printing the\r
1388 // name of the leaf MSA that did not match, along with\r
1389 // Expected: from the merge module's specification list\r
1390 // Got: from the leaf file that fails!\r
1391 //\r
1392 // For Each <Extern>\r
1393 // For each pair of <ModuleEntryPoint> and/or <ModuleUnloadImage>\r
1394 // The ModuleUnloadImage value must be identical for an identical pair of ModuleEntryPoint values\r
1395 // If not, FAIL THE MERGE, giving the current leaf MSA filename as the failure, along with the\r
1396 // additional error information as follows:\r
1397 // -- leafFilename --\r
1398 // ModuleEntryPoint: \r
1399 // Expected ModuleUnloadImage: fromMergeModule\r
1400 // Got ModuleUnloadImage: fromLeaf\r
1401 // Merge Aborted!\r
1402 // More than one <Extern> Section with a pair of <ModuleEntryPoint><ModuleUnloadImage> is allowed\r
1403 //\r
1404 // For each pair of one <Constructor> and/or one <Destructor> elements\r
1405 // The <Extern> section containing the <Constructor> <Destructor> pairs \r
1406 // The Destructor value in all leaf modules must be identical for all Constructor elements that are identical.\r
1407 // More than one <Extern> Section with Constructor/Destructor pair is permitted.\r
1408 //\r
1409 // For each Set four elements, DriverBinding, ComponentName, DriverConfig and DriverDiag,\r
1410 // 1 DriverBinding and\r
1411 // 0 or 1 ComponentName and/or\r
1412 // 0 or 1 DriverConfig and/or\r
1413 // 0 or 1 DriverDiag \r
1414 // elements must appear in 1 <Extern> Section.\r
1415 //\r
1416 // A ComponentName cannot be used without a DriverBinding element.\r
1417 // A DriverConfig element cannot appear without a DriverBinding element. \r
1418 // A DriverDiag element cannot appear without a DriverBinding element\r
1419 // These elements are matched within a single <Extern> Section uniquely defined by the DriverBinding element. \r
1420 // Multiple <Extern> sections of this type are permitted.\r
1421 //\r
1422 // Each pair of SetVirtualAddressMapCallBack and ExitBootServiceCallBack elements MUST \r
1423 // BE in one Extern Section. ONE AND ONLY ONE of this section is permitted.\r
1424 //\r
1425 // First PASS of the TOOL \r
1426 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1427 // this as an error!\r
1428 // Probable Enhancement\r
1429 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1430 //\r
1431 // First PASS of the TOOL\r
1432 // Ignore the FeatureFlag - we are not using it now.\r
1433 // Probable Enhancement\r
1434 // FeatureFlags must be identical for each unique Extern entry, otherwise fail the Merge\r
1435 //\r
1436 // Create the working copy if one does not exist!\r
1437 // TODO: Code Goes Here!\r
1438 if (mergeExterns == null)\r
1439 mergeExterns = ExternsDocument.Factory.newInstance().addNewExterns();\r
1440\r
1441 Externs leafExterns = leafMsa.getExterns();\r
1442 // PCD IS DRIVER NOT ALLOWED IN A MERGED Module\r
1443 if (leafExterns.isSetPcdIsDriver()) {\r
1444 System.out.println("The Module: " + leafFilename + " is a PCD Driver and CANNOT BE MERGED!");\r
1445 System.out.println("Merge Aborted");\r
1446 System.err.flush();\r
1447 System.exit(FAIL);\r
1448 }\r
1449\r
1450 // TIANO R8 FLASHMAP.H NOT ALLOWED IN A MERGED Module\r
1451 if (leafExterns.isSetTianoR8FlashMapH()) {\r
1452 System.out.println("The Module: " + leafFilename\r
1453 + " set the Tiano R8 FlashMap.h Flag and CANNOT BE MERGED!");\r
1454 System.out.println("Merge Aborted");\r
1455 System.err.flush();\r
1456 System.exit(FAIL);\r
1457 }\r
1458\r
1459 // Add the Specification Array, one time only.\r
1460 if (leafExterns.sizeOfSpecificationArray() > 0) {\r
1461 for (int index = 0; index < leafExterns.sizeOfSpecificationArray(); index++) {\r
1462 String spec = leafExterns.getSpecificationArray(index);\r
1463 String test = checkSpecs(spec, leafFilename, aSpecArray);\r
1464 if (test.length() > 0) {\r
1465 mergeExterns.addNewSpecification();\r
1466 mergeExterns.setSpecificationArray(specIndex++, test);\r
1467 }\r
1468 }\r
1469 }\r
1470\r
1471 if (leafExterns.sizeOfExternArray() > 0) {\r
1472 for (int index = 0; index < leafExterns.sizeOfExternArray(); index++) {\r
1473 String test = "";\r
1474 if (leafExterns.getExternArray(index).isSetModuleEntryPoint()) {\r
1475 // ModuleEntryPoint, if an Unload Image is paired with\r
1476 // the Module Entry point, it will piggy back on the\r
1477 // Module Entry Point Extern\r
1478 String moduleEntryPoint = leafExterns.getExternArray(index).getModuleEntryPoint();\r
1479 test = checkDuplicateStrings(moduleEntryPoint, aEntryPointList);\r
1480\r
1481 } else if (leafExterns.getExternArray(index).isSetModuleUnloadImage()) {\r
1482 // Module Unload Image is here in case there is no\r
1483 // Entry Point - not very typical\r
1484 String moduleUnloadImage = leafExterns.getExternArray(index).getModuleUnloadImage();\r
1485 test = checkDuplicateStrings(moduleUnloadImage, aUnloadImageList);\r
1486\r
1487 } else if (leafExterns.getExternArray(index).isSetConstructor()) {\r
1488 // Constructors must be unique, if a Destructor is\r
1489 // paired with a constructor, it will pigback on\r
1490 // the constructor\r
1491 String constructor = leafExterns.getExternArray(index).getConstructor();\r
1492 test = checkDuplicateStrings(constructor, aConstructorList);\r
1493\r
1494 } else if (leafExterns.getExternArray(index).isSetDestructor()) {\r
1495 // Destructors must be unique\r
1496 String destructor = leafExterns.getExternArray(index).getDestructor();\r
1497 test = checkDuplicateStrings(destructor, aDestructorList);\r
1498\r
1499 } else if (leafExterns.getExternArray(index).isSetDriverBinding()) {\r
1500 // Driver Bindings must be unique\r
1501 // Fixed the MSA files - ComponentName, Driver Config and\r
1502 // Driver Diag statments must be inside of an Extern that \r
1503 // has a Driver Binding\r
1504 String driverBinding = leafExterns.getExternArray(index).getDriverBinding();\r
1505 test = checkDuplicateStrings(driverBinding, aDriverBindingList);\r
1506\r
1507 } else if (leafExterns.getExternArray(index).isSetSetVirtualAddressMapCallBack()) {\r
1508 // Handle Virtual Address Map and Exit Boot Services Call Backs\r
1509 // in a single Extern if they are present\r
1510 String virtualAddressMap = leafExterns.getExternArray(index)\r
1511 .getSetVirtualAddressMapCallBack();\r
1512 test = checkDuplicateStrings(virtualAddressMap, aVirtualAddressMapList);\r
1513\r
1514 } else if (leafExterns.getExternArray(index).isSetExitBootServicesCallBack()) {\r
1515 // Handle a stand alone Exit Boot Services Call Back\r
1516 String exitBootServices = leafExterns.getExternArray(index)\r
1517 .getExitBootServicesCallBack();\r
1518 test = checkDuplicateStrings(exitBootServices, aExitBootServicesList);\r
1519 } else {\r
1520 // Unknown Extern FAIL - May be an invalid Component Name in it's own Extern Statement\r
1521 System.out.println("Unknown EXTERN defined in Module: " + leafFilename);\r
1522 System.out.println("Value: " + leafExterns.getExternArray(index).toString());\r
1523 System.out.println("Merge Aborted!");\r
1524 System.err.flush();\r
1525 System.exit(FAIL);\r
1526 }\r
1527\r
1528 if (test.length() > 0) {\r
1529 mergeExterns.addNewExtern();\r
1530 mergeExterns.setExternArray(externsIndex++, leafExterns.getExternArray(index));\r
1531 }\r
1532 }\r
1533 }\r
1534 }// endif mergeExterns\r
1535\r
1536 if (leafMsa.isSetPcdCoded()) {\r
1537 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1538 //\r
1539 // Keep only Unique PcdCoded elements, based on the PcdCoded.PcdEntry.C_Name element.\r
1540 //\r
1541 // If mergePcdCoded == null, create a new mergePcdCoded and add\r
1542 // leaf module's PcdCoded section to the merge Module's\r
1543 //\r
1544 // If mergePcdCoded != null, check that we have only unique PcdEntry entries\r
1545 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1546 // Mark the PcdEntry as ALWAYS_PRODUCED\r
1547 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1548 // Mark the PcdEntry as ALWAYS_CONSUMED\r
1549 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1550 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1551 // and another Leaf uses BY_START, create two entries, one for each.\r
1552 //\r
1553 // First PASS of the TOOL \r
1554 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1555 // this as an error!\r
1556 // Probable Enhancement\r
1557 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1558 //\r
1559 // First PASS of the TOOL\r
1560 // Ignore the FeatureFlag - we are not using it now.\r
1561 // Probable Enhancement\r
1562 // FeatureFlags must be identical for each unique HiiPackage entry, otherwise fail the Merge\r
1563 //\r
1564 // First PASS of the TOOL\r
1565 // Ignore the PcdEntry:Usage Attribute\r
1566 // Probable Enhancment\r
1567 // Have Usage Combined like was done for the Library Class\r
1568 //\r
1569 // First PASS of the TOOL\r
1570 // If Different PcdItemTypes, Abort The MERGE\r
1571 //\r
1572 // Probably Enhancement\r
1573 // The PcdItemType Should be checked using the following rules\r
1574 // Feature Flag MUST ALWAYS BE A FEATURE FLAG\r
1575 // If different Item Types occur, mark the PCD as DYNAMIC\r
1576 //\r
1577 // HelpText RULE:\r
1578 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1579 // is the leaf Module's path and filename to the MSA file!\r
1580 //\r
1581 // Create the working copy if one does not exist!\r
1582 // TODO: Code Goes Here!\r
1583 if (mergePcdCoded == null)\r
1584 mergePcdCoded = PcdCodedDocument.Factory.newInstance().addNewPcdCoded();\r
1585\r
1586 PcdCoded leafPcdCoded = leafMsa.getPcdCoded();\r
1587 if (leafPcdCoded.sizeOfPcdEntryArray() > 0) {\r
1588 for (int index = 0; index < leafPcdCoded.sizeOfPcdEntryArray(); index++) {\r
1589 String pcdCName = leafPcdCoded.getPcdEntryArray(index).getCName();\r
1590 String pcdItemType = leafPcdCoded.getPcdEntryArray(index).getPcdItemType().toString();\r
1591 String test = checkPcd(pcdCName, pcdItemType, leafFilename, aPcdCNameList);\r
1592 if (test.length() > 0) {\r
1593 mergePcdCoded.addNewPcdEntry();\r
1594 mergePcdCoded.setPcdEntryArray(pcdIndex++, leafPcdCoded.getPcdEntryArray(index));\r
1595 }\r
1596 }\r
1597 }\r
1598\r
1599 }// endif PcdCoded\r
1600\r
1601 if (leafMsa.isSetModuleBuildOptions()) {\r
1602 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1603 //\r
1604 // Any element that appear within a leaf's ModuleBuildOptions should be appended to\r
1605 // the Merge Module's BuildOptions section.\r
1606 //\r
1607 // NO ATTEMPT IS MADE TO VERIFY UNIQUENESS ON ANYTHING WITHIN THIS SECTION!\r
1608 //\r
1609 // Create the working copy if one does not exist!\r
1610 // if (mergeBuildOptions == null)\r
1611 // mergeBuildOptions = ModuleBuildOptionsDocument.Factory.newInstance().addNewModuleBuildOptions();\r
1612\r
1613 // ModuleBuildOptions leafModuleBuildOptions = leafMsa.getModuleBuildOptions();\r
1614\r
1615 // mergeBuildOptions.addNewModuleBuildOptions();\r
1616 // mergeBuildOptions.setModuleBuildOptions(leafModuleBuildOptions);\r
1617\r
1618 //\r
1619 // TODO: Code Goes Here!\r
1620 } // endif ModuleBuildOptions\r
1621\r
1622 // Need to process any UserExtensions here too.\r
1623 if (leafMsa.getUserExtensionsList() != null) {\r
1624\r
1625 if (mergeUserExtensions == null)\r
1626 mergeUserExtensions = UserExtensionsDocument.Factory.newInstance().addNewUserExtensions();\r
1627\r
1628 // for (int index = 0; index < leafMsa.getUserExtensionsList().size(); index++)\r
1629\r
1630 }\r
1631\r
1632 } // Completed parsing all leaf files.\r
1633\r
1634 header.setAbstract(Abstract);\r
1635 header.setCopyright(Copyright);\r
1636 header.setDescription(Description);\r
1637 License mLicense = License.Factory.newInstance();\r
1638 mLicense.setStringValue(licenseTxt);\r
1639 header.setLicense(mLicense);\r
1640 if ((DEBUG > 0) || (VERBOSE > 0))\r
1641 System.out.println("Merged Module supports: " + sArchitectures + " architectures.");\r
1642 List<String> lArchitectures = new ArrayList<String>();\r
1643 String s[] = sArchitectures.replace(" ", " ").trim().split(" ");\r
1644 for (int idx = 0; idx < s.length; idx++) {\r
1645 lArchitectures.add(s[idx]);\r
1646 if (DEBUG > 7)\r
1647 System.out.println("Adding architecture: " + s[idx]);\r
1648 }\r
1649 moduleDefs.setSupportedArchitectures(lArchitectures);\r
1650\r
1651 } // endif mergeMsaFile == null\r
1652\r
1653 if ((uiName != null) && (uiName.length() > 0) && (result == PASS)) {\r
1654 // TODO: Stub for replacing the msaFile UiName\r
1655 if ((DEBUG > 0) || (VERBOSE > 0))\r
1656 System.out.println("Updating the uiName: " + uiName);\r
1657 header.setModuleName(uiName);\r
1658 }\r
1659\r
1660 if ((baseName != null) && (baseName.length() > 0) && (result == PASS)) {\r
1661 if ((DEBUG > 0) || (VERBOSE > 0))\r
1662 System.out.println("Setting the Output Filename:" + baseName);\r
1663 moduleDefs.setOutputFileBasename(baseName);\r
1664 }\r
1665\r
1666 if (result == PASS) {\r
1667 // TODO: Stub to write out the new MSA file\r
1668 File outMsa = new File(msaFilename);\r
1669 try {\r
1670 if (DEBUG > 2)\r
1671 System.out.println("SAVING new MSA FILE: " + msaFilename);\r
1672\r
1673 mergeMsaFile.setMsaHeader(header);\r
1674 mergeMsaFile.setModuleDefinitions(moduleDefs);\r
1675 // ALL THE REST OF THE SECTIONS ARE OPTIONAL\r
1676 // SO check that they are not null before adding them to the merged MSA file!\r
1677 if (libClassDefs != null)\r
1678 mergeMsaFile.setLibraryClassDefinitions(libClassDefs);\r
1679 if (mergeSourceFiles != null)\r
1680 mergeMsaFile.setSourceFiles(mergeSourceFiles);\r
1681 if (mergePackageDependencies != null)\r
1682 mergeMsaFile.setPackageDependencies(mergePackageDependencies);\r
1683 if (mergeProtocols != null)\r
1684 mergeMsaFile.setProtocols(mergeProtocols);\r
1685\r
1686 if ((mergeCreateEvents != null) || (mergeSignalEvents != null)) {\r
1687 if (mergeEvents == null)\r
1688 mergeEvents = EventsDocument.Factory.newInstance().addNewEvents();\r
1689\r
1690 if (mergeCreateEvents.getEventTypesList().size() > 0) {\r
1691 mergeEvents.addNewCreateEvents();\r
1692 mergeEvents.setCreateEvents(mergeCreateEvents);\r
1693 }\r
1694 if (mergeSignalEvents.getEventTypesList().size() > 0) {\r
1695 mergeEvents.addNewSignalEvents();\r
1696 mergeEvents.setSignalEvents(mergeSignalEvents);\r
1697 }\r
1698\r
1699 mergeMsaFile.setEvents(mergeEvents);\r
1700 }\r
1701\r
1702 if (mergeHobs != null)\r
1703 mergeMsaFile.setHobs(mergeHobs);\r
1704\r
1705 if (mergePpis != null)\r
1706 mergeMsaFile.setPPIs(mergePpis);\r
1707\r
1708 if (mergeVariables != null)\r
1709 mergeMsaFile.setVariables(mergeVariables);\r
1710\r
1711 if (mergeBootModes != null)\r
1712 mergeMsaFile.setBootModes(mergeBootModes);\r
1713\r
1714 if (mergeSystemTables != null)\r
1715 mergeMsaFile.setSystemTables(mergeSystemTables);\r
1716\r
1717 if (mergeDataHubs != null)\r
1718 mergeMsaFile.setDataHubs(mergeDataHubs);\r
1719\r
1720 if (mergeHiiPackages != null)\r
1721 mergeMsaFile.setHiiPackages(mergeHiiPackages);\r
1722\r
1723 if (mergeGuids != null)\r
1724 mergeMsaFile.setGuids(mergeGuids);\r
1725\r
1726 if (mergeExterns != null)\r
1727 mergeMsaFile.setExterns(mergeExterns);\r
1728\r
1729 if (mergePcdCoded != null)\r
1730 mergeMsaFile.setPcdCoded(mergePcdCoded);\r
1731\r
1732 XmlCursor cursor = XmlConfig.setupXmlCursor(mergeMsaFile.newCursor());\r
1733 XmlOptions options = XmlConfig.setupXmlOptions();\r
1734 ModuleSurfaceAreaDocument msaDoc = ModuleSurfaceAreaDocument.Factory.newInstance();\r
1735 msaDoc.addNewModuleSurfaceArea();\r
1736 msaDoc.setModuleSurfaceArea(mergeMsaFile);\r
1737 msaDoc.save(outMsa, options);\r
1738 System.out.println("The Merged MSA file: " + msaFilename + ", has been created!");\r
1739 } catch (IOException e) {\r
1740 System.out.println("Problem writing the output file: " + msaFilename + " " + e);\r
1741 result = FAIL;\r
1742 }\r
1743 }\r
1744\r
1745 if ((spdFilename != null) && (result == PASS)) {\r
1746 // TODO: Stub for adding the msaFile to the <MsaFiles><Filename> in the spdFile\r
1747 String msaLine = getPathFromSpd(spdFilename, msaFilename);\r
1748 System.out.println("Updating the SPD file (" + spdFilename + ") with: " + msaLine);\r
1749 try {\r
1750 File spdFile = new File(spdFilename);\r
1751 PackageSurfaceAreaDocument spdDoc = PackageSurfaceAreaDocument.Factory.parse(spdFile);\r
1752 PackageSurfaceArea spd = spdDoc.getPackageSurfaceArea();\r
1753\r
0e771cd3 1754 List<String> msaFilenames = spd.getMsaFiles().getFilenameList();\r
1755 msaFilenames.add(msaLine);\r
1756 XmlCursor cursor = XmlConfig.setupXmlCursor(spd.newCursor());\r
1757 XmlOptions options = XmlConfig.setupXmlOptions();\r
1758 spdDoc.save(spdFile, options);\r
1759 } catch (IOException e) {\r
1760 System.out.println("I/O Exception on spd file: " + spdFilename + " " + e);\r
1761 } catch (XmlException x) {\r
1762 System.out.println("XML Exception on SPD file: " + spdFilename + " " + x);\r
1763 }\r
1764 } else if ((spdFilename == null) && (result == PASS)) {\r
1765\r
1766 System.out.println("The file: " + msaFilename + ", must be added to a package file before it can be used!");\r
1767 }\r
1768 return result;\r
1769 }\r
1770\r
1771 public ModuleSurfaceArea getLeafFile(String filename) {\r
1772 File leafMsaFile = new File(filename);\r
1773 if ((DEBUG > 1) || (VERBOSE > 1))\r
1774 System.out.println("Processing MSA File: " + filename);\r
1775 try {\r
1776 leafMsa = ModuleSurfaceAreaDocument.Factory.parse(leafMsaFile).getModuleSurfaceArea();\r
1777 if ((DEBUG > 4) || (VERBOSE > 4))\r
1778 System.out.println("Binary: " + leafMsa.getModuleDefinitions().getBinaryModule());\r
1779 if (leafMsa.getModuleDefinitions().getBinaryModule()) {\r
1780 System.out.println("ERROR: Binary Module was specified in MSA: " + filename);\r
1781 System.out.println("Merge Aborted!");\r
1782 System.err.flush();\r
1783 return null;\r
1784 }\r
1785 } catch (IOException e) {\r
1786 System.out.println("I/O Exception on filename: " + filename + " " + e);\r
1787 System.out.println("Merge Aborted!");\r
1788 System.err.flush();\r
1789 System.exit(FAIL);\r
1790 } catch (XmlException x) {\r
1791 System.out.println("XML Exception reading file: " + filename + " " + x);\r
1792 System.out.println("Merge Aborted!");\r
1793 System.err.flush();\r
1794 System.exit(FAIL);\r
1795 }\r
1796 return leafMsa;\r
1797 }\r
1798\r
1799 private String getPathFromSpd(String spdFn, String msaFn) {\r
1800 String path2Msa = null;\r
1801\r
1802 spdFn = spdFn.replace("\\", "/").trim();\r
1803 String s[] = spdFn.split("/");\r
1804 String justSpdFilename = s[s.length - 1];\r
1805\r
1806 String Cwd = System.getProperty("user.dir");\r
1807 Cwd = Cwd.replace("\\", "/").trim();\r
1808 if ((DEBUG > 10) || (VERBOSE > 10)) {\r
1809 System.out.println("Current directory = " + Cwd);\r
1810 }\r
1811 String sp[] = Cwd.split("/");\r
1812 int theDirectory = sp.length - (s.length - 1);\r
1813 if (DEBUG > 10)\r
1814 System.out.println("The Directory length: " + theDirectory + " s.length: " + s.length + " sp.length: "\r
1815 + (sp.length - 1));\r
1816\r
1817 String path2Spd = "";\r
1818 for (int ictr = 0; ictr < theDirectory; ictr++) {\r
1819 path2Spd += sp[ictr] + "/";\r
1820 if (DEBUG > 10)\r
1821 System.out.println("Creating path to SPD file: " + path2Spd);\r
1822 }\r
1823\r
1824 String testPath2Spd = path2Spd + justSpdFilename;\r
1825\r
1826 File tFile = new File(testPath2Spd);\r
1827 if (!tFile.exists()) {\r
1828 System.out.println("The specified SPD file, " + spdFn + " does not exist at: " + testPath2Spd);\r
1829 System.out.println("Please use the FrameworkWizard to add this MSA file to the package.");\r
1830 System.exit(FAIL);\r
1831 }\r
1832 path2Msa = Cwd.replace(path2Spd, "");\r
1833 path2Msa = path2Msa + "/" + msaFn;\r
1834 return path2Msa;\r
1835 }\r
1836\r
1837 private String checkDuplicateStrings(String aString, ArrayList<String> aList) {\r
1838\r
1839 for (int lctr = 0; lctr < aList.size(); lctr++) {\r
1840 if (DEBUG > 8)\r
1841 System.out.println("Comparing: \n" + aString.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
1842 + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
1843 if (aString.replace(" ", "").replace("\n", "").contains(\r
1844 aList.get(lctr).replace(" ", "").replace("\n", "")\r
1845 .toString().trim())) {\r
1846 if ((DEBUG > 3) || (VERBOSE > 3))\r
1847 System.out.println("Found a duplicate String, skipping!");\r
1848 return "";\r
1849 }\r
1850 }\r
1851 if ((DEBUG > 3) || (VERBOSE > 3))\r
1852 System.out.println("Returning UNIQUE String!\n " + aString);\r
1853 aList.add(aString);\r
1854 return aString;\r
1855 }\r
1856\r
1857 private String checkSpecs(String specName, String filename, ArrayList<String> aList) {\r
1858 // Check Specifications\r
1859 // Skip of Specs are identical\r
1860 String spec[] = new String[2];\r
1861 spec = specName.replace(" ", " ").trim().split(" ");\r
1862 String specInMem[] = new String[2];\r
1863 if ((DEBUG > 10) || (VERBOSE > 10))\r
1864 System.out.println("Specification: " + specName);\r
1865\r
1866 for (int lctr = 0; lctr < aList.size(); lctr++) {\r
1867 if (DEBUG > 8)\r
1868 System.out.println("Comparing: \n" + specName.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
1869 + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
1870 if (specName.replace(" ", "").replace("\n", "").contains(\r
1871 aList.get(lctr).replace(" ", "").replace("\n", "")\r
1872 .toString().trim())) {\r
1873 if ((DEBUG > 3) || (VERBOSE > 3))\r
1874 System.out.println("Found a duplicate String, skipping!");\r
1875 return "";\r
1876 }\r
1877 specInMem = aList.get(lctr).replace(" ", " ").trim().split(" ");\r
1878 if (spec[0].contentEquals(specInMem[0])) {\r
1879 if (!spec[1].contains(specInMem[1])) {\r
1880 System.out.println("Module: " + filename + " is coded to " + specName);\r
1881 System.out.println("Merge needs to be coded to: " + aList.get(lctr));\r
1882 System.out.println("Merge Aborted!");\r
1883 System.err.flush();\r
1884 System.exit(FAIL);\r
1885 }\r
1886 }\r
1887\r
1888 }\r
1889 if ((DEBUG > 3) || (VERBOSE > 3))\r
1890 System.out.println("Returning Specification: " + specName);\r
1891 aList.add(specName);\r
1892 return specName;\r
1893 }\r
1894\r
1895 private String checkPcd(String pcdName, String itemType, String filename, ArrayList<String> aList) {\r
1896\r
1897 for (int lctr = 0; lctr < aList.size(); lctr++) {\r
1898 if (DEBUG > 8)\r
1899 System.out.println("Comparing: \n" + pcdName.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
1900 + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
1901 if (pcdName.replace(" ", "").replace("\n", "").contains(\r
1902 aList.get(lctr).replace(" ", "").replace("\n", "")\r
1903 .toString().trim())) {\r
1904 if (!aPcdItemTypeList.get(lctr).contains(itemType)) {\r
1905 System.out\r
1906 .println("The Pcd Item Type for " + pcdName + " in file: " + filename + "does not match!");\r
1907 System.out.println("Expected: " + aPcdItemTypeList.get(lctr));\r
1908 System.out.println("Was set to: " + itemType);\r
1909 System.out.println("Merge Aborted!");\r
1910 System.err.flush();\r
1911 System.exit(FAIL);\r
1912 }\r
1913 if ((DEBUG > 3) || (VERBOSE > 3))\r
1914 System.out.println("Found a duplicate String, skipping!");\r
1915 return "";\r
1916 }\r
1917 }\r
1918 if ((DEBUG > 3) || (VERBOSE > 3))\r
1919 System.out.println("Returning UNIQUE String!\n " + pcdName);\r
1920 aPcdItemTypeList.add(itemType);\r
1921 aList.add(pcdName);\r
1922 return pcdName;\r
1923 }\r
1924\r
1925 private String checkUsage() {\r
1926 String result = "";\r
1927 // Usage types are different\r
1928 if (((mergeUsage.contains("CONSUMED")) && (leafUsage.contains("PRODUCED")))\r
1929 || ((mergeUsage.contains("PRODUCED")) && (leafUsage.contains("CONSUMED")))\r
1930 || ((mergeUsage.contains("TO_START")) && (leafUsage.contains("BY_START")))\r
1931 || ((mergeUsage.contains("BY_START")) && (leafUsage.contains("TO_START")))) {\r
1932 result = "DIFFERENT";\r
1933 }\r
1934 // Both Usage types are PRODUCED\r
1935 if (((mergeUsage.contains("ALWAYS_PRODUCED")) && (leafUsage.contains("SOMETIMES_PRODUCED")))\r
1936 || ((mergeUsage.contains("SOMETIMES_PRODUCED")) && (leafUsage.contains("ALWAYS_PRODUCED")))) {\r
1937 result = "PRODUCED";\r
1938 }\r
1939\r
1940 // Both Usage types are CONSUMED\r
1941 if (((mergeUsage.contains("ALWAYS_CONSUMED")) && (leafUsage.contains("SOMETIMES_CONSUMED")))\r
1942 || ((mergeUsage.contains("SOMETIMES_CONSUMED")) && (leafUsage.contains("ALWAYS_CONSUMED")))) {\r
1943 result = "CONSUMED";\r
1944 }\r
1945 return result;\r
1946 }\r
1947\r
1948 private boolean checkProduced() {\r
1949 boolean result = false;\r
1950\r
1951 if (((mergeUsage.contains("ALWAYS_PRODUCED")) && (leafUsage.contains("SOMETIMES_PRODUCED")))\r
1952 || ((mergeUsage.contains("SOMETIMES_PRODUCED")) && (leafUsage.contains("ALWAYS_PRODUCED")))) {\r
1953 result = true;\r
1954 }\r
1955 return result;\r
1956 }\r
1957\r
1958 private boolean checkConsumed() {\r
1959 boolean result = false;\r
1960\r
1961 if (((mergeUsage.contains("ALWAYS_CONSUMED")) && (leafUsage.contains("SOMETIMES_CONSUMED")))\r
1962 || ((mergeUsage.contains("SOMETIMES_CONSUMED")) && (leafUsage.contains("ALWAYS_CONSUMED")))) {\r
1963 result = true;\r
1964 }\r
1965 return result;\r
1966 }\r
1967\r
1968 private String getPathPartOfLeafMsa(String sFilename) {\r
1969 String pathName = "";\r
1970 String s[] = sFilename.replace("\\", "/").trim().split("/");\r
1971 for (int j = 0; j < (s.length - 1); j++) {\r
1972 pathName += s[j] + "/";\r
1973 }\r
1974 return pathName;\r
1975 }\r
1976\r
1977 private static class XmlConfig {\r
1978 public static XmlCursor setupXmlCursor(XmlCursor cursor) {\r
1979 String uri = "http://www.TianoCore.org/2006/Edk2.0";\r
1980 cursor.push();\r
1981 cursor.toNextToken();\r
1982 cursor.insertNamespace("", uri);\r
1983 cursor.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");\r
1984 cursor.pop();\r
1985 return cursor;\r
1986\r
1987 }\r
1988\r
1989 public static XmlOptions setupXmlOptions() {\r
1990 XmlOptions options = new XmlOptions();\r
1991 options.setCharacterEncoding("UTF-8");\r
1992 options.setSavePrettyPrint();\r
1993 options.setSavePrettyPrintIndent(2);\r
1994 return options;\r
1995 }\r
1996\r
1997 }\r
1998}\r