summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/Python/UPT/Xml/XmlParser.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/UPT/Xml/XmlParser.py')
-rw-r--r--BaseTools/Source/Python/UPT/Xml/XmlParser.py926
1 files changed, 926 insertions, 0 deletions
diff --git a/BaseTools/Source/Python/UPT/Xml/XmlParser.py b/BaseTools/Source/Python/UPT/Xml/XmlParser.py
new file mode 100644
index 0000000000..5a2f0dc705
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/XmlParser.py
@@ -0,0 +1,926 @@
+## @file
+# This file is used to parse a xml file of .PKG file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+XmlParser
+'''
+
+##
+# Import Modules
+#
+import re
+
+from Library.Xml.XmlRoutines import XmlNode
+from Library.Xml.XmlRoutines import CreateXmlElement
+from Library.Xml.XmlRoutines import XmlList
+from Library.Xml.XmlRoutines import XmlParseFile
+from Core.DistributionPackageClass import DistributionPackageClass
+from Object.POM.ModuleObject import DepexObject
+from Library.ParserValidate import IsValidInfMoudleType
+from Library.ParserValidate import IsValidInstallPath
+from Library.Misc import IsEqualList
+from Library.Misc import Sdict
+
+from Logger.StringTable import ERR_XML_INVALID_VARIABLENAME
+from Logger.StringTable import ERR_XML_INVALID_LIB_SUPMODLIST
+from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPARCHLIST
+from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST
+from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB
+from Logger.StringTable import ERR_FILE_NAME_INVALIDE
+from Logger.StringTable import ERR_XML_INVALID_BINARY_FILE_TYPE
+from Logger.ToolError import PARSER_ERROR
+from Logger.ToolError import FORMAT_INVALID
+
+from Xml.CommonXml import DistributionPackageHeaderXml
+from Xml.CommonXml import MiscellaneousFileXml
+from Xml.CommonXml import UserExtensionsXml
+from Xml.XmlParserMisc import ConvertVariableName
+from Xml.XmlParserMisc import IsRequiredItemListNull
+from Xml.ModuleSurfaceAreaXml import ModuleSurfaceAreaXml
+from Xml.PackageSurfaceAreaXml import PackageSurfaceAreaXml
+
+import Logger.Log as Logger
+
+##
+# DistributionPackageXml
+#
+class DistributionPackageXml(object):
+ def __init__(self):
+ self.DistP = DistributionPackageClass()
+ self.Pkg = ''
+
+ ## ValidateDistributionPackage
+ #
+ # Check if any required item is missing in DistributionPackage
+ #
+ def ValidateDistributionPackage(self):
+ XmlTreeLevel = ['DistributionPackage']
+ if self.DistP:
+ #
+ # Check DistributionPackage -> DistributionHeader
+ #
+ XmlTreeLevel = ['DistributionPackage', '']
+ CheckDict = {'DistributionHeader':self.DistP.Header }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if self.DistP.Header:
+ DpHeader = self.DistP.Header
+ XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
+ CheckDict = Sdict()
+ CheckDict['Name'] = DpHeader.GetName()
+ CheckDict['GUID'] = DpHeader.GetGuid()
+ CheckDict['Version'] = DpHeader.GetVersion()
+ CheckDict['Copyright'] = DpHeader.GetCopyright()
+ CheckDict['License'] = DpHeader.GetLicense()
+ CheckDict['Abstract'] = DpHeader.GetAbstract()
+ CheckDict['Vendor'] = DpHeader.GetVendor()
+ CheckDict['Date'] = DpHeader.GetDate()
+ CheckDict['XmlSpecification'] = DpHeader.GetXmlSpecification()
+
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ else:
+ XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
+ CheckDict = CheckDict = {'DistributionHeader':'', }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check Each Package
+ #
+ for Key in self.DistP.PackageSurfaceArea:
+ ValidatePackageSurfaceArea(self.DistP.PackageSurfaceArea[Key])
+
+ #
+ # Check Each Module
+ #
+ for Key in self.DistP.ModuleSurfaceArea:
+ ValidateMS(self.DistP.ModuleSurfaceArea[Key], ['DistributionPackage', 'ModuleSurfaceArea'])
+
+ #
+ # Check Each Tool
+ #
+ if self.DistP.Tools:
+ XmlTreeLevel = ['DistributionPackage', 'Tools', 'Header']
+ CheckDict = {'Name':self.DistP.Tools.GetName(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if not self.DistP.Tools.GetFileList():
+ XmlTreeLevel = ['DistributionPackage', 'Tools']
+ CheckDict = {'FileName':None, }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for Item in self.DistP.Tools.GetFileList():
+ XmlTreeLevel = ['DistributionPackage', 'Tools']
+ CheckDict = {'FileName':Item.GetURI(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check Each Misc File
+ #
+ if self.DistP.MiscellaneousFiles:
+ XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles', 'Header']
+ CheckDict = {'Name':self.DistP.MiscellaneousFiles.GetName(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if not self.DistP.MiscellaneousFiles.GetFileList():
+ XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
+ CheckDict = {'FileName':None, }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for Item in self.DistP.MiscellaneousFiles.GetFileList():
+ XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
+ CheckDict = {'FileName':Item.GetURI(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check Each Distribution Level User Extension
+ #
+ for Item in self.DistP.UserExtensions:
+ XmlTreeLevel = ['DistributionPackage', 'UserExtensions']
+ CheckDict = {'UserId':Item.GetUserID(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+
+ def FromXml(self, Filename=None):
+ if Filename != None:
+ self.DistP = DistributionPackageClass()
+ #
+ # Load to XML
+ #
+ self.Pkg = XmlParseFile(Filename)
+
+ #
+ # Parse Header information
+ #
+ Tmp = DistributionPackageHeaderXml()
+ DistributionPackageHeader = \
+ Tmp.FromXml(XmlNode(self.Pkg, '/DistributionPackage/DistributionHeader'), 'DistributionHeader')
+ self.DistP.Header = DistributionPackageHeader
+ #
+ # Parse each PackageSurfaceArea
+ #
+ for Item in XmlList(self.Pkg, '/DistributionPackage/PackageSurfaceArea'):
+ Psa = PackageSurfaceAreaXml()
+ Package = Psa.FromXml(Item, 'PackageSurfaceArea')
+ self.DistP.PackageSurfaceArea[(Package.GetGuid(), \
+ Package.GetVersion(), \
+ Package.GetPackagePath())] = \
+ Package
+ #
+ # Parse each ModuleSurfaceArea
+ #
+ for Item in XmlList(self.Pkg, '/DistributionPackage/ModuleSurfaceArea'):
+ Msa = ModuleSurfaceAreaXml()
+ Module = Msa.FromXml(Item, 'ModuleSurfaceArea', True)
+ ModuleKey = (Module.GetGuid(), Module.GetVersion(), Module.GetName(), Module.GetModulePath())
+ self.DistP.ModuleSurfaceArea[ModuleKey] = Module
+
+ #
+ # Parse Tools
+ #
+ Tmp = MiscellaneousFileXml()
+ self.DistP.Tools = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/Tools'), 'Tools')
+
+ #
+ # Parse MiscFiles
+ #
+ Tmp = MiscellaneousFileXml()
+ self.DistP.MiscellaneousFiles = \
+ Tmp.FromXml2(XmlNode(self.Pkg, \
+ '/DistributionPackage/MiscellaneousFiles'), \
+ 'MiscellaneousFiles')
+
+ #
+ # Parse UserExtensions
+ #
+ for Item in XmlList(self.Pkg, '/DistributionPackage/UserExtensions'):
+ Tmp = UserExtensionsXml()
+ self.DistP.UserExtensions.append(Tmp.FromXml2(Item, 'UserExtensions'))
+
+ #
+ # Check Required Items for XML
+ #
+ self.ValidateDistributionPackage()
+
+ return self.DistP
+
+ def ToXml(self, DistP):
+ if self.DistP:
+ pass
+ if DistP != None:
+ #
+ # Parse DistributionPackageHeader
+ #
+ Attrs = [['xmlns', 'http://www.uefi.org/2011/1.1'],
+ ['xmlns:xsi', 'http:/www.w3.org/2001/XMLSchema-instance'],
+ ]
+ Root = CreateXmlElement('DistributionPackage', '', [], Attrs)
+
+ Tmp = DistributionPackageHeaderXml()
+ Root.appendChild(Tmp.ToXml(DistP.Header, 'DistributionHeader'))
+ #
+ # Parse each PackageSurfaceArea
+ #
+ for Package in DistP.PackageSurfaceArea.values():
+ Psa = PackageSurfaceAreaXml()
+ DomPackage = Psa.ToXml(Package)
+ Root.appendChild(DomPackage)
+ #
+ # Parse each ModuleSurfaceArea
+ #
+ for Module in DistP.ModuleSurfaceArea.values():
+ Msa = ModuleSurfaceAreaXml()
+ DomModule = Msa.ToXml(Module)
+ Root.appendChild(DomModule)
+ #
+ # Parse Tools
+ #
+ Tmp = MiscellaneousFileXml()
+ ToolNode = Tmp.ToXml2(DistP.Tools, 'Tools')
+ if ToolNode is not None:
+ Root.appendChild(ToolNode)
+ #
+ # Parse MiscFiles
+ #
+ Tmp = MiscellaneousFileXml()
+ MiscFileNode = Tmp.ToXml2(DistP.MiscellaneousFiles,
+ 'MiscellaneousFiles')
+ if MiscFileNode is not None:
+ Root.appendChild(MiscFileNode)
+
+ XmlContent = Root.toprettyxml(indent=' ')
+
+
+ #
+ # Remove empty element
+ #
+ XmlContent = re.sub(r'[\s\r\n]*<[^<>=]*/>', '', XmlContent)
+
+ #
+ # Remove empty help text element
+ #
+ XmlContent = re.sub(r'[\s\r\n]*<HelpText Lang="en-US"/>', '',
+ XmlContent)
+
+ #
+ # Remove SupArchList="COMMON" or "common"
+ #
+ XmlContent = \
+ re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
+ '[\s\r\n]*"', '', XmlContent)
+ XmlContent = \
+ re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
+ '[\s\r\n]*"', '', XmlContent)
+ #
+ # Remove <SupArchList> COMMON </SupArchList>
+ #
+ XmlContent = \
+ re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*COMMON[\s\r\n]*'
+ '</SupArchList>[\s\r\n]*', '', XmlContent)
+
+ #
+ # Remove <SupArchList> common </SupArchList>
+ #
+ XmlContent = \
+ re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*'
+ 'common[\s\r\n]*</SupArchList>[\s\r\n]*', '', XmlContent)
+
+ #
+ # Remove SupModList="COMMON" or "common"
+ #
+ XmlContent = \
+ re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
+ '[\s\r\n]*"', '', XmlContent)
+ XmlContent = \
+ re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
+ '[\s\r\n]*"', '', XmlContent)
+
+ return XmlContent
+
+ return ''
+
+## ValidateMS
+#
+# Check if any required item is missing in ModuleSurfaceArea
+#
+# @param Module: The ModuleSurfaceArea to be checked
+# @param XmlTreeLevel: The top level of Module
+#
+def ValidateMS(Module, TopXmlTreeLevel):
+ ValidateMS1(Module, TopXmlTreeLevel)
+ ValidateMS2(Module, TopXmlTreeLevel)
+ ValidateMS3(Module, TopXmlTreeLevel)
+
+## ValidateMS1
+#
+# Check if any required item is missing in ModuleSurfaceArea
+#
+# @param Module: The ModuleSurfaceArea to be checked
+# @param XmlTreeLevel: The top level of Module
+#
+def ValidateMS1(Module, TopXmlTreeLevel):
+ #
+ # Check Guids -> GuidCName
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['Guids']
+ for Item in Module.GetGuidList():
+ if Item == None:
+ CheckDict = {'GuidCName':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['Guids', 'GuidCName']
+ for Item in Module.GetGuidList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'GuidType':Item.GetGuidTypeList(),
+ 'Usage':Item.GetUsage()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if Item.GetVariableName():
+ Result = ConvertVariableName(Item.GetVariableName())
+ if Result is None:
+ Msg = "->".join(Node for Node in XmlTreeLevel)
+ ErrorMsg = ERR_XML_INVALID_VARIABLENAME % (Item.GetVariableName(), Item.GetCName(), Msg)
+ Logger.Error('\nUPT', PARSER_ERROR, ErrorMsg, RaiseError=True)
+ else:
+ Item.SetVariableName(Result)
+
+ #
+ # Check Protocols -> Protocol
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['Protocols']
+ for Item in Module.GetProtocolList():
+ if Item == None:
+ CheckDict = {'Protocol':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['Protocols', 'Protocol']
+ for Item in Module.GetProtocolList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'Usage':Item.GetUsage()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check PPIs -> Ppi
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['PPIs']
+ for Item in Module.GetPpiList():
+ if Item == None:
+ CheckDict = {'Ppi':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['PPIs', 'Ppi']
+ for Item in Module.GetPpiList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'Usage':Item.GetUsage()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check PcdCoded -> Entry
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded']
+ for Item in Module.GetPcdList():
+ if Item == None:
+ CheckDict = {'PcdEntry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded', 'PcdEntry']
+ for Item in Module.GetPcdList():
+ CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
+ 'CName':Item.GetCName(),
+ 'PcdUsage':Item.GetValidUsage(),
+ 'PcdItemType':Item.GetItemType()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check Externs -> Extern
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['Externs']
+ for Item in Module.GetExternList():
+ if Item == None:
+ CheckDict = {'Extern':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # If SupArchList is used to identify different EntryPoint, UnloadImage, Constructor/Destructor elements and
+ # that SupArchList does not match ModuleSurfaceArea.ModuleProperties:SupArchList, the tool must exit gracefully,
+ # informing the user that the EDK II Build system does not support different EntryPoint, UnloadImage,
+ # Constructor or Destructor elements based on Architecture type. Two SupArchList attributes are considered
+ # identical if it lists the same CPU architectures in any order.
+ #
+ for Item in Module.GetExternList():
+ if len(Item.SupArchList) > 0:
+ if not IsEqualList(Item.SupArchList, Module.SupArchList):
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_EXTERN_SUPARCHLIST % (str(Item.SupArchList), str(Module.SupArchList)),
+ RaiseError=True)
+
+ #
+ # Check DistributionPackage -> ModuleSurfaceArea -> UserExtensions
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
+ for Item in Module.GetUserExtensionList():
+ CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['MiscellaneousFiles']
+ for Item in Module.GetMiscFileList():
+ if not Item.GetFileList():
+ CheckDict = {'Filename':'', }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for File in Item.GetFileList():
+ CheckDict = {'Filename':File.GetURI(), }
+
+## ValidateMS2
+#
+# Check if any required item is missing in ModuleSurfaceArea
+#
+# @param Module: The ModuleSurfaceArea to be checked
+# @param XmlTreeLevel: The top level of Module
+#
+def ValidateMS2(Module, TopXmlTreeLevel):
+ #
+ # Check Header
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['Header']
+ CheckDict = Sdict()
+ CheckDict['Name'] = Module.GetName()
+ CheckDict['BaseName'] = Module.GetBaseName()
+ CheckDict['GUID'] = Module.GetGuid()
+ CheckDict['Version'] = Module.GetVersion()
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check ModuleProperties
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties']
+ CheckDict = {'ModuleType':Module.GetModuleType(),
+ 'Path':Module.GetModulePath()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if not IsValidInstallPath(Module.GetModulePath()):
+ Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Module.GetModulePath())
+
+ #
+ # Check ModuleProperties->BootMode
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['BootMode']
+ for Item in Module.GetBootModeList():
+ CheckDict = {'Usage':Item.GetUsage(),
+ 'SupportedBootModes':Item.GetSupportedBootModes()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check ModuleProperties->Event
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['Event']
+ for Item in Module.GetEventList():
+ CheckDict = {'Usage':Item.GetUsage(),
+ 'EventType':Item.GetEventType()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check ModuleProperties->Hob
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['HOB']
+ for Item in Module.GetHobList():
+ CheckDict = {'Usage':Item.GetUsage(),
+ 'HobType':Item.GetHobType()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # The UDP Specification supports the module type of UEFI_RUNTIME_DRIVER, which is not present in the EDK II INF
+ # File Specification v. 1.23, so UPT must perform the following translation that include the generation of a
+ # [Depex] section.
+ #
+ if Module.ModuleType == "UEFI_RUNTIME_DRIVER":
+ Module.ModuleType = "DXE_RUNTIME_DRIVER"
+ DxeObj = DepexObject()
+ DxeObj.SetDepex("gEfiBdsArchProtocolGuid AND \ngEfiCpuArchProtocolGuid AND\n" + \
+ "gEfiMetronomeArchProtocolGuid AND \ngEfiMonotonicCounterArchProtocolGuid AND\n" + \
+ "gEfiRealTimeClockArchProtocolGuid AND \ngEfiResetArchProtocolGuid AND\n" + \
+ "gEfiRuntimeArchProtocolGuid AND \ngEfiSecurityArchProtocolGuid AND\n" + \
+ "gEfiTimerArchProtocolGuid AND \ngEfiVariableWriteArchProtocolGuid AND\n" + \
+ "gEfiVariableArchProtocolGuid AND \ngEfiWatchdogTimerArchProtocolGuid")
+ DxeObj.SetModuleType(['DXE_RUNTIME_DRIVER'])
+ Module.PeiDepex = []
+ Module.DxeDepex = []
+ Module.SmmDepex = []
+ Module.DxeDepex.append(DxeObj)
+
+ #
+ # Check LibraryClassDefinitions -> LibraryClass
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions']
+ for Item in Module.GetLibraryClassList():
+ if Item == None:
+ CheckDict = {'LibraryClass':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions', 'LibraryClass']
+
+ IsLibraryModule = False
+ LibrarySupModList = []
+ for Item in Module.GetLibraryClassList():
+ CheckDict = {'Keyword':Item.GetLibraryClass(),
+ 'Usage':Item.GetUsage()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # If the LibraryClass:SupModList is not "UNDEFINED" the LIBRARY_CLASS entry must have the list
+ # appended using the format:
+ # LIBRARY_CLASS = <ClassName> ["|" <Edk2ModuleTypeList>]
+ #
+ # Edk2ModuleTypeList ::= <ModuleType> [" " <ModuleType>]{0,}
+ # <ModuleTypes> ::= {"BASE"} {"SEC"} {"PEI_CORE"} {"PEIM"}
+ # {"DXE_CORE"} {"DXE_DRIVER"} {"SMM_CORE"}
+ # {"DXE_SMM_DRIVER"} {"DXE_RUNTIME_DRIVER"}
+ # {"DXE_SAL_DRIVER"} {"UEFI_DRIVER"}
+ # {"UEFI_APPLICATION"} {"USER_DEFINED"}
+ #
+ if len(Item.SupModuleList) > 0:
+ for SupModule in Item.SupModuleList:
+ if not IsValidInfMoudleType(SupModule):
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_LIB_SUPMODLIST % (Item.LibraryClass, str(SupModule)),
+ RaiseError=True)
+
+ if Item.Usage == 'PRODUCES' or Item.Usage == 'SOMETIMES_PRODUCES':
+ IsLibraryModule = True
+ LibrarySupModList = Item.SupModuleList
+
+
+ #
+ # For Library modules (indicated by a LIBRARY_CLASS statement in the [Defines] section)
+ # If the SupModList attribute of the CONSTRUCTOR or DESTRUCTOR element does not match the Supported Module
+ # Types listed after "LIBRARY_CLASS = <Keyword> |", the tool should gracefully exit with an error message
+ # stating that there is a conflict in the module types the CONSTRUCTOR/DESTRUCTOR is to be used with and
+ # the Module types this Library supports.
+ #
+ if IsLibraryModule:
+ for Item in Module.GetExternList():
+ if Item.Constructor or Item.Destructor:
+ if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
+ not IsEqualList(Item.SupModList, LibrarySupModList):
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_EXTERN_SUPMODLIST % (str(Item.SupModList), str(LibrarySupModList)),
+ RaiseError=True)
+
+ #
+ # If the module is not a library module, the MODULE_TYPE listed in the ModuleSurfaceArea.Header must match the
+ # SupModList attribute. If these conditions cannot be met, the tool must exit gracefully, informing the user
+ # that the EDK II Build system does not currently support the features required by this Module.
+ #
+ if not IsLibraryModule:
+ for Item in Module.GetExternList():
+ if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
+ not IsEqualList(Item.SupModList, [Module.ModuleType]):
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB % (str(Module.ModuleType), str(Item.SupModList)),
+ RaiseError=True)
+ #
+ # Check SourceFiles
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
+ for Item in Module.GetSourceFileList():
+ if Item == None:
+ CheckDict = {'Filename':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
+ for Item in Module.GetSourceFileList():
+ CheckDict = {'Filename':Item.GetSourceFile()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ for ItemCount in range(len(Module.GetBinaryFileList())):
+ Item = Module.GetBinaryFileList()[ItemCount]
+ if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'FREEFORM':
+ Item.FileNamList[0].FileType = 'SUBTYPE_GUID'
+ Module.GetBinaryFileList()[ItemCount] = Item
+ if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'DISPOSABLE':
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_BINARY_FILE_TYPE % ('DISPOSABLE'),
+ RaiseError=True)
+
+## ValidateMS3
+#
+# Check if any required item is missing in ModuleSurfaceArea
+#
+# @param Module: The ModuleSurfaceArea to be checked
+# @param XmlTreeLevel: The top level of Module
+#
+def ValidateMS3(Module, TopXmlTreeLevel):
+ #
+ # Check PackageDependencies -> Package
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies']
+ for Item in Module.GetPackageDependencyList():
+ if Item == None:
+ CheckDict = {'Package':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies', 'Package']
+ for Item in Module.GetPackageDependencyList():
+ CheckDict = {'GUID':Item.GetGuid()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check BinaryFiles -> BinaryFile
+ #
+ for Item in Module.GetBinaryFileList():
+ if Item == None:
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles']
+ CheckDict = {'BinaryFile':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ if not Item.GetFileNameList():
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
+ CheckDict = {'Filename':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
+ for File in Item.GetFileNameList():
+ CheckDict = {'Filename':File.GetFilename(),
+ 'FileType':File.GetFileType()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for AsBuilt in Item.GetAsBuiltList():
+ #
+ # Check LibInstance
+ #
+ if len(AsBuilt.LibraryInstancesList) == 1 and not AsBuilt.LibraryInstancesList[0]:
+ CheckDict = {'GUID':''}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ for LibItem in AsBuilt.LibraryInstancesList:
+ CheckDict = {'Guid':LibItem.Guid,
+ 'Version':LibItem.Version}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check PatchPcd
+ #
+ for PatchPcdItem in AsBuilt.PatchPcdList:
+ CheckDict = {'TokenSpaceGuidValue':PatchPcdItem.TokenSpaceGuidValue,
+ 'PcdCName':PatchPcdItem.PcdCName,
+ 'Token':PatchPcdItem.Token,
+ 'DatumType':PatchPcdItem.DatumType,
+ 'Value':PatchPcdItem.DefaultValue,
+ 'Offset':PatchPcdItem.Offset}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PatchPcdValue']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # Check PcdError
+ #
+ for PcdErrorItem in PatchPcdItem.PcdErrorsList:
+ CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
+ 'PatchPcdValue', 'PcdError']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # Check PcdEx
+ #
+ for PcdExItem in AsBuilt.PcdExValueList:
+ CheckDict = {'TokenSpaceGuidValue':PcdExItem.TokenSpaceGuidValue,
+ 'Token':PcdExItem.Token,
+ 'DatumType':PcdExItem.DatumType,
+ 'Value':PcdExItem.DefaultValue}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PcdExValue']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # Check PcdError
+ #
+ for PcdErrorItem in PcdExItem.PcdErrorsList:
+ CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
+ 'PcdExValue', 'PcdError']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # Check SmmDepex
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['SmmDepex']
+ for Item in Module.GetSmmDepex():
+ CheckDict = {'Expression':Item.GetDepex()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check PeiDepex
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['PeiDepex']
+ for Item in Module.GetPeiDepex():
+ CheckDict = {'Expression':Item.GetDepex()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DxeDepex
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['DxeDepex']
+ for Item in Module.GetDxeDepex():
+ CheckDict = {'Expression':Item.GetDepex()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check <UserExtensions>
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
+ for Item in Module.GetUserExtensionList():
+ CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+## ValidatePS1
+#
+# ValidatePS1
+#
+def ValidatePS1(Package):
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> Header
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Header']
+ CheckDict = Sdict()
+ CheckDict['Name'] = Package.GetName()
+ CheckDict['BaseName'] = Package.GetBaseName()
+ CheckDict['GUID'] = Package.GetGuid()
+ CheckDict['Version'] = Package.GetVersion()
+ CheckDict['PackagePath'] = Package.GetPackagePath()
+
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ if not IsValidInstallPath(Package.GetPackagePath()):
+ Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Package.GetPackagePath())
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> ClonedFrom
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ClonedFrom']
+ for Item in Package.GetClonedFromList():
+ if Item == None:
+ CheckDict = Sdict()
+ CheckDict['GUID'] = ''
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ CheckDict = Sdict()
+ CheckDict['GUID'] = Item.GetPackageGuid()
+ CheckDict['Version'] = Item.GetPackageVersion()
+
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> LibraryClassDeclarations -> LibraryClass
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations']
+ for Item in Package.GetLibraryClassList():
+ if Item == None:
+ CheckDict = {'LibraryClass':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations', 'LibraryClass']
+ for Item in Package.GetLibraryClassList():
+ CheckDict = {'Keyword':Item.GetLibraryClass(),
+ 'HeaderFile':Item.GetIncludeHeader()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> IndustryStandardIncludes -> IndustryStandardHeader
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes']
+ for Item in Package.GetStandardIncludeFileList():
+ if Item == None:
+ CheckDict = {'IndustryStandardHeader':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes', 'IndustryStandardHeader']
+ for Item in Package.GetStandardIncludeFileList():
+ CheckDict = {'HeaderFile':Item.GetFilePath()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> PackageIncludes -> PackageHeader
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes']
+ for Item in Package.GetPackageIncludeFileList():
+ if Item == None:
+ CheckDict = {'PackageHeader':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes', 'PackageHeader']
+ for Item in Package.GetPackageIncludeFileList():
+ CheckDict = {'HeaderFile':Item.GetFilePath()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+## ValidatePS2
+#
+# ValidatePS2
+#
+def ValidatePS2(Package):
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> Modules -> ModuleSurfaceArea
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Modules', 'ModuleSurfaceArea']
+ for Item in Package.GetModuleDict().values():
+ ValidateMS(Item, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> GuidDeclarations Entry
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations']
+ for Item in Package.GetGuidList():
+ if Item == None:
+ CheckDict = {'Entry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations', 'Entry']
+ for Item in Package.GetGuidList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'GuidValue':Item.GetGuid()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> ProtocolDeclarations -> Entry
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations']
+ for Item in Package.GetProtocolList():
+ if Item == None:
+ CheckDict = {'Entry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations', 'Entry']
+ for Item in Package.GetProtocolList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'GuidValue':Item.GetGuid()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> PpiDeclarations -> Entry
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations']
+ for Item in Package.GetPpiList():
+ if Item == None:
+ CheckDict = {'Entry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations', 'Entry']
+ for Item in Package.GetPpiList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'GuidValue':Item.GetGuid()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> PcdDeclarations -> Entry
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations']
+ for Item in Package.GetPcdList():
+ if Item == None:
+ CheckDict = {'PcdEntry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations', 'PcdEntry']
+ for Item in Package.GetPcdList():
+ CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
+ 'Token':Item.GetToken(),
+ 'CName':Item.GetCName(),
+ 'DatumType':Item.GetDatumType(),
+ 'ValidUsage':Item.GetValidUsage(),
+ 'DefaultValue':Item.GetDefaultValue()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> UserExtensions
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'UserExtensions']
+ for Item in Package.GetUserExtensionList():
+ CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'MiscellaneousFiles']
+ for Item in Package.GetMiscFileList():
+ if not Item.GetFileList():
+ CheckDict = {'Filename':'', }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for File in Item.GetFileList():
+ CheckDict = {'Filename':File.GetURI(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+## ValidatePackageSurfaceArea
+#
+# Check if any required item is missing in PackageSurfaceArea
+#
+# @param Package: The PackageSurfaceArea to be checked
+#
+def ValidatePackageSurfaceArea(Package):
+ ValidatePS1(Package)
+ ValidatePS2(Package)