diff options
| author | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
|---|---|---|
| committer | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
| commit | 7e2ccccace24636f29ddc210b94606abd4c7e42b (patch) | |
| tree | 545d43ea12671048956cafeb12303e84d601e571 /BaseTools/Source/Python/Workspace/DecBuildData.py | |
| parent | 27b044605cd5f6b33a3d231576003850b3fe305b (diff) | |
| download | edk2-trunk.tar.xz | |
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'BaseTools/Source/Python/Workspace/DecBuildData.py')
| -rw-r--r-- | BaseTools/Source/Python/Workspace/DecBuildData.py | 922 |
1 files changed, 461 insertions, 461 deletions
diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py index eeb7c490ac..9289e969fb 100644 --- a/BaseTools/Source/Python/Workspace/DecBuildData.py +++ b/BaseTools/Source/Python/Workspace/DecBuildData.py @@ -1,461 +1,461 @@ -## @file
-# This file is used to create a database used by build tool
-#
-# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
-# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-from Common.StringUtils import *
-from Common.DataType import *
-from Common.Misc import *
-from types import *
-from collections import OrderedDict
-from CommonDataClass.DataClass import *
-from Workspace.BuildClassObject import PackageBuildClassObject, StructurePcd, PcdClassObject
-from Common.GlobalData import gGlobalDefines
-from re import compile
-
-## Platform build information from DEC file
-#
-# This class is used to retrieve information stored in database and convert them
-# into PackageBuildClassObject form for easier use for AutoGen.
-#
-class DecBuildData(PackageBuildClassObject):
-
- # dict used to convert part of [Defines] to members of DecBuildData directly
- _PROPERTY_ = {
- #
- # Required Fields
- #
- TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",
- TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",
- TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",
- TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",
- }
-
- ## Constructor of DecBuildData
- #
- # Initialize object of DecBuildData
- #
- # @param FilePath The path of package description file
- # @param RawData The raw data of DEC file
- # @param BuildDataBase Database used to retrieve module information
- # @param Arch The target architecture
- # @param Platform (not used for DecBuildData)
- # @param Macros Macros used for replacement in DSC file
- #
- def __init__(self, File, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
- self.MetaFile = File
- self._PackageDir = File.Dir
- self._RawData = RawData
- self._Bdb = BuildDataBase
- self._Arch = Arch
- self._Target = Target
- self._Toolchain = Toolchain
- self._Clear()
- self.UpdatePcdTypeDict()
-
- ## XXX[key] = value
- def __setitem__(self, key, value):
- self.__dict__[self._PROPERTY_[key]] = value
-
- ## value = XXX[key]
- def __getitem__(self, key):
- return self.__dict__[self._PROPERTY_[key]]
-
- ## "in" test support
- def __contains__(self, key):
- return key in self._PROPERTY_
-
- ## Set all internal used members of DecBuildData to None
- def _Clear(self):
- self._Header = None
- self._PackageName = None
- self._Guid = None
- self._Version = None
- self._PkgUniFile = None
- self._Protocols = None
- self._Ppis = None
- self._Guids = None
- self._Includes = None
- self._CommonIncludes = None
- self._LibraryClasses = None
- self._Pcds = None
- self._MacroDict = None
- self._PrivateProtocols = None
- self._PrivatePpis = None
- self._PrivateGuids = None
- self._PrivateIncludes = None
-
- ## Get current effective macros
- @property
- def _Macros(self):
- if self._MacroDict is None:
- self._MacroDict = dict(gGlobalDefines)
- return self._MacroDict
-
- ## Get architecture
- @property
- def Arch(self):
- return self._Arch
-
- ## Retrieve all information in [Defines] section
- #
- # (Retrieving all [Defines] information in one-shot is just to save time.)
- #
- def _GetHeaderInfo(self):
- RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
- for Record in RecordList:
- Name = Record[1]
- if Name in self:
- self[Name] = Record[2]
- self._Header = 'DUMMY'
-
- ## Retrieve package name
- @property
- def PackageName(self):
- if self._PackageName is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._PackageName is None:
- EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)
- return self._PackageName
-
- ## Retrieve file guid
- @property
- def PackageName(self):
- if self._Guid is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._Guid is None:
- EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)
- return self._Guid
-
- ## Retrieve package version
- @property
- def Version(self):
- if self._Version is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._Version is None:
- self._Version = ''
- return self._Version
-
- ## Retrieve protocol definitions (name/value pairs)
- @property
- def Protocols(self):
- if self._Protocols is None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # protocol definition for given ARCH
- #
- ProtocolDict = tdict(True)
- PrivateProtocolDict = tdict(True)
- NameList = []
- PrivateNameList = []
- PublicNameList = []
- # find out all protocol definitions for specific and 'common' arch
- RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]
- for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
- if PrivateFlag == 'PRIVATE':
- if Name not in PrivateNameList:
- PrivateNameList.append(Name)
- PrivateProtocolDict[Arch, Name] = Guid
- if Name in PublicNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- else:
- if Name not in PublicNameList:
- PublicNameList.append(Name)
- if Name in PrivateNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- if Name not in NameList:
- NameList.append(Name)
- ProtocolDict[Arch, Name] = Guid
- # use OrderedDict to keep the order
- self._Protocols = OrderedDict()
- self._PrivateProtocols = OrderedDict()
- for Name in NameList:
- #
- # limit the ARCH to self._Arch, if no self._Arch found, tdict
- # will automatically turn to 'common' ARCH for trying
- #
- self._Protocols[Name] = ProtocolDict[self._Arch, Name]
- for Name in PrivateNameList:
- self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]
- return self._Protocols
-
- ## Retrieve PPI definitions (name/value pairs)
- @property
- def Ppis(self):
- if self._Ppis is None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # PPI definition for given ARCH
- #
- PpiDict = tdict(True)
- PrivatePpiDict = tdict(True)
- NameList = []
- PrivateNameList = []
- PublicNameList = []
- # find out all PPI definitions for specific arch and 'common' arch
- RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]
- for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
- if PrivateFlag == 'PRIVATE':
- if Name not in PrivateNameList:
- PrivateNameList.append(Name)
- PrivatePpiDict[Arch, Name] = Guid
- if Name in PublicNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- else:
- if Name not in PublicNameList:
- PublicNameList.append(Name)
- if Name in PrivateNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- if Name not in NameList:
- NameList.append(Name)
- PpiDict[Arch, Name] = Guid
- # use OrderedDict to keep the order
- self._Ppis = OrderedDict()
- self._PrivatePpis = OrderedDict()
- for Name in NameList:
- #
- # limit the ARCH to self._Arch, if no self._Arch found, tdict
- # will automatically turn to 'common' ARCH for trying
- #
- self._Ppis[Name] = PpiDict[self._Arch, Name]
- for Name in PrivateNameList:
- self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]
- return self._Ppis
-
- ## Retrieve GUID definitions (name/value pairs)
- @property
- def Guids(self):
- if self._Guids is None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # GUID definition for given ARCH
- #
- GuidDict = tdict(True)
- PrivateGuidDict = tdict(True)
- NameList = []
- PrivateNameList = []
- PublicNameList = []
- # find out all protocol definitions for specific and 'common' arch
- RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]
- for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
- if PrivateFlag == 'PRIVATE':
- if Name not in PrivateNameList:
- PrivateNameList.append(Name)
- PrivateGuidDict[Arch, Name] = Guid
- if Name in PublicNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- else:
- if Name not in PublicNameList:
- PublicNameList.append(Name)
- if Name in PrivateNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- if Name not in NameList:
- NameList.append(Name)
- GuidDict[Arch, Name] = Guid
- # use OrderedDict to keep the order
- self._Guids = OrderedDict()
- self._PrivateGuids = OrderedDict()
- for Name in NameList:
- #
- # limit the ARCH to self._Arch, if no self._Arch found, tdict
- # will automatically turn to 'common' ARCH for trying
- #
- self._Guids[Name] = GuidDict[self._Arch, Name]
- for Name in PrivateNameList:
- self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]
- return self._Guids
-
- ## Retrieve public include paths declared in this package
- @property
- def Includes(self):
- if self._Includes is None or self._CommonIncludes is None:
- self._CommonIncludes = []
- self._Includes = []
- self._PrivateIncludes = []
- PublicInclues = []
- RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
- Macros = self._Macros
- for Record in RecordList:
- File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)
- LineNo = Record[-1]
- # validate the path
- ErrorCode, ErrorInfo = File.Validate()
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
-
- # avoid duplicate include path
- if File not in self._Includes:
- self._Includes.append(File)
- if Record[4] == 'PRIVATE':
- if File not in self._PrivateIncludes:
- self._PrivateIncludes.append(File)
- if File in PublicInclues:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
- else:
- if File not in PublicInclues:
- PublicInclues.append(File)
- if File in self._PrivateIncludes:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
- if Record[3] == TAB_COMMON:
- self._CommonIncludes.append(File)
- return self._Includes
-
- ## Retrieve library class declarations (not used in build at present)
- @property
- def LibraryClasses(self):
- if self._LibraryClasses is None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # library class declaration for given ARCH
- #
- LibraryClassDict = tdict(True)
- LibraryClassSet = set()
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
- Macros = self._Macros
- for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
- File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate()
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
- LibraryClassSet.add(LibraryClass)
- LibraryClassDict[Arch, LibraryClass] = File
- self._LibraryClasses = OrderedDict()
- for LibraryClass in LibraryClassSet:
- self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]
- return self._LibraryClasses
-
- ## Retrieve PCD declarations
- @property
- def Pcds(self):
- if self._Pcds is None:
- self._Pcds = OrderedDict()
- self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
- self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
- self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
- self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))
- self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
- return self._Pcds
-
- def ParsePcdName(self,TokenCName):
- TokenCName = TokenCName.strip()
- if TokenCName.startswith("["):
- if "." in TokenCName:
- Demesionattr = TokenCName[:TokenCName.index(".")]
- Fields = TokenCName[TokenCName.index(".")+1:]
- else:
- Demesionattr = TokenCName
- Fields = ""
- else:
- Demesionattr = ""
- Fields = TokenCName
-
- return Demesionattr,Fields
-
- def ProcessStructurePcd(self, StructurePcdRawDataSet):
- s_pcd_set = OrderedDict()
- for s_pcd, LineNo in StructurePcdRawDataSet:
- if s_pcd.TokenSpaceGuidCName not in s_pcd_set:
- s_pcd_set[s_pcd.TokenSpaceGuidCName] = []
- s_pcd_set[s_pcd.TokenSpaceGuidCName].append((s_pcd, LineNo))
-
- str_pcd_set = []
- for pcdname in s_pcd_set:
- dep_pkgs = []
- struct_pcd = StructurePcd()
- for item, LineNo in s_pcd_set[pcdname]:
- if not item.TokenCName:
- continue
- if "<HeaderFiles>" in item.TokenCName:
- struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue)
- elif "<Packages>" in item.TokenCName:
- dep_pkgs.append(item.DefaultValue)
- elif item.DatumType == item.TokenCName:
- struct_pcd.copy(item)
- struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip()
- struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".")
- struct_pcd.PcdDefineLineNo = LineNo
- struct_pcd.PkgPath = self.MetaFile.File
- struct_pcd.SetDecDefaultValue(item.DefaultValue,self.MetaFile.File,LineNo)
- else:
- DemesionAttr, Fields = self.ParsePcdName(item.TokenCName)
- struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr)
-
- struct_pcd.PackageDecs = dep_pkgs
- str_pcd_set.append(struct_pcd)
- return str_pcd_set
-
- ## Retrieve PCD declarations for given type
- def _GetPcd(self, Type):
- Pcds = OrderedDict()
- #
- # tdict is a special kind of dict, used for selecting correct
- # PCD declaration for given ARCH
- #
- PcdDict = tdict(True, 3)
- # for summarizing PCD
- PcdSet = []
- # find out all PCDs of the 'type'
-
- StrPcdSet = []
- RecordList = self._RawData[Type, self._Arch]
- for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:
- PcdDict[Arch, PcdCName, TokenSpaceGuid] = (Setting, Dummy2)
- if not (PcdCName, TokenSpaceGuid) in PcdSet:
- PcdSet.append((PcdCName, TokenSpaceGuid))
-
- DefinitionPosition = {}
- for PcdCName, TokenSpaceGuid in PcdSet:
- #
- # limit the ARCH to self._Arch, if no self._Arch found, tdict
- # will automatically turn to 'common' ARCH and try again
- #
- Setting, LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
- if Setting is None:
- continue
-
- DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
- validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
- PcdObj = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- DefaultValue,
- TokenNumber,
- '',
- {},
- False,
- None,
- list(validateranges),
- list(validlists),
- list(expressions)
- )
- DefinitionPosition[PcdObj] = (self.MetaFile.File, LineNo)
- if "." in TokenSpaceGuid:
- StrPcdSet.append((PcdObj, LineNo))
- else:
- Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdObj
-
- StructurePcds = self.ProcessStructurePcd(StrPcdSet)
- for pcd in StructurePcds:
- Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd
- StructPattern = compile(r'[_a-zA-Z][0-9A-Za-z_]*$')
- for pcd in Pcds.values():
- if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
- if not pcd.IsAggregateDatumType():
- EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", DefinitionPosition[pcd][0], DefinitionPosition[pcd][1])
- elif not pcd.IsArray() and not pcd.StructuredPcdIncludeFile:
- EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (pcd.TokenSpaceGuidCName, pcd.TokenCName, pcd.DefinitionPosition[0], pcd.DefinitionPosition[1] ))
- return Pcds
-
- @property
- def CommonIncludes(self):
- if self._CommonIncludes is None:
- self.Includes
- return self._CommonIncludes
+## @file +# This file is used to create a database used by build tool +# +# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> +# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +from Common.StringUtils import * +from Common.DataType import * +from Common.Misc import * +from types import * +from collections import OrderedDict +from CommonDataClass.DataClass import * +from Workspace.BuildClassObject import PackageBuildClassObject, StructurePcd, PcdClassObject +from Common.GlobalData import gGlobalDefines +from re import compile + +## Platform build information from DEC file +# +# This class is used to retrieve information stored in database and convert them +# into PackageBuildClassObject form for easier use for AutoGen. +# +class DecBuildData(PackageBuildClassObject): + + # dict used to convert part of [Defines] to members of DecBuildData directly + _PROPERTY_ = { + # + # Required Fields + # + TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName", + TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid", + TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version", + TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile", + } + + ## Constructor of DecBuildData + # + # Initialize object of DecBuildData + # + # @param FilePath The path of package description file + # @param RawData The raw data of DEC file + # @param BuildDataBase Database used to retrieve module information + # @param Arch The target architecture + # @param Platform (not used for DecBuildData) + # @param Macros Macros used for replacement in DSC file + # + def __init__(self, File, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None): + self.MetaFile = File + self._PackageDir = File.Dir + self._RawData = RawData + self._Bdb = BuildDataBase + self._Arch = Arch + self._Target = Target + self._Toolchain = Toolchain + self._Clear() + self.UpdatePcdTypeDict() + + ## XXX[key] = value + def __setitem__(self, key, value): + self.__dict__[self._PROPERTY_[key]] = value + + ## value = XXX[key] + def __getitem__(self, key): + return self.__dict__[self._PROPERTY_[key]] + + ## "in" test support + def __contains__(self, key): + return key in self._PROPERTY_ + + ## Set all internal used members of DecBuildData to None + def _Clear(self): + self._Header = None + self._PackageName = None + self._Guid = None + self._Version = None + self._PkgUniFile = None + self._Protocols = None + self._Ppis = None + self._Guids = None + self._Includes = None + self._CommonIncludes = None + self._LibraryClasses = None + self._Pcds = None + self._MacroDict = None + self._PrivateProtocols = None + self._PrivatePpis = None + self._PrivateGuids = None + self._PrivateIncludes = None + + ## Get current effective macros + @property + def _Macros(self): + if self._MacroDict is None: + self._MacroDict = dict(gGlobalDefines) + return self._MacroDict + + ## Get architecture + @property + def Arch(self): + return self._Arch + + ## Retrieve all information in [Defines] section + # + # (Retrieving all [Defines] information in one-shot is just to save time.) + # + def _GetHeaderInfo(self): + RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch] + for Record in RecordList: + Name = Record[1] + if Name in self: + self[Name] = Record[2] + self._Header = 'DUMMY' + + ## Retrieve package name + @property + def PackageName(self): + if self._PackageName is None: + if self._Header is None: + self._GetHeaderInfo() + if self._PackageName is None: + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile) + return self._PackageName + + ## Retrieve file guid + @property + def PackageName(self): + if self._Guid is None: + if self._Header is None: + self._GetHeaderInfo() + if self._Guid is None: + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile) + return self._Guid + + ## Retrieve package version + @property + def Version(self): + if self._Version is None: + if self._Header is None: + self._GetHeaderInfo() + if self._Version is None: + self._Version = '' + return self._Version + + ## Retrieve protocol definitions (name/value pairs) + @property + def Protocols(self): + if self._Protocols is None: + # + # tdict is a special kind of dict, used for selecting correct + # protocol definition for given ARCH + # + ProtocolDict = tdict(True) + PrivateProtocolDict = tdict(True) + NameList = [] + PrivateNameList = [] + PublicNameList = [] + # find out all protocol definitions for specific and 'common' arch + RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch] + for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList: + if PrivateFlag == 'PRIVATE': + if Name not in PrivateNameList: + PrivateNameList.append(Name) + PrivateProtocolDict[Arch, Name] = Guid + if Name in PublicNameList: + EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo) + else: + if Name not in PublicNameList: + PublicNameList.append(Name) + if Name in PrivateNameList: + EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo) + if Name not in NameList: + NameList.append(Name) + ProtocolDict[Arch, Name] = Guid + # use OrderedDict to keep the order + self._Protocols = OrderedDict() + self._PrivateProtocols = OrderedDict() + for Name in NameList: + # + # limit the ARCH to self._Arch, if no self._Arch found, tdict + # will automatically turn to 'common' ARCH for trying + # + self._Protocols[Name] = ProtocolDict[self._Arch, Name] + for Name in PrivateNameList: + self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name] + return self._Protocols + + ## Retrieve PPI definitions (name/value pairs) + @property + def Ppis(self): + if self._Ppis is None: + # + # tdict is a special kind of dict, used for selecting correct + # PPI definition for given ARCH + # + PpiDict = tdict(True) + PrivatePpiDict = tdict(True) + NameList = [] + PrivateNameList = [] + PublicNameList = [] + # find out all PPI definitions for specific arch and 'common' arch + RecordList = self._RawData[MODEL_EFI_PPI, self._Arch] + for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList: + if PrivateFlag == 'PRIVATE': + if Name not in PrivateNameList: + PrivateNameList.append(Name) + PrivatePpiDict[Arch, Name] = Guid + if Name in PublicNameList: + EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo) + else: + if Name not in PublicNameList: + PublicNameList.append(Name) + if Name in PrivateNameList: + EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo) + if Name not in NameList: + NameList.append(Name) + PpiDict[Arch, Name] = Guid + # use OrderedDict to keep the order + self._Ppis = OrderedDict() + self._PrivatePpis = OrderedDict() + for Name in NameList: + # + # limit the ARCH to self._Arch, if no self._Arch found, tdict + # will automatically turn to 'common' ARCH for trying + # + self._Ppis[Name] = PpiDict[self._Arch, Name] + for Name in PrivateNameList: + self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name] + return self._Ppis + + ## Retrieve GUID definitions (name/value pairs) + @property + def Guids(self): + if self._Guids is None: + # + # tdict is a special kind of dict, used for selecting correct + # GUID definition for given ARCH + # + GuidDict = tdict(True) + PrivateGuidDict = tdict(True) + NameList = [] + PrivateNameList = [] + PublicNameList = [] + # find out all protocol definitions for specific and 'common' arch + RecordList = self._RawData[MODEL_EFI_GUID, self._Arch] + for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList: + if PrivateFlag == 'PRIVATE': + if Name not in PrivateNameList: + PrivateNameList.append(Name) + PrivateGuidDict[Arch, Name] = Guid + if Name in PublicNameList: + EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo) + else: + if Name not in PublicNameList: + PublicNameList.append(Name) + if Name in PrivateNameList: + EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo) + if Name not in NameList: + NameList.append(Name) + GuidDict[Arch, Name] = Guid + # use OrderedDict to keep the order + self._Guids = OrderedDict() + self._PrivateGuids = OrderedDict() + for Name in NameList: + # + # limit the ARCH to self._Arch, if no self._Arch found, tdict + # will automatically turn to 'common' ARCH for trying + # + self._Guids[Name] = GuidDict[self._Arch, Name] + for Name in PrivateNameList: + self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name] + return self._Guids + + ## Retrieve public include paths declared in this package + @property + def Includes(self): + if self._Includes is None or self._CommonIncludes is None: + self._CommonIncludes = [] + self._Includes = [] + self._PrivateIncludes = [] + PublicInclues = [] + RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch] + Macros = self._Macros + for Record in RecordList: + File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch) + LineNo = Record[-1] + # validate the path + ErrorCode, ErrorInfo = File.Validate() + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) + + # avoid duplicate include path + if File not in self._Includes: + self._Includes.append(File) + if Record[4] == 'PRIVATE': + if File not in self._PrivateIncludes: + self._PrivateIncludes.append(File) + if File in PublicInclues: + EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo) + else: + if File not in PublicInclues: + PublicInclues.append(File) + if File in self._PrivateIncludes: + EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo) + if Record[3] == TAB_COMMON: + self._CommonIncludes.append(File) + return self._Includes + + ## Retrieve library class declarations (not used in build at present) + @property + def LibraryClasses(self): + if self._LibraryClasses is None: + # + # tdict is a special kind of dict, used for selecting correct + # library class declaration for given ARCH + # + LibraryClassDict = tdict(True) + LibraryClassSet = set() + RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch] + Macros = self._Macros + for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList: + File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch) + # check the file validation + ErrorCode, ErrorInfo = File.Validate() + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) + LibraryClassSet.add(LibraryClass) + LibraryClassDict[Arch, LibraryClass] = File + self._LibraryClasses = OrderedDict() + for LibraryClass in LibraryClassSet: + self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass] + return self._LibraryClasses + + ## Retrieve PCD declarations + @property + def Pcds(self): + if self._Pcds is None: + self._Pcds = OrderedDict() + self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD)) + self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE)) + self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG)) + self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC)) + self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX)) + return self._Pcds + + def ParsePcdName(self,TokenCName): + TokenCName = TokenCName.strip() + if TokenCName.startswith("["): + if "." in TokenCName: + Demesionattr = TokenCName[:TokenCName.index(".")] + Fields = TokenCName[TokenCName.index(".")+1:] + else: + Demesionattr = TokenCName + Fields = "" + else: + Demesionattr = "" + Fields = TokenCName + + return Demesionattr,Fields + + def ProcessStructurePcd(self, StructurePcdRawDataSet): + s_pcd_set = OrderedDict() + for s_pcd, LineNo in StructurePcdRawDataSet: + if s_pcd.TokenSpaceGuidCName not in s_pcd_set: + s_pcd_set[s_pcd.TokenSpaceGuidCName] = [] + s_pcd_set[s_pcd.TokenSpaceGuidCName].append((s_pcd, LineNo)) + + str_pcd_set = [] + for pcdname in s_pcd_set: + dep_pkgs = [] + struct_pcd = StructurePcd() + for item, LineNo in s_pcd_set[pcdname]: + if not item.TokenCName: + continue + if "<HeaderFiles>" in item.TokenCName: + struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue) + elif "<Packages>" in item.TokenCName: + dep_pkgs.append(item.DefaultValue) + elif item.DatumType == item.TokenCName: + struct_pcd.copy(item) + struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip() + struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".") + struct_pcd.PcdDefineLineNo = LineNo + struct_pcd.PkgPath = self.MetaFile.File + struct_pcd.SetDecDefaultValue(item.DefaultValue,self.MetaFile.File,LineNo) + else: + DemesionAttr, Fields = self.ParsePcdName(item.TokenCName) + struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr) + + struct_pcd.PackageDecs = dep_pkgs + str_pcd_set.append(struct_pcd) + return str_pcd_set + + ## Retrieve PCD declarations for given type + def _GetPcd(self, Type): + Pcds = OrderedDict() + # + # tdict is a special kind of dict, used for selecting correct + # PCD declaration for given ARCH + # + PcdDict = tdict(True, 3) + # for summarizing PCD + PcdSet = [] + # find out all PCDs of the 'type' + + StrPcdSet = [] + RecordList = self._RawData[Type, self._Arch] + for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList: + PcdDict[Arch, PcdCName, TokenSpaceGuid] = (Setting, Dummy2) + if not (PcdCName, TokenSpaceGuid) in PcdSet: + PcdSet.append((PcdCName, TokenSpaceGuid)) + + DefinitionPosition = {} + for PcdCName, TokenSpaceGuid in PcdSet: + # + # limit the ARCH to self._Arch, if no self._Arch found, tdict + # will automatically turn to 'common' ARCH and try again + # + Setting, LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid] + if Setting is None: + continue + + DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting) + validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName) + PcdObj = PcdClassObject( + PcdCName, + TokenSpaceGuid, + self._PCD_TYPE_STRING_[Type], + DatumType, + DefaultValue, + TokenNumber, + '', + {}, + False, + None, + list(validateranges), + list(validlists), + list(expressions) + ) + DefinitionPosition[PcdObj] = (self.MetaFile.File, LineNo) + if "." in TokenSpaceGuid: + StrPcdSet.append((PcdObj, LineNo)) + else: + Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdObj + + StructurePcds = self.ProcessStructurePcd(StrPcdSet) + for pcd in StructurePcds: + Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd + StructPattern = compile(r'[_a-zA-Z][0-9A-Za-z_]*$') + for pcd in Pcds.values(): + if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]: + if not pcd.IsAggregateDatumType(): + EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", DefinitionPosition[pcd][0], DefinitionPosition[pcd][1]) + elif not pcd.IsArray() and not pcd.StructuredPcdIncludeFile: + EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (pcd.TokenSpaceGuidCName, pcd.TokenCName, pcd.DefinitionPosition[0], pcd.DefinitionPosition[1] )) + return Pcds + + @property + def CommonIncludes(self): + if self._CommonIncludes is None: + self.Includes + return self._CommonIncludes |
