summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/Workspace
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /BaseTools/Source/Python/Workspace
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'BaseTools/Source/Python/Workspace')
-rw-r--r--BaseTools/Source/Python/Workspace/BuildClassObject.py1246
-rw-r--r--BaseTools/Source/Python/Workspace/DecBuildData.py922
-rw-r--r--BaseTools/Source/Python/Workspace/DscBuildData.py7344
-rw-r--r--BaseTools/Source/Python/Workspace/InfBuildData.py2200
-rw-r--r--BaseTools/Source/Python/Workspace/MetaDataTable.py612
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileCommentParser.py90
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileParser.py4394
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileTable.py860
-rw-r--r--BaseTools/Source/Python/Workspace/WorkspaceCommon.py520
-rw-r--r--BaseTools/Source/Python/Workspace/WorkspaceDatabase.py408
-rw-r--r--BaseTools/Source/Python/Workspace/__init__.py18
11 files changed, 9307 insertions, 9307 deletions
diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py
index ef873720f4..7e8e36526e 100644
--- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
+++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
@@ -1,623 +1,623 @@
-## @file
-# This file is used to define each component of the build database
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from collections import OrderedDict, namedtuple
-from Common.DataType import *
-import collections
-import re
-from collections import OrderedDict
-from Common.Misc import CopyDict,ArrayIndex
-import copy
-from CommonDataClass.DataClass import *
-import Common.EdkLogger as EdkLogger
-import Common.GlobalData as GlobalData
-from Common.BuildToolError import OPTION_VALUE_INVALID
-from Common.caching import cached_property
-StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_\[\]]*$')
-
-## PcdClassObject
-#
-# This Class is used for PcdObject
-#
-# @param object: Inherited from object class
-# @param Name: Input value for Name of Pcd, default is None
-# @param Guid: Input value for Guid of Pcd, default is None
-# @param Type: Input value for Type of Pcd, default is None
-# @param DatumType: Input value for DatumType of Pcd, default is None
-# @param Value: Input value for Value of Pcd, default is None
-# @param Token: Input value for Token of Pcd, default is None
-# @param MaxDatumSize: Input value for MaxDatumSize of Pcd, default is None
-# @param SkuInfoList: Input value for SkuInfoList of Pcd, default is {}
-# @param IsOverrided: Input value for IsOverrided of Pcd, default is False
-# @param GuidValue: Input value for TokenSpaceGuidValue of Pcd, default is None
-#
-# @var TokenCName: To store value for TokenCName
-# @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName
-# @var Type: To store value for Type
-# @var DatumType: To store value for DatumType
-# @var TokenValue: To store value for TokenValue
-# @var MaxDatumSize: To store value for MaxDatumSize
-# @var SkuInfoList: To store value for SkuInfoList
-# @var IsOverrided: To store value for IsOverrided
-# @var Phase: To store value for Phase, default is "DXE"
-#
-class PcdClassObject(object):
- def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = None, IsOverrided = False, GuidValue = None, validateranges = None, validlists = None, expressions = None, IsDsc = False, UserDefinedDefaultStoresFlag = False):
- self.TokenCName = Name
- self.TokenSpaceGuidCName = Guid
- self.TokenSpaceGuidValue = GuidValue
- self.Type = Type
- self._DatumType = DatumType
- self.DefaultValue = Value
- self.TokenValue = Token
- self.MaxDatumSize = MaxDatumSize
- self.MaxSizeUserSet = None
- self.SkuInfoList = SkuInfoList if SkuInfoList is not None else OrderedDict()
- self.Phase = "DXE"
- self.Pending = False
- self.IsOverrided = IsOverrided
- self.IsFromBinaryInf = False
- self.IsFromDsc = False
- self.validateranges = validateranges if validateranges is not None else []
- self.validlists = validlists if validlists is not None else []
- self.expressions = expressions if expressions is not None else []
- self.DscDefaultValue = None
- self.DscRawValue = {}
- self.DscRawValueInfo = {}
- if IsDsc:
- self.DscDefaultValue = Value
- self.PcdValueFromComm = ""
- self.PcdValueFromFdf = ""
- self.PcdValueFromComponents = {} #{ModuleGuid:value, file_path,lineNo}
- self.CustomAttribute = {}
- self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
- self._Capacity = None
-
- @property
- def Capacity(self):
- if self._Capacity is None:
- self._Capacity = []
- dimension = ArrayIndex.findall(self._DatumType)
- for item in dimension:
- maxsize = item.lstrip("[").rstrip("]").strip()
- if not maxsize:
- maxsize = "-1"
- maxsize = str(int(maxsize,16)) if maxsize.startswith(("0x","0X")) else maxsize
- self._Capacity.append(maxsize)
- if hasattr(self, "SkuOverrideValues"):
- for sku in self.SkuOverrideValues:
- for defaultstore in self.SkuOverrideValues[sku]:
- fields = self.SkuOverrideValues[sku][defaultstore]
- for demesionattr in fields:
- fieldinfo = fields[demesionattr]
- deme = ArrayIndex.findall(demesionattr)
- for i in range(len(deme)):
- if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]):
- if self._Capacity[i] != "-1":
- firstfieldinfo = list(fieldinfo.values())[0]
- EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size. From %s Line %s \n " %
- (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] ))
- if hasattr(self,"DefaultValues"):
- for demesionattr in self.DefaultValues:
- fieldinfo = self.DefaultValues[demesionattr]
- deme = ArrayIndex.findall(demesionattr)
- for i in range(len(deme)):
- if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]):
- if self._Capacity[i] != "-1":
- firstfieldinfo = list(fieldinfo.values())[0]
- EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size. From %s Line %s \n " %
- (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] ))
- return self._Capacity
-
- def PcdArraySize(self):
- if self.Capacity[-1] == "-1":
- return -1
- size = 1
- for de in self.Capacity:
- size = size * int(de)
- return size
- @property
- def DatumType(self):
- return self._DatumType
-
- @DatumType.setter
- def DatumType(self,DataType):
- self._DatumType = DataType
- self._Capacity = None
-
- @property
- def BaseDatumType(self):
- if self.IsArray():
- return self._DatumType[:self._DatumType.index("[")]
- else:
- return self._DatumType
- def IsArray(self):
- return True if len(self.Capacity) else False
-
- def IsAggregateDatumType(self):
- if self.DatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
- return False
- if self.IsArray() or StructPattern.match(self.DatumType):
- return True
- return False
-
- def IsSimpleTypeArray(self):
- if self.IsArray() and self.BaseDatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, "BOOLEAN"]:
- return True
- return False
-
- @staticmethod
- def GetPcdMaxSizeWorker(PcdString, MaxSize):
- if PcdString.startswith("{") and PcdString.endswith("}"):
- return max([len(PcdString.split(",")),MaxSize])
-
- if PcdString.startswith("\"") or PcdString.startswith("\'"):
- return max([len(PcdString)-2+1,MaxSize])
-
- if PcdString.startswith("L\""):
- return max([2*(len(PcdString)-3+1),MaxSize])
-
- return max([len(PcdString),MaxSize])
-
- ## Get the maximum number of bytes
- def GetPcdMaxSize(self):
- if self.DatumType in TAB_PCD_NUMERIC_TYPES:
- return MAX_SIZE_TYPE[self.DatumType]
-
- MaxSize = int(self.MaxDatumSize, 10) if self.MaxDatumSize else 0
- if self.PcdValueFromFdf:
- MaxSize = self.GetPcdMaxSizeWorker(self.PcdValueFromFdf,MaxSize)
- if self.PcdValueFromComm:
- MaxSize = self.GetPcdMaxSizeWorker(self.PcdValueFromComm,MaxSize)
- if hasattr(self, "DefaultValueFromDec"):
- MaxSize = self.GetPcdMaxSizeWorker(self.DefaultValueFromDec,MaxSize)
- return MaxSize
-
- ## Get the number of bytes
- def GetPcdSize(self):
- if self.DatumType in TAB_PCD_NUMERIC_TYPES:
- return MAX_SIZE_TYPE[self.DatumType]
- if not self.DefaultValue:
- return 1
- elif self.DefaultValue[0] == 'L':
- return (len(self.DefaultValue) - 2) * 2
- elif self.DefaultValue[0] == '{':
- return len(self.DefaultValue.split(','))
- else:
- return len(self.DefaultValue) - 1
-
-
- ## Convert the class to a string
- #
- # Convert each member of the class to string
- # Organize to a single line format string
- #
- # @retval Rtn Formatted String
- #
- def __str__(self):
- Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \
- 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \
- 'Type=' + str(self.Type) + ', ' + \
- 'DatumType=' + str(self.DatumType) + ', ' + \
- 'DefaultValue=' + str(self.DefaultValue) + ', ' + \
- 'TokenValue=' + str(self.TokenValue) + ', ' + \
- 'MaxDatumSize=' + str(self.MaxDatumSize) + ', '
- for Item in self.SkuInfoList.values():
- Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName
- Rtn = Rtn + ', IsOverrided=' + str(self.IsOverrided)
-
- return Rtn
-
- ## Override __eq__ function
- #
- # Check whether pcds are the same
- #
- # @retval False The two pcds are different
- # @retval True The two pcds are the same
- #
- def __eq__(self, Other):
- return Other and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName
-
- ## Override __hash__ function
- #
- # Use (TokenCName, TokenSpaceGuidCName) as key in hash table
- #
- # @retval truple() Key for hash table
- #
- def __hash__(self):
- return hash((self.TokenCName, self.TokenSpaceGuidCName))
-
- @cached_property
- def _fullname(self):
- return ".".join((self.TokenSpaceGuidCName,self.TokenCName))
-
- def __lt__(self,pcd):
- return self._fullname < pcd._fullname
- def __gt__(self,pcd):
- return self._fullname > pcd._fullname
-
- def sharedcopy(self,new_pcd):
- new_pcd.TokenCName = self.TokenCName
- new_pcd.TokenSpaceGuidCName = self.TokenSpaceGuidCName
- new_pcd.TokenSpaceGuidValue = self.TokenSpaceGuidValue
- new_pcd.Type = self.Type
- new_pcd.DatumType = self.DatumType
- new_pcd.DefaultValue = self.DefaultValue
- new_pcd.TokenValue = self.TokenValue
- new_pcd.MaxDatumSize = self.MaxDatumSize
- new_pcd.MaxSizeUserSet = self.MaxSizeUserSet
-
- new_pcd.Phase = self.Phase
- new_pcd.Pending = self.Pending
- new_pcd.IsOverrided = self.IsOverrided
- new_pcd.IsFromBinaryInf = self.IsFromBinaryInf
- new_pcd.IsFromDsc = self.IsFromDsc
- new_pcd.PcdValueFromComm = self.PcdValueFromComm
- new_pcd.PcdValueFromFdf = self.PcdValueFromFdf
- new_pcd.UserDefinedDefaultStoresFlag = self.UserDefinedDefaultStoresFlag
- new_pcd.DscRawValue = self.DscRawValue
- new_pcd.DscRawValueInfo = self.DscRawValueInfo
- new_pcd.CustomAttribute = self.CustomAttribute
- new_pcd.validateranges = [item for item in self.validateranges]
- new_pcd.validlists = [item for item in self.validlists]
- new_pcd.expressions = [item for item in self.expressions]
- new_pcd.SkuInfoList = {key: copy.deepcopy(skuobj) for key,skuobj in self.SkuInfoList.items()}
- return new_pcd
-
- def __deepcopy__(self,memo):
- new_pcd = PcdClassObject()
- self.sharedcopy(new_pcd)
- return new_pcd
-
-class StructurePcd(PcdClassObject):
- def __init__(self, StructuredPcdIncludeFile=None, Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList=None, IsOverrided=False, GuidValue=None, validateranges=None, validlists=None, expressions=None,default_store = TAB_DEFAULT_STORES_DEFAULT):
- if SkuInfoList is None:
- SkuInfoList = {}
- if validateranges is None:
- validateranges = []
- if validlists is None:
- validlists = []
- if expressions is None:
- expressions = []
- if Packages is None:
- Packages = []
- super(StructurePcd, self).__init__(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided, GuidValue, validateranges, validlists, expressions)
- self.StructuredPcdIncludeFile = [] if StructuredPcdIncludeFile is None else StructuredPcdIncludeFile
- self.PackageDecs = Packages
- self.DefaultStoreName = [default_store]
- self.DefaultValues = OrderedDict()
- self.PcdMode = None
- self.SkuOverrideValues = OrderedDict()
- self.StructName = None
- self.PcdDefineLineNo = 0
- self.PkgPath = ""
- self.DefaultValueFromDec = ""
- self.DefaultValueFromDecInfo = None
- self.ValueChain = set()
- self.PcdFieldValueFromComm = OrderedDict()
- self.PcdFieldValueFromFdf = OrderedDict()
- self.DefaultFromDSC=None
- self.PcdFiledValueFromDscComponent = OrderedDict()
- def __repr__(self):
- return self.TypeName
-
- def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0,DimensionAttr ="-1"):
- if DimensionAttr not in self.DefaultValues:
- self.DefaultValues[DimensionAttr] = collections.OrderedDict()
- if FieldName in self.DefaultValues[DimensionAttr]:
- del self.DefaultValues[DimensionAttr][FieldName]
- self.DefaultValues[DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
- return self.DefaultValues[DimensionAttr][FieldName]
-
- def SetDecDefaultValue(self, DefaultValue,decpath=None,lineno=None):
- self.DefaultValueFromDec = DefaultValue
- self.DefaultValueFromDecInfo = (decpath,lineno)
- def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0, DimensionAttr = '-1'):
- if SkuName not in self.SkuOverrideValues:
- self.SkuOverrideValues[SkuName] = OrderedDict()
- if DefaultStoreName not in self.SkuOverrideValues[SkuName]:
- self.SkuOverrideValues[SkuName][DefaultStoreName] = OrderedDict()
- if DimensionAttr not in self.SkuOverrideValues[SkuName][DefaultStoreName]:
- self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr] = collections.OrderedDict()
- if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]:
- del self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName]
- self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
- return self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName]
-
- def AddComponentOverrideValue(self,FieldName, Value, ModuleGuid, FileName="", LineNo=0, DimensionAttr = '-1'):
- self.PcdFiledValueFromDscComponent.setdefault(ModuleGuid, OrderedDict())
- self.PcdFiledValueFromDscComponent[ModuleGuid].setdefault(DimensionAttr,OrderedDict())
- self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
- return self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldName]
-
- def SetPcdMode (self, PcdMode):
- self.PcdMode = PcdMode
-
- def copy(self, PcdObject):
- self.TokenCName = PcdObject.TokenCName if PcdObject.TokenCName else self.TokenCName
- self.TokenSpaceGuidCName = PcdObject.TokenSpaceGuidCName if PcdObject.TokenSpaceGuidCName else PcdObject.TokenSpaceGuidCName
- self.TokenSpaceGuidValue = PcdObject.TokenSpaceGuidValue if PcdObject.TokenSpaceGuidValue else self.TokenSpaceGuidValue
- self.Type = PcdObject.Type if PcdObject.Type else self.Type
- self._DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType
- self.DefaultValue = PcdObject.DefaultValue if PcdObject.DefaultValue else self.DefaultValue
- self.TokenValue = PcdObject.TokenValue if PcdObject.TokenValue else self.TokenValue
- self.MaxDatumSize = PcdObject.MaxDatumSize if PcdObject.MaxDatumSize else self.MaxDatumSize
- self.SkuInfoList = PcdObject.SkuInfoList if PcdObject.SkuInfoList else self.SkuInfoList
- self.Phase = PcdObject.Phase if PcdObject.Phase else self.Phase
- self.Pending = PcdObject.Pending if PcdObject.Pending else self.Pending
- self.IsOverrided = PcdObject.IsOverrided if PcdObject.IsOverrided else self.IsOverrided
- self.IsFromBinaryInf = PcdObject.IsFromBinaryInf if PcdObject.IsFromBinaryInf else self.IsFromBinaryInf
- self.IsFromDsc = PcdObject.IsFromDsc if PcdObject.IsFromDsc else self.IsFromDsc
- self.validateranges = PcdObject.validateranges if PcdObject.validateranges else self.validateranges
- self.validlists = PcdObject.validlists if PcdObject.validlists else self.validlists
- self.expressions = PcdObject.expressions if PcdObject.expressions else self.expressions
- self.DscRawValue = PcdObject.DscRawValue if PcdObject.DscRawValue else self.DscRawValue
- self.DscRawValueInfo = PcdObject.DscRawValueInfo if PcdObject.DscRawValueInfo else self.DscRawValueInfo
- self.PcdValueFromComm = PcdObject.PcdValueFromComm if PcdObject.PcdValueFromComm else self.PcdValueFromComm
- self.PcdValueFromFdf = PcdObject.PcdValueFromFdf if PcdObject.PcdValueFromFdf else self.PcdValueFromFdf
- self.CustomAttribute = PcdObject.CustomAttribute if PcdObject.CustomAttribute else self.CustomAttribute
- self.UserDefinedDefaultStoresFlag = PcdObject.UserDefinedDefaultStoresFlag if PcdObject.UserDefinedDefaultStoresFlag else self.UserDefinedDefaultStoresFlag
- if isinstance(PcdObject, StructurePcd):
- self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else self.StructuredPcdIncludeFile
- self.PackageDecs = PcdObject.PackageDecs if PcdObject.PackageDecs else self.PackageDecs
- self.DefaultValues = PcdObject.DefaultValues if PcdObject.DefaultValues else self.DefaultValues
- self.PcdMode = PcdObject.PcdMode if PcdObject.PcdMode else self.PcdMode
- self.DefaultValueFromDec = PcdObject.DefaultValueFromDec if PcdObject.DefaultValueFromDec else self.DefaultValueFromDec
- self.DefaultValueFromDecInfo = PcdObject.DefaultValueFromDecInfo if PcdObject.DefaultValueFromDecInfo else self.DefaultValueFromDecInfo
- self.SkuOverrideValues = PcdObject.SkuOverrideValues if PcdObject.SkuOverrideValues else self.SkuOverrideValues
- self.StructName = PcdObject.DatumType if PcdObject.DatumType else self.StructName
- self.PcdDefineLineNo = PcdObject.PcdDefineLineNo if PcdObject.PcdDefineLineNo else self.PcdDefineLineNo
- self.PkgPath = PcdObject.PkgPath if PcdObject.PkgPath else self.PkgPath
- self.ValueChain = PcdObject.ValueChain if PcdObject.ValueChain else self.ValueChain
- self.PcdFieldValueFromComm = PcdObject.PcdFieldValueFromComm if PcdObject.PcdFieldValueFromComm else self.PcdFieldValueFromComm
- self.PcdFieldValueFromFdf = PcdObject.PcdFieldValueFromFdf if PcdObject.PcdFieldValueFromFdf else self.PcdFieldValueFromFdf
- self.PcdFiledValueFromDscComponent = PcdObject.PcdFiledValueFromDscComponent if PcdObject.PcdFiledValueFromDscComponent else self.PcdFiledValueFromDscComponent
-
- def __deepcopy__(self,memo):
- new_pcd = StructurePcd()
- self.sharedcopy(new_pcd)
-
- new_pcd.DefaultValueFromDec = self.DefaultValueFromDec
- new_pcd.DefaultValueFromDecInfo = self.DefaultValueFromDecInfo
- new_pcd.PcdMode = self.PcdMode
- new_pcd.StructName = self.DatumType
- new_pcd.PcdDefineLineNo = self.PcdDefineLineNo
- new_pcd.PkgPath = self.PkgPath
- new_pcd.StructuredPcdIncludeFile = [item for item in self.StructuredPcdIncludeFile]
- new_pcd.PackageDecs = [item for item in self.PackageDecs]
- new_pcd.DefaultValues = CopyDict(self.DefaultValues)
- new_pcd.DefaultFromDSC=CopyDict(self.DefaultFromDSC)
- new_pcd.SkuOverrideValues = CopyDict(self.SkuOverrideValues)
- new_pcd.PcdFieldValueFromComm = CopyDict(self.PcdFieldValueFromComm)
- new_pcd.PcdFieldValueFromFdf = CopyDict(self.PcdFieldValueFromFdf)
- new_pcd.PcdFiledValueFromDscComponent = CopyDict(self.PcdFiledValueFromDscComponent)
- new_pcd.ValueChain = {item for item in self.ValueChain}
- return new_pcd
-
-LibraryClassObject = namedtuple('LibraryClassObject', ['LibraryClass','SupModList'])
-
-class BuildData(object):
- # dict used to convert PCD type in database to string used by build tool
-
- _PCD_TYPE_STRING_ = {
- MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,
- MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,
- MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,
- MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC,
- MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC,
- MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII,
- MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD,
- MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,
- MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,
- MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,
- MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
- }
-
- def UpdatePcdTypeDict(self):
- if GlobalData.gCommandLineDefines.get(TAB_DSC_DEFINES_PCD_DYNAMIC_AS_DYNAMICEX,"FALSE").upper() == "TRUE":
- self._PCD_TYPE_STRING_ = {
- MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,
- MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,
- MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,
- MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC_EX,
- MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC_EX,
- MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_EX_HII,
- MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
- MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,
- MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,
- MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,
- MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
- }
-
- ## Convert the class to a string
- #
- # Convert member MetaFile of the class to a string
- #
- # @retval string Formatted String
- #
- def __str__(self):
- return str(self.MetaFile)
-
- ## Override __eq__ function
- #
- # Check whether ModuleBuildClassObjects are the same
- #
- # @retval False The two ModuleBuildClassObjects are different
- # @retval True The two ModuleBuildClassObjects are the same
- #
- def __eq__(self, Other):
- return self.MetaFile == Other
-
- ## Override __hash__ function
- #
- # Use MetaFile as key in hash table
- #
- # @retval string Key for hash table
- #
- def __hash__(self):
- return hash(self.MetaFile)
-
-## ModuleBuildClassObject
-#
-# This Class defines ModuleBuildClass
-#
-# @param object: Inherited from object class
-#
-# @var MetaFile: To store value for module meta file path
-# @var BaseName: To store value for BaseName
-# @var ModuleType: To store value for ModuleType
-# @var Guid: To store value for Guid
-# @var Version: To store value for Version
-# @var PcdIsDriver: To store value for PcdIsDriver
-# @var BinaryModule: To store value for BinaryModule
-# @var CustomMakefile: To store value for CustomMakefile
-# @var Specification: To store value for Specification
-# @var Shadow To store value for Shadow
-# @var LibraryClass: To store value for LibraryClass, it is a list structure as
-# [ LibraryClassObject, ...]
-# @var ModuleEntryPointList: To store value for ModuleEntryPointList
-# @var ModuleUnloadImageList: To store value for ModuleUnloadImageList
-# @var ConstructorList: To store value for ConstructorList
-# @var DestructorList: To store value for DestructorList
-# @var Binaries: To store value for Binaries, it is a list structure as
-# [ ModuleBinaryClassObject, ...]
-# @var Sources: To store value for Sources, it is a list structure as
-# [ ModuleSourceFilesClassObject, ... ]
-# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
-# { [LibraryClassName, ModuleType] : LibraryClassInfFile }
-# @var Protocols: To store value for Protocols, it is a list structure as
-# [ ProtocolName, ... ]
-# @var Ppis: To store value for Ppis, it is a list structure as
-# [ PpiName, ... ]
-# @var Guids: To store value for Guids, it is a list structure as
-# [ GuidName, ... ]
-# @var Includes: To store value for Includes, it is a list structure as
-# [ IncludePath, ... ]
-# @var Packages: To store value for Packages, it is a list structure as
-# [ DecFileName, ... ]
-# @var Pcds: To store value for Pcds, it is a set structure as
-# { [(PcdCName, PcdGuidCName)] : PcdClassObject}
-# @var BuildOptions: To store value for BuildOptions, it is a set structure as
-# { [BuildOptionKey] : BuildOptionValue}
-# @var Depex: To store value for Depex
-#
-class ModuleBuildClassObject(BuildData):
- def __init__(self):
- self.AutoGenVersion = 0
- self.MetaFile = ''
- self.BaseName = ''
- self.ModuleType = ''
- self.Guid = ''
- self.Version = ''
- self.PcdIsDriver = ''
- self.BinaryModule = ''
- self.Shadow = ''
- self.CustomMakefile = {}
- self.Specification = {}
- self.LibraryClass = []
- self.ModuleEntryPointList = []
- self.ModuleUnloadImageList = []
- self.ConstructorList = []
- self.DestructorList = []
-
- self.Binaries = []
- self.Sources = []
- self.LibraryClasses = OrderedDict()
- self.Libraries = []
- self.Protocols = []
- self.Ppis = []
- self.Guids = []
- self.Includes = []
- self.Packages = []
- self.Pcds = {}
- self.BuildOptions = {}
- self.Depex = {}
- self.StrPcdSet = []
- self.StrPcdOverallValue = {}
-
-## PackageBuildClassObject
-#
-# This Class defines PackageBuildClass
-#
-# @param object: Inherited from object class
-#
-# @var MetaFile: To store value for package meta file path
-# @var PackageName: To store value for PackageName
-# @var Guid: To store value for Guid
-# @var Version: To store value for Version
-# @var Protocols: To store value for Protocols, it is a set structure as
-# { [ProtocolName] : Protocol Guid, ... }
-# @var Ppis: To store value for Ppis, it is a set structure as
-# { [PpiName] : Ppi Guid, ... }
-# @var Guids: To store value for Guids, it is a set structure as
-# { [GuidName] : Guid, ... }
-# @var Includes: To store value for Includes, it is a list structure as
-# [ IncludePath, ... ]
-# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
-# { [LibraryClassName] : LibraryClassInfFile }
-# @var Pcds: To store value for Pcds, it is a set structure as
-# { [(PcdCName, PcdGuidCName)] : PcdClassObject}
-#
-class PackageBuildClassObject(BuildData):
- def __init__(self):
- self.MetaFile = ''
- self.PackageName = ''
- self.Guid = ''
- self.Version = ''
-
- self.Protocols = {}
- self.Ppis = {}
- self.Guids = {}
- self.Includes = []
- self.LibraryClasses = {}
- self.Pcds = {}
-
-## PlatformBuildClassObject
-#
-# This Class defines PlatformBuildClass
-#
-# @param object: Inherited from object class
-#
-# @var MetaFile: To store value for platform meta-file path
-# @var PlatformName: To store value for PlatformName
-# @var Guid: To store value for Guid
-# @var Version: To store value for Version
-# @var DscSpecification: To store value for DscSpecification
-# @var OutputDirectory: To store value for OutputDirectory
-# @var FlashDefinition: To store value for FlashDefinition
-# @var BuildNumber: To store value for BuildNumber
-# @var SkuIds: To store value for SkuIds, it is a set structure as
-# { 'SkuName' : SkuId, '!include' : includefilename, ...}
-# @var Modules: To store value for Modules, it is a list structure as
-# [ InfFileName, ... ]
-# @var Libraries: To store value for Libraries, it is a list structure as
-# [ InfFileName, ... ]
-# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
-# { (LibraryClassName, ModuleType) : LibraryClassInfFile }
-# @var Pcds: To store value for Pcds, it is a set structure as
-# { [(PcdCName, PcdGuidCName)] : PcdClassObject }
-# @var BuildOptions: To store value for BuildOptions, it is a set structure as
-# { [BuildOptionKey] : BuildOptionValue }
-#
-class PlatformBuildClassObject(BuildData):
- def __init__(self):
- self.MetaFile = ''
- self.PlatformName = ''
- self.Guid = ''
- self.Version = ''
- self.DscSpecification = ''
- self.OutputDirectory = ''
- self.FlashDefinition = ''
- self.BuildNumber = ''
-
- self.SkuIds = {}
- self.Modules = []
- self.LibraryInstances = []
- self.LibraryClasses = {}
- self.Libraries = {}
- self.Pcds = {}
- self.BuildOptions = {}
+## @file
+# This file is used to define each component of the build database
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+from collections import OrderedDict, namedtuple
+from Common.DataType import *
+import collections
+import re
+from collections import OrderedDict
+from Common.Misc import CopyDict,ArrayIndex
+import copy
+from CommonDataClass.DataClass import *
+import Common.EdkLogger as EdkLogger
+import Common.GlobalData as GlobalData
+from Common.BuildToolError import OPTION_VALUE_INVALID
+from Common.caching import cached_property
+StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_\[\]]*$')
+
+## PcdClassObject
+#
+# This Class is used for PcdObject
+#
+# @param object: Inherited from object class
+# @param Name: Input value for Name of Pcd, default is None
+# @param Guid: Input value for Guid of Pcd, default is None
+# @param Type: Input value for Type of Pcd, default is None
+# @param DatumType: Input value for DatumType of Pcd, default is None
+# @param Value: Input value for Value of Pcd, default is None
+# @param Token: Input value for Token of Pcd, default is None
+# @param MaxDatumSize: Input value for MaxDatumSize of Pcd, default is None
+# @param SkuInfoList: Input value for SkuInfoList of Pcd, default is {}
+# @param IsOverrided: Input value for IsOverrided of Pcd, default is False
+# @param GuidValue: Input value for TokenSpaceGuidValue of Pcd, default is None
+#
+# @var TokenCName: To store value for TokenCName
+# @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName
+# @var Type: To store value for Type
+# @var DatumType: To store value for DatumType
+# @var TokenValue: To store value for TokenValue
+# @var MaxDatumSize: To store value for MaxDatumSize
+# @var SkuInfoList: To store value for SkuInfoList
+# @var IsOverrided: To store value for IsOverrided
+# @var Phase: To store value for Phase, default is "DXE"
+#
+class PcdClassObject(object):
+ def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = None, IsOverrided = False, GuidValue = None, validateranges = None, validlists = None, expressions = None, IsDsc = False, UserDefinedDefaultStoresFlag = False):
+ self.TokenCName = Name
+ self.TokenSpaceGuidCName = Guid
+ self.TokenSpaceGuidValue = GuidValue
+ self.Type = Type
+ self._DatumType = DatumType
+ self.DefaultValue = Value
+ self.TokenValue = Token
+ self.MaxDatumSize = MaxDatumSize
+ self.MaxSizeUserSet = None
+ self.SkuInfoList = SkuInfoList if SkuInfoList is not None else OrderedDict()
+ self.Phase = "DXE"
+ self.Pending = False
+ self.IsOverrided = IsOverrided
+ self.IsFromBinaryInf = False
+ self.IsFromDsc = False
+ self.validateranges = validateranges if validateranges is not None else []
+ self.validlists = validlists if validlists is not None else []
+ self.expressions = expressions if expressions is not None else []
+ self.DscDefaultValue = None
+ self.DscRawValue = {}
+ self.DscRawValueInfo = {}
+ if IsDsc:
+ self.DscDefaultValue = Value
+ self.PcdValueFromComm = ""
+ self.PcdValueFromFdf = ""
+ self.PcdValueFromComponents = {} #{ModuleGuid:value, file_path,lineNo}
+ self.CustomAttribute = {}
+ self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
+ self._Capacity = None
+
+ @property
+ def Capacity(self):
+ if self._Capacity is None:
+ self._Capacity = []
+ dimension = ArrayIndex.findall(self._DatumType)
+ for item in dimension:
+ maxsize = item.lstrip("[").rstrip("]").strip()
+ if not maxsize:
+ maxsize = "-1"
+ maxsize = str(int(maxsize,16)) if maxsize.startswith(("0x","0X")) else maxsize
+ self._Capacity.append(maxsize)
+ if hasattr(self, "SkuOverrideValues"):
+ for sku in self.SkuOverrideValues:
+ for defaultstore in self.SkuOverrideValues[sku]:
+ fields = self.SkuOverrideValues[sku][defaultstore]
+ for demesionattr in fields:
+ fieldinfo = fields[demesionattr]
+ deme = ArrayIndex.findall(demesionattr)
+ for i in range(len(deme)):
+ if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]):
+ if self._Capacity[i] != "-1":
+ firstfieldinfo = list(fieldinfo.values())[0]
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size. From %s Line %s \n " %
+ (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] ))
+ if hasattr(self,"DefaultValues"):
+ for demesionattr in self.DefaultValues:
+ fieldinfo = self.DefaultValues[demesionattr]
+ deme = ArrayIndex.findall(demesionattr)
+ for i in range(len(deme)):
+ if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]):
+ if self._Capacity[i] != "-1":
+ firstfieldinfo = list(fieldinfo.values())[0]
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size. From %s Line %s \n " %
+ (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] ))
+ return self._Capacity
+
+ def PcdArraySize(self):
+ if self.Capacity[-1] == "-1":
+ return -1
+ size = 1
+ for de in self.Capacity:
+ size = size * int(de)
+ return size
+ @property
+ def DatumType(self):
+ return self._DatumType
+
+ @DatumType.setter
+ def DatumType(self,DataType):
+ self._DatumType = DataType
+ self._Capacity = None
+
+ @property
+ def BaseDatumType(self):
+ if self.IsArray():
+ return self._DatumType[:self._DatumType.index("[")]
+ else:
+ return self._DatumType
+ def IsArray(self):
+ return True if len(self.Capacity) else False
+
+ def IsAggregateDatumType(self):
+ if self.DatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
+ return False
+ if self.IsArray() or StructPattern.match(self.DatumType):
+ return True
+ return False
+
+ def IsSimpleTypeArray(self):
+ if self.IsArray() and self.BaseDatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, "BOOLEAN"]:
+ return True
+ return False
+
+ @staticmethod
+ def GetPcdMaxSizeWorker(PcdString, MaxSize):
+ if PcdString.startswith("{") and PcdString.endswith("}"):
+ return max([len(PcdString.split(",")),MaxSize])
+
+ if PcdString.startswith("\"") or PcdString.startswith("\'"):
+ return max([len(PcdString)-2+1,MaxSize])
+
+ if PcdString.startswith("L\""):
+ return max([2*(len(PcdString)-3+1),MaxSize])
+
+ return max([len(PcdString),MaxSize])
+
+ ## Get the maximum number of bytes
+ def GetPcdMaxSize(self):
+ if self.DatumType in TAB_PCD_NUMERIC_TYPES:
+ return MAX_SIZE_TYPE[self.DatumType]
+
+ MaxSize = int(self.MaxDatumSize, 10) if self.MaxDatumSize else 0
+ if self.PcdValueFromFdf:
+ MaxSize = self.GetPcdMaxSizeWorker(self.PcdValueFromFdf,MaxSize)
+ if self.PcdValueFromComm:
+ MaxSize = self.GetPcdMaxSizeWorker(self.PcdValueFromComm,MaxSize)
+ if hasattr(self, "DefaultValueFromDec"):
+ MaxSize = self.GetPcdMaxSizeWorker(self.DefaultValueFromDec,MaxSize)
+ return MaxSize
+
+ ## Get the number of bytes
+ def GetPcdSize(self):
+ if self.DatumType in TAB_PCD_NUMERIC_TYPES:
+ return MAX_SIZE_TYPE[self.DatumType]
+ if not self.DefaultValue:
+ return 1
+ elif self.DefaultValue[0] == 'L':
+ return (len(self.DefaultValue) - 2) * 2
+ elif self.DefaultValue[0] == '{':
+ return len(self.DefaultValue.split(','))
+ else:
+ return len(self.DefaultValue) - 1
+
+
+ ## Convert the class to a string
+ #
+ # Convert each member of the class to string
+ # Organize to a single line format string
+ #
+ # @retval Rtn Formatted String
+ #
+ def __str__(self):
+ Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \
+ 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \
+ 'Type=' + str(self.Type) + ', ' + \
+ 'DatumType=' + str(self.DatumType) + ', ' + \
+ 'DefaultValue=' + str(self.DefaultValue) + ', ' + \
+ 'TokenValue=' + str(self.TokenValue) + ', ' + \
+ 'MaxDatumSize=' + str(self.MaxDatumSize) + ', '
+ for Item in self.SkuInfoList.values():
+ Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName
+ Rtn = Rtn + ', IsOverrided=' + str(self.IsOverrided)
+
+ return Rtn
+
+ ## Override __eq__ function
+ #
+ # Check whether pcds are the same
+ #
+ # @retval False The two pcds are different
+ # @retval True The two pcds are the same
+ #
+ def __eq__(self, Other):
+ return Other and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName
+
+ ## Override __hash__ function
+ #
+ # Use (TokenCName, TokenSpaceGuidCName) as key in hash table
+ #
+ # @retval truple() Key for hash table
+ #
+ def __hash__(self):
+ return hash((self.TokenCName, self.TokenSpaceGuidCName))
+
+ @cached_property
+ def _fullname(self):
+ return ".".join((self.TokenSpaceGuidCName,self.TokenCName))
+
+ def __lt__(self,pcd):
+ return self._fullname < pcd._fullname
+ def __gt__(self,pcd):
+ return self._fullname > pcd._fullname
+
+ def sharedcopy(self,new_pcd):
+ new_pcd.TokenCName = self.TokenCName
+ new_pcd.TokenSpaceGuidCName = self.TokenSpaceGuidCName
+ new_pcd.TokenSpaceGuidValue = self.TokenSpaceGuidValue
+ new_pcd.Type = self.Type
+ new_pcd.DatumType = self.DatumType
+ new_pcd.DefaultValue = self.DefaultValue
+ new_pcd.TokenValue = self.TokenValue
+ new_pcd.MaxDatumSize = self.MaxDatumSize
+ new_pcd.MaxSizeUserSet = self.MaxSizeUserSet
+
+ new_pcd.Phase = self.Phase
+ new_pcd.Pending = self.Pending
+ new_pcd.IsOverrided = self.IsOverrided
+ new_pcd.IsFromBinaryInf = self.IsFromBinaryInf
+ new_pcd.IsFromDsc = self.IsFromDsc
+ new_pcd.PcdValueFromComm = self.PcdValueFromComm
+ new_pcd.PcdValueFromFdf = self.PcdValueFromFdf
+ new_pcd.UserDefinedDefaultStoresFlag = self.UserDefinedDefaultStoresFlag
+ new_pcd.DscRawValue = self.DscRawValue
+ new_pcd.DscRawValueInfo = self.DscRawValueInfo
+ new_pcd.CustomAttribute = self.CustomAttribute
+ new_pcd.validateranges = [item for item in self.validateranges]
+ new_pcd.validlists = [item for item in self.validlists]
+ new_pcd.expressions = [item for item in self.expressions]
+ new_pcd.SkuInfoList = {key: copy.deepcopy(skuobj) for key,skuobj in self.SkuInfoList.items()}
+ return new_pcd
+
+ def __deepcopy__(self,memo):
+ new_pcd = PcdClassObject()
+ self.sharedcopy(new_pcd)
+ return new_pcd
+
+class StructurePcd(PcdClassObject):
+ def __init__(self, StructuredPcdIncludeFile=None, Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList=None, IsOverrided=False, GuidValue=None, validateranges=None, validlists=None, expressions=None,default_store = TAB_DEFAULT_STORES_DEFAULT):
+ if SkuInfoList is None:
+ SkuInfoList = {}
+ if validateranges is None:
+ validateranges = []
+ if validlists is None:
+ validlists = []
+ if expressions is None:
+ expressions = []
+ if Packages is None:
+ Packages = []
+ super(StructurePcd, self).__init__(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided, GuidValue, validateranges, validlists, expressions)
+ self.StructuredPcdIncludeFile = [] if StructuredPcdIncludeFile is None else StructuredPcdIncludeFile
+ self.PackageDecs = Packages
+ self.DefaultStoreName = [default_store]
+ self.DefaultValues = OrderedDict()
+ self.PcdMode = None
+ self.SkuOverrideValues = OrderedDict()
+ self.StructName = None
+ self.PcdDefineLineNo = 0
+ self.PkgPath = ""
+ self.DefaultValueFromDec = ""
+ self.DefaultValueFromDecInfo = None
+ self.ValueChain = set()
+ self.PcdFieldValueFromComm = OrderedDict()
+ self.PcdFieldValueFromFdf = OrderedDict()
+ self.DefaultFromDSC=None
+ self.PcdFiledValueFromDscComponent = OrderedDict()
+ def __repr__(self):
+ return self.TypeName
+
+ def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0,DimensionAttr ="-1"):
+ if DimensionAttr not in self.DefaultValues:
+ self.DefaultValues[DimensionAttr] = collections.OrderedDict()
+ if FieldName in self.DefaultValues[DimensionAttr]:
+ del self.DefaultValues[DimensionAttr][FieldName]
+ self.DefaultValues[DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
+ return self.DefaultValues[DimensionAttr][FieldName]
+
+ def SetDecDefaultValue(self, DefaultValue,decpath=None,lineno=None):
+ self.DefaultValueFromDec = DefaultValue
+ self.DefaultValueFromDecInfo = (decpath,lineno)
+ def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0, DimensionAttr = '-1'):
+ if SkuName not in self.SkuOverrideValues:
+ self.SkuOverrideValues[SkuName] = OrderedDict()
+ if DefaultStoreName not in self.SkuOverrideValues[SkuName]:
+ self.SkuOverrideValues[SkuName][DefaultStoreName] = OrderedDict()
+ if DimensionAttr not in self.SkuOverrideValues[SkuName][DefaultStoreName]:
+ self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr] = collections.OrderedDict()
+ if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]:
+ del self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName]
+ self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
+ return self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName]
+
+ def AddComponentOverrideValue(self,FieldName, Value, ModuleGuid, FileName="", LineNo=0, DimensionAttr = '-1'):
+ self.PcdFiledValueFromDscComponent.setdefault(ModuleGuid, OrderedDict())
+ self.PcdFiledValueFromDscComponent[ModuleGuid].setdefault(DimensionAttr,OrderedDict())
+ self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
+ return self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldName]
+
+ def SetPcdMode (self, PcdMode):
+ self.PcdMode = PcdMode
+
+ def copy(self, PcdObject):
+ self.TokenCName = PcdObject.TokenCName if PcdObject.TokenCName else self.TokenCName
+ self.TokenSpaceGuidCName = PcdObject.TokenSpaceGuidCName if PcdObject.TokenSpaceGuidCName else PcdObject.TokenSpaceGuidCName
+ self.TokenSpaceGuidValue = PcdObject.TokenSpaceGuidValue if PcdObject.TokenSpaceGuidValue else self.TokenSpaceGuidValue
+ self.Type = PcdObject.Type if PcdObject.Type else self.Type
+ self._DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType
+ self.DefaultValue = PcdObject.DefaultValue if PcdObject.DefaultValue else self.DefaultValue
+ self.TokenValue = PcdObject.TokenValue if PcdObject.TokenValue else self.TokenValue
+ self.MaxDatumSize = PcdObject.MaxDatumSize if PcdObject.MaxDatumSize else self.MaxDatumSize
+ self.SkuInfoList = PcdObject.SkuInfoList if PcdObject.SkuInfoList else self.SkuInfoList
+ self.Phase = PcdObject.Phase if PcdObject.Phase else self.Phase
+ self.Pending = PcdObject.Pending if PcdObject.Pending else self.Pending
+ self.IsOverrided = PcdObject.IsOverrided if PcdObject.IsOverrided else self.IsOverrided
+ self.IsFromBinaryInf = PcdObject.IsFromBinaryInf if PcdObject.IsFromBinaryInf else self.IsFromBinaryInf
+ self.IsFromDsc = PcdObject.IsFromDsc if PcdObject.IsFromDsc else self.IsFromDsc
+ self.validateranges = PcdObject.validateranges if PcdObject.validateranges else self.validateranges
+ self.validlists = PcdObject.validlists if PcdObject.validlists else self.validlists
+ self.expressions = PcdObject.expressions if PcdObject.expressions else self.expressions
+ self.DscRawValue = PcdObject.DscRawValue if PcdObject.DscRawValue else self.DscRawValue
+ self.DscRawValueInfo = PcdObject.DscRawValueInfo if PcdObject.DscRawValueInfo else self.DscRawValueInfo
+ self.PcdValueFromComm = PcdObject.PcdValueFromComm if PcdObject.PcdValueFromComm else self.PcdValueFromComm
+ self.PcdValueFromFdf = PcdObject.PcdValueFromFdf if PcdObject.PcdValueFromFdf else self.PcdValueFromFdf
+ self.CustomAttribute = PcdObject.CustomAttribute if PcdObject.CustomAttribute else self.CustomAttribute
+ self.UserDefinedDefaultStoresFlag = PcdObject.UserDefinedDefaultStoresFlag if PcdObject.UserDefinedDefaultStoresFlag else self.UserDefinedDefaultStoresFlag
+ if isinstance(PcdObject, StructurePcd):
+ self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else self.StructuredPcdIncludeFile
+ self.PackageDecs = PcdObject.PackageDecs if PcdObject.PackageDecs else self.PackageDecs
+ self.DefaultValues = PcdObject.DefaultValues if PcdObject.DefaultValues else self.DefaultValues
+ self.PcdMode = PcdObject.PcdMode if PcdObject.PcdMode else self.PcdMode
+ self.DefaultValueFromDec = PcdObject.DefaultValueFromDec if PcdObject.DefaultValueFromDec else self.DefaultValueFromDec
+ self.DefaultValueFromDecInfo = PcdObject.DefaultValueFromDecInfo if PcdObject.DefaultValueFromDecInfo else self.DefaultValueFromDecInfo
+ self.SkuOverrideValues = PcdObject.SkuOverrideValues if PcdObject.SkuOverrideValues else self.SkuOverrideValues
+ self.StructName = PcdObject.DatumType if PcdObject.DatumType else self.StructName
+ self.PcdDefineLineNo = PcdObject.PcdDefineLineNo if PcdObject.PcdDefineLineNo else self.PcdDefineLineNo
+ self.PkgPath = PcdObject.PkgPath if PcdObject.PkgPath else self.PkgPath
+ self.ValueChain = PcdObject.ValueChain if PcdObject.ValueChain else self.ValueChain
+ self.PcdFieldValueFromComm = PcdObject.PcdFieldValueFromComm if PcdObject.PcdFieldValueFromComm else self.PcdFieldValueFromComm
+ self.PcdFieldValueFromFdf = PcdObject.PcdFieldValueFromFdf if PcdObject.PcdFieldValueFromFdf else self.PcdFieldValueFromFdf
+ self.PcdFiledValueFromDscComponent = PcdObject.PcdFiledValueFromDscComponent if PcdObject.PcdFiledValueFromDscComponent else self.PcdFiledValueFromDscComponent
+
+ def __deepcopy__(self,memo):
+ new_pcd = StructurePcd()
+ self.sharedcopy(new_pcd)
+
+ new_pcd.DefaultValueFromDec = self.DefaultValueFromDec
+ new_pcd.DefaultValueFromDecInfo = self.DefaultValueFromDecInfo
+ new_pcd.PcdMode = self.PcdMode
+ new_pcd.StructName = self.DatumType
+ new_pcd.PcdDefineLineNo = self.PcdDefineLineNo
+ new_pcd.PkgPath = self.PkgPath
+ new_pcd.StructuredPcdIncludeFile = [item for item in self.StructuredPcdIncludeFile]
+ new_pcd.PackageDecs = [item for item in self.PackageDecs]
+ new_pcd.DefaultValues = CopyDict(self.DefaultValues)
+ new_pcd.DefaultFromDSC=CopyDict(self.DefaultFromDSC)
+ new_pcd.SkuOverrideValues = CopyDict(self.SkuOverrideValues)
+ new_pcd.PcdFieldValueFromComm = CopyDict(self.PcdFieldValueFromComm)
+ new_pcd.PcdFieldValueFromFdf = CopyDict(self.PcdFieldValueFromFdf)
+ new_pcd.PcdFiledValueFromDscComponent = CopyDict(self.PcdFiledValueFromDscComponent)
+ new_pcd.ValueChain = {item for item in self.ValueChain}
+ return new_pcd
+
+LibraryClassObject = namedtuple('LibraryClassObject', ['LibraryClass','SupModList'])
+
+class BuildData(object):
+ # dict used to convert PCD type in database to string used by build tool
+
+ _PCD_TYPE_STRING_ = {
+ MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,
+ MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,
+ MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,
+ MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC,
+ MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC,
+ MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII,
+ MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD,
+ MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,
+ MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
+ }
+
+ def UpdatePcdTypeDict(self):
+ if GlobalData.gCommandLineDefines.get(TAB_DSC_DEFINES_PCD_DYNAMIC_AS_DYNAMICEX,"FALSE").upper() == "TRUE":
+ self._PCD_TYPE_STRING_ = {
+ MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,
+ MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,
+ MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,
+ MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_EX_HII,
+ MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
+ MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,
+ MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
+ }
+
+ ## Convert the class to a string
+ #
+ # Convert member MetaFile of the class to a string
+ #
+ # @retval string Formatted String
+ #
+ def __str__(self):
+ return str(self.MetaFile)
+
+ ## Override __eq__ function
+ #
+ # Check whether ModuleBuildClassObjects are the same
+ #
+ # @retval False The two ModuleBuildClassObjects are different
+ # @retval True The two ModuleBuildClassObjects are the same
+ #
+ def __eq__(self, Other):
+ return self.MetaFile == Other
+
+ ## Override __hash__ function
+ #
+ # Use MetaFile as key in hash table
+ #
+ # @retval string Key for hash table
+ #
+ def __hash__(self):
+ return hash(self.MetaFile)
+
+## ModuleBuildClassObject
+#
+# This Class defines ModuleBuildClass
+#
+# @param object: Inherited from object class
+#
+# @var MetaFile: To store value for module meta file path
+# @var BaseName: To store value for BaseName
+# @var ModuleType: To store value for ModuleType
+# @var Guid: To store value for Guid
+# @var Version: To store value for Version
+# @var PcdIsDriver: To store value for PcdIsDriver
+# @var BinaryModule: To store value for BinaryModule
+# @var CustomMakefile: To store value for CustomMakefile
+# @var Specification: To store value for Specification
+# @var Shadow To store value for Shadow
+# @var LibraryClass: To store value for LibraryClass, it is a list structure as
+# [ LibraryClassObject, ...]
+# @var ModuleEntryPointList: To store value for ModuleEntryPointList
+# @var ModuleUnloadImageList: To store value for ModuleUnloadImageList
+# @var ConstructorList: To store value for ConstructorList
+# @var DestructorList: To store value for DestructorList
+# @var Binaries: To store value for Binaries, it is a list structure as
+# [ ModuleBinaryClassObject, ...]
+# @var Sources: To store value for Sources, it is a list structure as
+# [ ModuleSourceFilesClassObject, ... ]
+# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
+# { [LibraryClassName, ModuleType] : LibraryClassInfFile }
+# @var Protocols: To store value for Protocols, it is a list structure as
+# [ ProtocolName, ... ]
+# @var Ppis: To store value for Ppis, it is a list structure as
+# [ PpiName, ... ]
+# @var Guids: To store value for Guids, it is a list structure as
+# [ GuidName, ... ]
+# @var Includes: To store value for Includes, it is a list structure as
+# [ IncludePath, ... ]
+# @var Packages: To store value for Packages, it is a list structure as
+# [ DecFileName, ... ]
+# @var Pcds: To store value for Pcds, it is a set structure as
+# { [(PcdCName, PcdGuidCName)] : PcdClassObject}
+# @var BuildOptions: To store value for BuildOptions, it is a set structure as
+# { [BuildOptionKey] : BuildOptionValue}
+# @var Depex: To store value for Depex
+#
+class ModuleBuildClassObject(BuildData):
+ def __init__(self):
+ self.AutoGenVersion = 0
+ self.MetaFile = ''
+ self.BaseName = ''
+ self.ModuleType = ''
+ self.Guid = ''
+ self.Version = ''
+ self.PcdIsDriver = ''
+ self.BinaryModule = ''
+ self.Shadow = ''
+ self.CustomMakefile = {}
+ self.Specification = {}
+ self.LibraryClass = []
+ self.ModuleEntryPointList = []
+ self.ModuleUnloadImageList = []
+ self.ConstructorList = []
+ self.DestructorList = []
+
+ self.Binaries = []
+ self.Sources = []
+ self.LibraryClasses = OrderedDict()
+ self.Libraries = []
+ self.Protocols = []
+ self.Ppis = []
+ self.Guids = []
+ self.Includes = []
+ self.Packages = []
+ self.Pcds = {}
+ self.BuildOptions = {}
+ self.Depex = {}
+ self.StrPcdSet = []
+ self.StrPcdOverallValue = {}
+
+## PackageBuildClassObject
+#
+# This Class defines PackageBuildClass
+#
+# @param object: Inherited from object class
+#
+# @var MetaFile: To store value for package meta file path
+# @var PackageName: To store value for PackageName
+# @var Guid: To store value for Guid
+# @var Version: To store value for Version
+# @var Protocols: To store value for Protocols, it is a set structure as
+# { [ProtocolName] : Protocol Guid, ... }
+# @var Ppis: To store value for Ppis, it is a set structure as
+# { [PpiName] : Ppi Guid, ... }
+# @var Guids: To store value for Guids, it is a set structure as
+# { [GuidName] : Guid, ... }
+# @var Includes: To store value for Includes, it is a list structure as
+# [ IncludePath, ... ]
+# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
+# { [LibraryClassName] : LibraryClassInfFile }
+# @var Pcds: To store value for Pcds, it is a set structure as
+# { [(PcdCName, PcdGuidCName)] : PcdClassObject}
+#
+class PackageBuildClassObject(BuildData):
+ def __init__(self):
+ self.MetaFile = ''
+ self.PackageName = ''
+ self.Guid = ''
+ self.Version = ''
+
+ self.Protocols = {}
+ self.Ppis = {}
+ self.Guids = {}
+ self.Includes = []
+ self.LibraryClasses = {}
+ self.Pcds = {}
+
+## PlatformBuildClassObject
+#
+# This Class defines PlatformBuildClass
+#
+# @param object: Inherited from object class
+#
+# @var MetaFile: To store value for platform meta-file path
+# @var PlatformName: To store value for PlatformName
+# @var Guid: To store value for Guid
+# @var Version: To store value for Version
+# @var DscSpecification: To store value for DscSpecification
+# @var OutputDirectory: To store value for OutputDirectory
+# @var FlashDefinition: To store value for FlashDefinition
+# @var BuildNumber: To store value for BuildNumber
+# @var SkuIds: To store value for SkuIds, it is a set structure as
+# { 'SkuName' : SkuId, '!include' : includefilename, ...}
+# @var Modules: To store value for Modules, it is a list structure as
+# [ InfFileName, ... ]
+# @var Libraries: To store value for Libraries, it is a list structure as
+# [ InfFileName, ... ]
+# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
+# { (LibraryClassName, ModuleType) : LibraryClassInfFile }
+# @var Pcds: To store value for Pcds, it is a set structure as
+# { [(PcdCName, PcdGuidCName)] : PcdClassObject }
+# @var BuildOptions: To store value for BuildOptions, it is a set structure as
+# { [BuildOptionKey] : BuildOptionValue }
+#
+class PlatformBuildClassObject(BuildData):
+ def __init__(self):
+ self.MetaFile = ''
+ self.PlatformName = ''
+ self.Guid = ''
+ self.Version = ''
+ self.DscSpecification = ''
+ self.OutputDirectory = ''
+ self.FlashDefinition = ''
+ self.BuildNumber = ''
+
+ self.SkuIds = {}
+ self.Modules = []
+ self.LibraryInstances = []
+ self.LibraryClasses = {}
+ self.Libraries = {}
+ self.Pcds = {}
+ self.BuildOptions = {}
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
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 5df184f9c8..c42db4bb9a 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -1,3672 +1,3672 @@
-## @file
-# This file is used to create a database used by build tool
-#
-# Copyright (c) 2008 - 2020, Intel Corporation. All rights reserved.<BR>
-# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-## Platform build information from DSC file
-#
-# This class is used to retrieve information stored in database and convert them
-# into PlatformBuildClassObject form for easier use for AutoGen.
-#
-from __future__ import print_function
-from __future__ import absolute_import
-from Common.StringUtils import *
-from Common.DataType import *
-from Common.Misc import *
-from types import *
-from Common.Expression import *
-from CommonDataClass.CommonClass import SkuInfoClass
-from Common.TargetTxtClassObject import TargetTxtDict,gDefaultTargetTxtFile
-from Common.ToolDefClassObject import ToolDefDict,gDefaultToolsDefFile
-from .MetaDataTable import *
-from .MetaFileTable import *
-from .MetaFileParser import *
-
-from .WorkspaceCommon import GetDeclaredPcd
-from Common.Misc import AnalyzeDscPcd
-from Common.Misc import ProcessDuplicatedInf,RemoveCComments,ArrayIndex
-import re
-from Common.Parsing import IsValidWord
-from Common.VariableAttributes import VariableAttributes
-import Common.GlobalData as GlobalData
-import subprocess
-from functools import reduce
-from Common.Misc import SaveFileOnChange
-from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
-from collections import OrderedDict, defaultdict
-import json
-import shutil
-
-def _IsFieldValueAnArray (Value):
- Value = Value.strip()
- if Value.startswith(TAB_GUID) and Value.endswith(')'):
- return True
- if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:
- return True
- if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
- return True
- if Value[0] == '{' and Value[-1] == '}':
- return True
- if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
- return True
- if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
- return True
- return False
-
-PcdValueInitName = 'PcdValueInit'
-PcdValueCommonName = 'PcdValueCommon'
-StructuredPcdsDataName = 'StructuredPcdsData.json'
-
-PcdMainCHeader = '''
-/**
- DO NOT EDIT
- FILE auto-generated
-**/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <PcdValueCommon.h>
-'''
-
-PcdMainCEntry = '''
-int
-main (
- int argc,
- char *argv[]
- )
-{
- return PcdValueMain (argc, argv);
-}
-'''
-
-PcdMakefileHeader = '''
-#
-# DO NOT EDIT
-# This file is auto-generated by build utility
-#
-
-'''
-
-WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
-LinuxCFLAGS = 'CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
-PcdMakefileEnd = r'''
-!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
-!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
-'''
-
-AppTarget = '''
-all: $(APPFILE)
-$(APPLICATION): $(OBJECTS)
-$(APPFILE): $(APPLICATION)
-%s
-'''
-
-PcdGccMakefile = '''
-MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
-LIBS = -lCommon
-'''
-
-variablePattern = re.compile(r'[\t\s]*0[xX][a-fA-F0-9]+$')
-SkuIdPattern = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
-## regular expressions for finding decimal and hex numbers
-Pattern = re.compile(r'^[1-9]\d*|0$')
-HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
-## Regular expression for finding header file inclusions
-from AutoGen.GenMake import gIncludePattern
-
-## Find dependencies for one source file
-#
-# By searching recursively "#include" directive in file, find out all the
-# files needed by given source file. The dependecies will be only searched
-# in given search path list.
-#
-# @param SearchPathList The list of search path
-#
-# @retval list The list of files the given source file depends on
-#
-def GetDependencyList(FileStack, SearchPathList):
- DepDb = dict()
- DependencySet = set(FileStack)
- while len(FileStack) > 0:
- F = FileStack.pop()
- FullPathDependList = []
- CurrentFileDependencyList = []
- if F in DepDb:
- CurrentFileDependencyList = DepDb[F]
- else:
- try:
- Fd = open(F, 'r')
- FileContent = Fd.read()
- except BaseException as X:
- EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X))
- finally:
- if "Fd" in dir(locals()):
- Fd.close()
-
- if len(FileContent) == 0:
- continue
-
- try:
- if FileContent[0] == 0xff or FileContent[0] == 0xfe:
- FileContent = FileContent.decode('utf-16')
- else:
- FileContent = FileContent.decode()
- except:
- # The file is not txt file. for example .mcb file
- continue
- IncludedFileList = gIncludePattern.findall(FileContent)
-
- for Inc in IncludedFileList:
- Inc = Inc.strip()
- Inc = os.path.normpath(Inc)
- CurrentFileDependencyList.append(Inc)
- DepDb[F] = CurrentFileDependencyList
-
- CurrentFilePath = os.path.dirname(F)
- PathList = [CurrentFilePath] + SearchPathList
- for Inc in CurrentFileDependencyList:
- for SearchPath in PathList:
- FilePath = os.path.join(SearchPath, Inc)
- if not os.path.exists(FilePath):
- continue
- if FilePath not in DependencySet:
- FileStack.append(FilePath)
- FullPathDependList.append(FilePath)
- break
- DependencySet.update(FullPathDependList)
- DependencyList = list(DependencySet) # remove duplicate ones
-
- return DependencyList
-
-class DscBuildData(PlatformBuildClassObject):
-
- # dict used to convert part of [Defines] to members of DscBuildData directly
- _PROPERTY_ = {
- #
- # Required Fields
- #
- TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",
- TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",
- TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",
- TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",
- # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
- # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
- # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
- TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
- # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
- TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
- TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
- TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
- TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
- # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
- # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
- }
-
- # used to compose dummy library class name for those forced library instances
- _NullLibraryNumber = 0
-
- ## Constructor of DscBuildData
- #
- # Initialize object of DscBuildData
- #
- # @param FilePath The path of platform description file
- # @param RawData The raw data of DSC file
- # @param BuildDataBase Database used to retrieve module/package information
- # @param Arch The target architecture
- # @param Platform (not used for DscBuildData)
- # @param Macros Macros used for replacement in DSC file
- #
- def __init__(self, FilePath, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
- self.MetaFile = FilePath
- self._RawData = RawData
- self._Bdb = BuildDataBase
- self._Arch = Arch
- self._Target = Target
- self._Toolchain = Toolchain
- self._ToolChainFamily = None
- self._Clear()
- self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else ""
- self.DefaultStores = None
- self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)
- self.UpdatePcdTypeDict()
- @property
- def OutputPath(self):
- if os.getenv("WORKSPACE"):
- return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain, PcdValueInitName)
- else:
- return os.path.dirname(self.DscFile)
-
- ## 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 DscBuildData to None
- def _Clear(self):
- self._Header = None
- self._PlatformName = None
- self._Guid = None
- self._Version = None
- self._DscSpecification = None
- self._OutputDirectory = None
- self._SupArchList = None
- self._BuildTargets = None
- self._SkuName = None
- self._PcdInfoFlag = None
- self._VarCheckFlag = None
- self._FlashDefinition = None
- self._Prebuild = None
- self._Postbuild = None
- self._BuildNumber = None
- self._MakefileName = None
- self._BsBaseAddress = None
- self._RtBaseAddress = None
- self._SkuIds = None
- self._Modules = None
- self._LibraryInstances = None
- self._LibraryClasses = None
- self._Pcds = None
- self._DecPcds = None
- self._BuildOptions = None
- self._ModuleTypeOptions = None
- self._LoadFixAddress = None
- self._RFCLanguages = None
- self._ISOLanguages = None
- self._VpdToolGuid = None
- self._MacroDict = None
- self.DefaultStores = None
-
- ## Get current effective macros
- @property
- def _Macros(self):
- if self._MacroDict is None:
- self._MacroDict = {}
- self._MacroDict.update(GlobalData.gPlatformDefines)
- self._MacroDict.update(GlobalData.gGlobalDefines)
- self._MacroDict.update(GlobalData.gCommandLineDefines)
- return self._MacroDict
-
- ## Get architecture
- @property
- def Arch(self):
- return self._Arch
- @property
- def Dir(self):
- return self.MetaFile.Dir
-
- ## 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]
- # items defined _PROPERTY_ don't need additional processing
-
- # some special items in [Defines] section need special treatment
- if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
- self._OutputDirectory = NormPath(Record[2], self._Macros)
- if ' ' in self._OutputDirectory:
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
- File=self.MetaFile, Line=Record[-1],
- ExtraData=self._OutputDirectory)
- elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
- self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
- ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
- ExtraData=ErrorInfo)
- elif Name == TAB_DSC_PREBUILD:
- PrebuildValue = Record[2]
- if Record[2][0] == '"':
- if Record[2][-1] != '"':
- EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,
- File=self.MetaFile, Line=Record[-1])
- PrebuildValue = Record[2][1:-1]
- self._Prebuild = PrebuildValue
- elif Name == TAB_DSC_POSTBUILD:
- PostbuildValue = Record[2]
- if Record[2][0] == '"':
- if Record[2][-1] != '"':
- EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,
- File=self.MetaFile, Line=Record[-1])
- PostbuildValue = Record[2][1:-1]
- self._Postbuild = PostbuildValue
- elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
- self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
- elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
- self._BuildTargets = GetSplitValueList(Record[2])
- elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
- if self._SkuName is None:
- self._SkuName = Record[2]
- if GlobalData.gSKUID_CMD:
- self._SkuName = GlobalData.gSKUID_CMD
- elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
- self._PcdInfoFlag = Record[2]
- elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
- self._VarCheckFlag = Record[2]
- elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
- try:
- self._LoadFixAddress = int (Record[2], 0)
- except:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
- elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
- if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
- File=self.MetaFile, Line=Record[-1])
- LanguageCodes = Record[2][1:-1]
- if not LanguageCodes:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
- File=self.MetaFile, Line=Record[-1])
- LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)
- # check whether there is empty entries in the list
- if None in LanguageList:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
- File=self.MetaFile, Line=Record[-1])
- self._RFCLanguages = LanguageList
- elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
- if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
- File=self.MetaFile, Line=Record[-1])
- LanguageCodes = Record[2][1:-1]
- if not LanguageCodes:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
- File=self.MetaFile, Line=Record[-1])
- if len(LanguageCodes) % 3:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',
- File=self.MetaFile, Line=Record[-1])
- LanguageList = []
- for i in range(0, len(LanguageCodes), 3):
- LanguageList.append(LanguageCodes[i:i + 3])
- self._ISOLanguages = LanguageList
- elif Name == TAB_DSC_DEFINES_VPD_AUTHENTICATED_VARIABLE_STORE:
- if TAB_DSC_DEFINES_VPD_AUTHENTICATED_VARIABLE_STORE not in gCommandLineDefines:
- gCommandLineDefines[TAB_DSC_DEFINES_VPD_AUTHENTICATED_VARIABLE_STORE] = Record[2].strip()
-
- elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
- #
- # try to convert GUID to a real UUID value to see whether the GUID is format
- # for VPD_TOOL_GUID is correct.
- #
- try:
- uuid.UUID(Record[2])
- except:
- EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
- self._VpdToolGuid = Record[2]
- elif Name == TAB_DSC_DEFINES_PCD_DYNAMIC_AS_DYNAMICEX:
- if TAB_DSC_DEFINES_PCD_DYNAMIC_AS_DYNAMICEX not in gCommandLineDefines:
- gCommandLineDefines[TAB_DSC_DEFINES_PCD_DYNAMIC_AS_DYNAMICEX] = Record[2].strip()
- elif Name in self:
- self[Name] = Record[2]
- # set _Header to non-None in order to avoid database re-querying
- self._Header = 'DUMMY'
-
- ## Retrieve platform name
- @property
- def PlatformName(self):
- if self._PlatformName is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._PlatformName is None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)
- return self._PlatformName
-
- @property
- def Platform(self):
- return self.PlatformName
-
- ## Retrieve file guid
- @property
- def Guid(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 PLATFORM_GUID", File=self.MetaFile)
- return self._Guid
-
- ## Retrieve platform version
- @property
- def Version(self):
- if self._Version is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._Version is None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)
- return self._Version
-
- ## Retrieve platform description file version
- @property
- def DscSpecification(self):
- if self._DscSpecification is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._DscSpecification is None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)
- return self._DscSpecification
-
- ## Retrieve OUTPUT_DIRECTORY
- @property
- def OutputDirectory(self):
- if self._OutputDirectory is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._OutputDirectory is None:
- self._OutputDirectory = os.path.join("Build", self._PlatformName)
- return self._OutputDirectory
-
- ## Retrieve SUPPORTED_ARCHITECTURES
- @property
- def SupArchList(self):
- if self._SupArchList is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._SupArchList is None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)
- return self._SupArchList
-
- ## Retrieve BUILD_TARGETS
- @property
- def BuildTargets(self):
- if self._BuildTargets is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._BuildTargets is None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
- return self._BuildTargets
-
- @property
- def PcdInfoFlag(self):
- if self._PcdInfoFlag is None or self._PcdInfoFlag.upper() == 'FALSE':
- return False
- elif self._PcdInfoFlag.upper() == 'TRUE':
- return True
- else:
- return False
-
- @property
- def VarCheckFlag(self):
- if self._VarCheckFlag is None or self._VarCheckFlag.upper() == 'FALSE':
- return False
- elif self._VarCheckFlag.upper() == 'TRUE':
- return True
- else:
- return False
-
- # # Retrieve SKUID_IDENTIFIER
- @property
- def SkuName(self):
- if self._SkuName is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._SkuName is None:
- self._SkuName = TAB_DEFAULT
- return self._SkuName
-
- ## Override SKUID_IDENTIFIER
- @SkuName.setter
- def SkuName(self, Value):
- self._SkuName = Value
-
- @property
- def FlashDefinition(self):
- if self._FlashDefinition is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._FlashDefinition is None:
- self._FlashDefinition = ''
- return self._FlashDefinition
-
- @property
- def Prebuild(self):
- if self._Prebuild is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._Prebuild is None:
- self._Prebuild = ''
- return self._Prebuild
-
- @property
- def Postbuild(self):
- if self._Postbuild is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._Postbuild is None:
- self._Postbuild = ''
- return self._Postbuild
-
- ## Retrieve FLASH_DEFINITION
- @property
- def BuildNumber(self):
- if self._BuildNumber is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._BuildNumber is None:
- self._BuildNumber = ''
- return self._BuildNumber
-
- ## Retrieve MAKEFILE_NAME
- @property
- def MakefileName(self):
- if self._MakefileName is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._MakefileName is None:
- self._MakefileName = ''
- return self._MakefileName
-
- ## Retrieve BsBaseAddress
- @property
- def BsBaseAddress(self):
- if self._BsBaseAddress is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._BsBaseAddress is None:
- self._BsBaseAddress = ''
- return self._BsBaseAddress
-
- ## Retrieve RtBaseAddress
- @property
- def RtBaseAddress(self):
- if self._RtBaseAddress is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._RtBaseAddress is None:
- self._RtBaseAddress = ''
- return self._RtBaseAddress
-
- ## Retrieve the top address for the load fix address
- @property
- def LoadFixAddress(self):
- if self._LoadFixAddress is None:
- if self._Header is None:
- self._GetHeaderInfo()
-
- if self._LoadFixAddress is None:
- self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
-
- try:
- self._LoadFixAddress = int (self._LoadFixAddress, 0)
- except:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
-
- #
- # If command line defined, should override the value in DSC file.
- #
- if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines:
- try:
- self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
- except:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))
-
- if self._LoadFixAddress < 0:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
- if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
-
- return self._LoadFixAddress
-
- ## Retrieve RFCLanguage filter
- @property
- def RFCLanguages(self):
- if self._RFCLanguages is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._RFCLanguages is None:
- self._RFCLanguages = []
- return self._RFCLanguages
-
- ## Retrieve ISOLanguage filter
- @property
- def ISOLanguages(self):
- if self._ISOLanguages is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._ISOLanguages is None:
- self._ISOLanguages = []
- return self._ISOLanguages
-
- ## Retrieve the GUID string for VPD tool
- @property
- def VpdToolGuid(self):
- if self._VpdToolGuid is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._VpdToolGuid is None:
- self._VpdToolGuid = ''
- return self._VpdToolGuid
-
- ## Retrieve [SkuIds] section information
- @property
- def SkuIds(self):
- if self._SkuIds is None:
- self._SkuIds = OrderedDict()
- RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
- for Record in RecordList:
- if not Record[0]:
- EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
- File=self.MetaFile, Line=Record[-1])
- if not Record[1]:
- EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',
- File=self.MetaFile, Line=Record[-1])
- if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]):
- EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",
- File=self.MetaFile, Line=Record[-1])
- if not SkuIdPattern.match(Record[1]) or (Record[2] and not SkuIdPattern.match(Record[2])):
- EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z_)(a-zA-Z0-9_)*'",
- File=self.MetaFile, Line=Record[-1])
- self._SkuIds[Record[1].upper()] = (str(DscBuildData.ToInt(Record[0])), Record[1].upper(), Record[2].upper())
- if TAB_DEFAULT not in self._SkuIds:
- self._SkuIds[TAB_DEFAULT] = ("0", TAB_DEFAULT, TAB_DEFAULT)
- if TAB_COMMON not in self._SkuIds:
- self._SkuIds[TAB_COMMON] = ("0", TAB_DEFAULT, TAB_DEFAULT)
- return self._SkuIds
-
- @staticmethod
- def ToInt(intstr):
- return int(intstr, 16) if intstr.upper().startswith("0X") else int(intstr)
-
- def _GetDefaultStores(self):
- if self.DefaultStores is None:
- self.DefaultStores = OrderedDict()
- RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]
- for Record in RecordList:
- if not Record[0]:
- EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',
- File=self.MetaFile, Line=Record[-1])
- if not Record[1]:
- EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',
- File=self.MetaFile, Line=Record[-1])
- if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]):
- EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",
- File=self.MetaFile, Line=Record[-1])
- if not IsValidWord(Record[1]):
- EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
- File=self.MetaFile, Line=Record[-1])
- self.DefaultStores[Record[1].upper()] = (DscBuildData.ToInt(Record[0]), Record[1].upper())
- if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:
- self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0, TAB_DEFAULT_STORES_DEFAULT)
- GlobalData.gDefaultStores = sorted(self.DefaultStores.keys())
- return self.DefaultStores
-
- def OverrideDuplicateModule(self):
- RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
- Macros = self._Macros
- Components = {}
- for Record in RecordList:
- ModuleId = Record[6]
- file_guid = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
- file_guid_str = file_guid[0][2] if file_guid else "NULL"
- ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- if self._Arch != TAB_ARCH_COMMON and (file_guid_str,str(ModuleFile)) in Components:
- self._RawData.DisableOverrideComponent(Components[(file_guid_str,str(ModuleFile))])
- Components[(file_guid_str,str(ModuleFile))] = ModuleId
- self._RawData._PostProcessed = False
-
- ## Retrieve packages this Platform depends on
- @cached_property
- def Packages(self):
- RetVal = set()
- RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch]
- Macros = self._Macros
- for Record in RecordList:
- File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate('.dec')
- if ErrorCode != 0:
- LineNo = Record[-1]
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
- # parse this package now. we need it to get protocol/ppi/guid value
- RetVal.add(self._Bdb[File, self._Arch, self._Target, self._Toolchain])
- return RetVal
-
- ## Retrieve [Components] section information
- @property
- def Modules(self):
- if self._Modules is not None:
- return self._Modules
- self.OverrideDuplicateModule()
- self._Modules = OrderedDict()
- RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
- Macros = self._Macros
- for Record in RecordList:
- ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- ModuleId = Record[6]
- LineNo = Record[7]
-
- # check the file validation
- ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
- ExtraData=ErrorInfo)
-
- ModuleBuildData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
- Module = ModuleBuildClassObject()
- Module.MetaFile = ModuleFile
- Module.Guid = ModuleBuildData.Guid
- # get module private library instance
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
- for Record in RecordList:
- LibraryClass = Record[0]
- LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- LineNo = Record[-1]
-
- # check the file validation
- ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
- ExtraData=ErrorInfo)
-
- if LibraryClass == '' or LibraryClass == 'NULL':
- self._NullLibraryNumber += 1
- LibraryClass = 'NULL%d' % self._NullLibraryNumber
- EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
- Module.LibraryClasses[LibraryClass] = LibraryPath
- if LibraryPath not in self.LibraryInstances:
- self.LibraryInstances.append(LibraryPath)
- S_PcdSet = []
- # get module private PCD setting
- for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \
- MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
- RecordList = self._RawData[Type, self._Arch, None, ModuleId]
- for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
- TokenList = GetSplitValueList(Setting)
- DefaultValue = TokenList[0]
- # the format is PcdName| Value | VOID* | MaxDatumSize
- if len(TokenList) > 2:
- MaxDatumSize = TokenList[2]
- else:
- MaxDatumSize = ''
- TypeString = self._PCD_TYPE_STRING_[Type]
-
- TCName,PCName,DimensionAttr,Field = self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
-
- if ("." in TokenSpaceGuid or "[" in PcdCName):
- S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, ModuleBuildData.Guid, "", Dummy5, AnalyzePcdExpression(Setting)[0]])
- DefaultValue = ''
- if ( PCName,TCName) not in Module.Pcds:
- Pcd = PcdClassObject(
- PCName,
- TCName,
- TypeString,
- '',
- DefaultValue,
- '',
- MaxDatumSize,
- {},
- False,
- None,
- IsDsc=True)
- Module.Pcds[PCName, TCName] = Pcd
-
- Module.StrPcdSet = S_PcdSet
- for TCName,PCName, _,_,_,_,_,_ in S_PcdSet:
- if (PCName,TCName) in Module.Pcds:
- Module.StrPcdOverallValue[(PCName,TCName)] = Module.Pcds[(PCName,TCName)].DefaultValue, self.MetaFile,Dummy5
- # get module private build options
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
- for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
- if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
- Module.BuildOptions[ToolChainFamily, ToolChain] = Option
- else:
- OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
- Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
-
- RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
- if RecordList:
- if len(RecordList) != 1:
- EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',
- File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
- ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
- ModuleFile.Arch = self._Arch
- Module.Guid = RecordList[0][2]
- for item in Module.StrPcdSet:
- item[4] = RecordList[0][2]
- self._Modules[ModuleFile] = Module
- return self._Modules
-
- ## Retrieve all possible library instances used in this platform
- @property
- def LibraryInstances(self):
- if self._LibraryInstances is None:
- self.LibraryClasses
- return self._LibraryInstances
-
- ## Retrieve [LibraryClasses] information
- @property
- def LibraryClasses(self):
- if self._LibraryClasses is None:
- self._LibraryInstances = []
- #
- # tdict is a special dict kind of type, used for selecting correct
- # library instance for given library class and module type
- #
- LibraryClassDict = tdict(True, 3)
- # track all library class names
- LibraryClassSet = set()
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
- Macros = self._Macros
- for Record in RecordList:
- LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, Dummy, LineNo = Record
- if LibraryClass == '' or LibraryClass == 'NULL':
- self._NullLibraryNumber += 1
- LibraryClass = 'NULL%d' % self._NullLibraryNumber
- EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
- LibraryClassSet.add(LibraryClass)
- LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
- # check the file validation
- ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
- ExtraData=ErrorInfo)
-
- if ModuleType != TAB_COMMON and ModuleType not in SUP_MODULE_LIST:
- EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
- File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
- LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
- if LibraryInstance not in self._LibraryInstances:
- self._LibraryInstances.append(LibraryInstance)
-
- # resolve the specific library instance for each class and each module type
- self._LibraryClasses = tdict(True)
- for LibraryClass in LibraryClassSet:
- # try all possible module types
- for ModuleType in SUP_MODULE_LIST:
- LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
- if LibraryInstance is None:
- continue
- self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
-
- RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
- for Record in RecordList:
- File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- LineNo = Record[-1]
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate('.inf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
- ExtraData=ErrorInfo)
- if File not in self._LibraryInstances:
- self._LibraryInstances.append(File)
- #
- # we need the module name as the library class name, so we have
- # to parse it here. (self._Bdb[] will trigger a file parse if it
- # hasn't been parsed)
- #
- Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
- self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
- return self._LibraryClasses
-
- def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
- if not self._DecPcds:
-
- FdfInfList = []
- if GlobalData.gFdfParser:
- FdfInfList = GlobalData.gFdfParser.Profile.InfList
-
- PkgSet = set()
- for Inf in FdfInfList:
- ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
- if ModuleFile in self._Modules:
- continue
- ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
- PkgSet.update(ModuleData.Packages)
- if self.Packages:
- PkgSet.update(self.Packages)
- self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
- self._GuidDict.update(GlobalData.gPlatformPcds)
-
- if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
- EdkLogger.error('build', PARSER_ERROR,
- "Pcd (%s.%s) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
- File=self.MetaFile, Line=LineNo)
- ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
- if not IsValid:
- if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
- EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
- ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
- else:
- if ValueList[2] == '-1':
- EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
- ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
- if ValueList[Index]:
- DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
- if "{CODE(" not in ValueList[Index]:
- try:
- ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
- except BadExpression as Value:
- EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
- ExtraData="PCD [%s.%s] Value \"%s\" " % (
- TokenSpaceGuid, PcdCName, ValueList[Index]))
- except EvaluationException as Excpt:
- if hasattr(Excpt, 'Pcd'):
- if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
- EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
- " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
- " of the DSC file" % Excpt.Pcd,
- File=self.MetaFile, Line=LineNo)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
- File=self.MetaFile, Line=LineNo)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
- File=self.MetaFile, Line=LineNo)
-
- if ValueList[Index]:
- Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
- if not Valid:
- EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
- ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
- if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):
- if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():
- DecPcd = self._DecPcds[PcdCName, TokenSpaceGuid]
- EdkLogger.error('build', FORMAT_INVALID,
- "Pcd datumtype used in DSC file is not the same as its declaration. DatumType:%s"%DecPcd.DatumType,
- File=self.MetaFile, Line=LineNo,
- ExtraData="Dsc:%s.%s|%s\n Dec:%s.%s|%s|%s|%s" % (TokenSpaceGuid, PcdCName, Setting, TokenSpaceGuid, \
- PcdCName, DecPcd.DefaultValue, DecPcd.DatumType, DecPcd.TokenValue))
- if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:
- if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:
- GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
- GlobalData.gPlatformFinalPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
- return ValueList
-
- def _FilterPcdBySkuUsage(self, Pcds):
- available_sku = self.SkuIdMgr.AvailableSkuIdSet
- sku_usage = self.SkuIdMgr.SkuUsageType
- if sku_usage == SkuClass.SINGLE:
- for pcdname in Pcds:
- pcd = Pcds[pcdname]
- Pcds[pcdname].SkuInfoList = {TAB_DEFAULT:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
- if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
- Pcds[pcdname].SkuOverrideValues = {TAB_DEFAULT:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
- else:
- for pcdname in Pcds:
- pcd = Pcds[pcdname]
- Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
- if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
- Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
- return Pcds
-
- def CompleteHiiPcdsDefaultStores(self, Pcds):
- HiiPcd = [Pcds[pcd] for pcd in Pcds if Pcds[pcd].Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]]
- DefaultStoreMgr = DefaultStore(self.DefaultStores)
- for pcd in HiiPcd:
- for skuid in pcd.SkuInfoList:
- skuobj = pcd.SkuInfoList.get(skuid)
- if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:
- PcdDefaultStoreSet = set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict)
- mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
- skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = skuobj.DefaultStoreDict[mindefaultstorename]
- return Pcds
-
- def RecoverCommandLinePcd(self):
- def UpdateCommandLineValue(pcd):
- if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
- self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
- pcd.PcdValueFromComm = pcd.DefaultValue
- elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
- pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).HiiDefaultValue
- else:
- pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).DefaultValue
- for pcd in self._Pcds:
- if isinstance(self._Pcds[pcd], StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):
- UpdateCommandLineValue(self._Pcds[pcd])
-
- def __ParsePcdFromCommandLine(self):
- if GlobalData.BuildOptionPcd:
- for i, pcd in enumerate(GlobalData.BuildOptionPcd):
- if isinstance(pcd, tuple):
- continue
- (pcdname, pcdvalue) = pcd.split('=')
- if not pcdvalue:
- EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
- if '.' in pcdname:
- (Name1, Name2) = pcdname.split('.', 1)
- if "." in Name2:
- (Name3, FieldName) = Name2.split(".", 1)
- if ((Name3, Name1)) in self.DecPcds:
- HasTokenSpace = True
- TokenCName = Name3
- TokenSpaceGuidCName = Name1
- else:
- FieldName = Name2
- TokenCName = Name1
- TokenSpaceGuidCName = ''
- HasTokenSpace = False
- else:
- if ((Name2, Name1)) in self.DecPcds:
- HasTokenSpace = True
- TokenCName = Name2
- TokenSpaceGuidCName = Name1
- FieldName =""
- else:
- FieldName = Name2
- TokenCName = Name1
- TokenSpaceGuidCName = ''
- HasTokenSpace = False
- else:
- FieldName = ""
- TokenCName = pcdname
- TokenSpaceGuidCName = ''
- HasTokenSpace = False
- TokenSpaceGuidCNameList = []
- FoundFlag = False
- PcdDatumType = ''
- DisplayName = TokenCName
- if FieldName:
- DisplayName = TokenCName + '.' + FieldName
- if not HasTokenSpace:
- for key in self.DecPcds:
- PcdItem = self.DecPcds[key]
- if TokenCName == PcdItem.TokenCName:
- if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
- if len (TokenSpaceGuidCNameList) < 1:
- TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
- TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
- PcdDatumType = PcdItem.DatumType
- FoundFlag = True
- else:
- EdkLogger.error(
- 'build',
- AUTOGEN_ERROR,
- "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
- )
- else:
- if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
- PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType
- FoundFlag = True
- if not FoundFlag:
- if HasTokenSpace:
- EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))
- else:
- EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))
- pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
- if FieldName:
- pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)
- else:
- pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)
- IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)
- if not IsValid:
- EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
- GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, ("build command options", 1))
-
- if GlobalData.BuildOptionPcd:
- inf_objs = [item for item in self._Bdb._CACHE_.values() if item.Arch == self.Arch and item.MetaFile.Ext.lower() == '.inf']
- for pcd in GlobalData.BuildOptionPcd:
- (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, _) = pcd
- for BuildData in inf_objs:
- for key in BuildData.Pcds:
- PcdItem = BuildData.Pcds[key]
- if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
- PcdItem.DefaultValue = pcdvalue
- PcdItem.PcdValueFromComm = pcdvalue
- #In command line, the latter full assign value in commandLine should override the former field assign value.
- #For example, --pcd Token.pcd.field="" --pcd Token.pcd=H"{}"
- delete_assign = []
- field_assign = {}
- if GlobalData.BuildOptionPcd:
- for pcdTuple in GlobalData.BuildOptionPcd:
- TokenSpaceGuid, Token, Field = pcdTuple[0], pcdTuple[1], pcdTuple[2]
- if Field:
- if (TokenSpaceGuid, Token) not in field_assign:
- field_assign[TokenSpaceGuid, Token] = []
- field_assign[TokenSpaceGuid, Token].append(pcdTuple)
- else:
- if (TokenSpaceGuid, Token) in field_assign:
- delete_assign.extend(field_assign[TokenSpaceGuid, Token])
- field_assign[TokenSpaceGuid, Token] = []
- for item in delete_assign:
- GlobalData.BuildOptionPcd.remove(item)
-
- @staticmethod
- def HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):
- if FieldName:
- IsArray = False
- TokenCName += '.' + FieldName
- if PcdValue.startswith('H'):
- if FieldName and _IsFieldValueAnArray(PcdValue[1:]):
- PcdDatumType = TAB_VOID
- IsArray = True
- if FieldName and not IsArray:
- return PcdValue
- try:
- PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)
- except BadExpression as Value:
- EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
- (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
- elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
- if FieldName and _IsFieldValueAnArray(PcdValue):
- PcdDatumType = TAB_VOID
- IsArray = True
- if FieldName and not IsArray:
- return PcdValue
- try:
- PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
- except BadExpression as Value:
- EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
- (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
- elif PcdValue.startswith('L'):
- PcdValue = 'L"' + PcdValue[1:] + '"'
- if FieldName and _IsFieldValueAnArray(PcdValue):
- PcdDatumType = TAB_VOID
- IsArray = True
- if FieldName and not IsArray:
- return PcdValue
- try:
- PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
- except BadExpression as Value:
- EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
- (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
- else:
- if PcdValue.upper() == 'FALSE':
- PcdValue = str(0)
- if PcdValue.upper() == 'TRUE':
- PcdValue = str(1)
- if not FieldName:
- if PcdDatumType not in TAB_PCD_NUMERIC_TYPES:
- PcdValue = '"' + PcdValue + '"'
- elif not PcdValue.isdigit() and not PcdValue.upper().startswith('0X'):
- PcdValue = '"' + PcdValue + '"'
- else:
- IsArray = False
- Base = 10
- if PcdValue.upper().startswith('0X'):
- Base = 16
- try:
- Num = int(PcdValue, Base)
- except:
- PcdValue = '"' + PcdValue + '"'
- if _IsFieldValueAnArray(PcdValue):
- PcdDatumType = TAB_VOID
- IsArray = True
- if not IsArray:
- return PcdValue
- try:
- PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
- except BadExpression as Value:
- EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
- (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
- return PcdValue
-
- ## Retrieve all PCD settings in platform
- @property
- def Pcds(self):
- if self._Pcds is None:
- self._Pcds = OrderedDict()
- self.__ParsePcdFromCommandLine()
- 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._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
- self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
- self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
- self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
- self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
- self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
-
- self._Pcds = self.CompletePcdValues(self._Pcds)
- self._Pcds = self.OverrideByFdfOverAll(self._Pcds)
- self._Pcds = self.OverrideByCommOverAll(self._Pcds)
- self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
- self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
- self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
-
- self.RecoverCommandLinePcd()
- return self._Pcds
-
- ## Retrieve [BuildOptions]
- @property
- def BuildOptions(self):
- if self._BuildOptions is None:
- self._BuildOptions = OrderedDict()
- #
- # Retrieve build option for EDKII and EDK style module
- #
- for CodeBase in (EDKII_NAME, EDK_NAME):
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
- for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
- if Dummy3.upper() != TAB_COMMON:
- continue
- CurKey = (ToolChainFamily, ToolChain, CodeBase)
- #
- # Only flags can be appended
- #
- if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
- self._BuildOptions[CurKey] = Option
- else:
- if ' ' + Option not in self._BuildOptions[CurKey]:
- self._BuildOptions[CurKey] += ' ' + Option
- return self._BuildOptions
- def GetBuildOptionsByPkg(self, Module, ModuleType):
-
- local_pkg = os.path.split(Module.LocalPkg())[0]
- if self._ModuleTypeOptions is None:
- self._ModuleTypeOptions = OrderedDict()
- if ModuleType not in self._ModuleTypeOptions:
- options = OrderedDict()
- self._ModuleTypeOptions[ ModuleType] = options
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
- for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
- if Dummy2 not in (TAB_COMMON,local_pkg.upper(),"EDKII"):
- continue
- Type = Dummy3
- if Type.upper() == ModuleType.upper():
- Key = (ToolChainFamily, ToolChain)
- if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
- options[Key] = Option
- else:
- if ' ' + Option not in options[Key]:
- options[Key] += ' ' + Option
- return self._ModuleTypeOptions[ModuleType]
- def GetBuildOptionsByModuleType(self, Edk, ModuleType):
- if self._ModuleTypeOptions is None:
- self._ModuleTypeOptions = OrderedDict()
- if (Edk, ModuleType) not in self._ModuleTypeOptions:
- options = OrderedDict()
- self._ModuleTypeOptions[Edk, ModuleType] = options
- DriverType = '%s.%s' % (Edk, ModuleType)
- CommonDriverType = '%s.%s' % (TAB_COMMON, ModuleType)
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
- for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
- Type = Dummy2 + '.' + Dummy3
- if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
- Key = (ToolChainFamily, ToolChain, Edk)
- if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
- options[Key] = Option
- else:
- if ' ' + Option not in options[Key]:
- options[Key] += ' ' + Option
- return self._ModuleTypeOptions[Edk, ModuleType]
-
- @staticmethod
- def GetStructurePcdInfo(PcdSet):
- structure_pcd_data = defaultdict(list)
- for item in PcdSet:
- structure_pcd_data[(item[0], item[1])].append(item)
-
- return structure_pcd_data
-
- @staticmethod
- def OverrideByFdf(StruPcds,workspace):
- if GlobalData.gFdfParser is None:
- return StruPcds
- StructurePcdInFdf = OrderedDict()
- fdfpcd = GlobalData.gFdfParser.Profile.PcdDict
- fdfpcdlocation = GlobalData.gFdfParser.Profile.PcdLocalDict
- for item in fdfpcd :
- if len(item[2]) and (item[0],item[1]) in StruPcds:
- StructurePcdInFdf[(item[1],item[0],item[2] )] = fdfpcd[item]
- GlobalPcds = {(item[0],item[1]) for item in StructurePcdInFdf}
- for Pcd in StruPcds.values():
- if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
- continue
- FieldValues = OrderedDict()
- for item in StructurePcdInFdf:
- if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:
- FieldValues[item[2]] = StructurePcdInFdf[item]
- for field in FieldValues:
- if field not in Pcd.PcdFieldValueFromFdf:
- Pcd.PcdFieldValueFromFdf[field] = ["","",""]
- Pcd.PcdFieldValueFromFdf[field][0] = FieldValues[field]
- Pcd.PcdFieldValueFromFdf[field][1] = os.path.relpath(fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][0],workspace)
- Pcd.PcdFieldValueFromFdf[field][2] = fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][1]
-
- return StruPcds
-
- @staticmethod
- def OverrideByComm(StruPcds):
- StructurePcdInCom = OrderedDict()
- for item in GlobalData.BuildOptionPcd:
- if len(item) == 5 and (item[1], item[0]) in StruPcds:
- StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
- GlobalPcds = {(item[0], item[1]) for item in StructurePcdInCom}
- for Pcd in StruPcds.values():
- if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in GlobalPcds:
- continue
- FieldValues = OrderedDict()
- for item in StructurePcdInCom:
- if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (item[0], item[1]) and item[2]:
- FieldValues[item[2]] = StructurePcdInCom[item]
- for field in FieldValues:
- if field not in Pcd.PcdFieldValueFromComm:
- Pcd.PcdFieldValueFromComm[field] = ["", "", ""]
- Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]
- Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]
- Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]
- return StruPcds
-
- def OverrideByCommOverAll(self,AllPcds):
- def CheckStructureInComm(commpcds):
- if not commpcds:
- return False
- if len(commpcds[0]) == 5:
- return True
- return False
- NoFiledValues = OrderedDict()
- if CheckStructureInComm(GlobalData.BuildOptionPcd):
- StructurePcdInCom = OrderedDict()
- for item in GlobalData.BuildOptionPcd:
- StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
- for item in StructurePcdInCom:
- if not item[2]:
- NoFiledValues[(item[0], item[1])] = StructurePcdInCom[item]
- else:
- for item in GlobalData.BuildOptionPcd:
- NoFiledValues[(item[0], item[1])] = [item[2]]
- for Guid, Name in NoFiledValues:
- if (Name, Guid) in AllPcds:
- Pcd = AllPcds.get((Name, Guid))
- if isinstance(self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), None), StructurePcd):
- self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
- else:
- Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
- Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
- for sku in Pcd.SkuInfoList:
- SkuInfo = Pcd.SkuInfoList[sku]
- if SkuInfo.DefaultValue:
- SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
- else:
- SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
- for defaultstore in SkuInfo.DefaultStoreDict:
- SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
- if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
- if Pcd.DatumType == TAB_VOID:
- if not Pcd.MaxDatumSize:
- Pcd.MaxDatumSize = '0'
- CurrentSize = int(Pcd.MaxDatumSize, 16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
- OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
- MaxSize = max(CurrentSize, OptionSize)
- Pcd.MaxDatumSize = str(MaxSize)
- else:
- PcdInDec = self.DecPcds.get((Name, Guid))
- if PcdInDec:
- PcdInDec.PcdValueFromComm = NoFiledValues[(Guid, Name)][0]
- if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
- self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
- self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
- self._Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
- self._Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid, Name)][0]
- if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
- self._Pcds[Name, Guid].SkuInfoList = {TAB_DEFAULT:SkuInfoClass(TAB_DEFAULT, self.SkuIds[TAB_DEFAULT][0], '', '', '', '', '', NoFiledValues[( Guid, Name)][0])}
- return AllPcds
-
- def OverrideByFdfOverAll(self,AllPcds):
-
- if GlobalData.gFdfParser is None:
- return AllPcds
- NoFiledValues = GlobalData.gFdfParser.Profile.PcdDict
- for Name,Guid,Field in NoFiledValues:
- if len(Field):
- continue
- Value = NoFiledValues[(Name,Guid,Field)]
- if (Name,Guid) in AllPcds:
- Pcd = AllPcds.get((Name,Guid))
- if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):
- self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = Value
- else:
- Pcd.PcdValueFromComm = Value
- Pcd.DefaultValue = Value
- for sku in Pcd.SkuInfoList:
- SkuInfo = Pcd.SkuInfoList[sku]
- if SkuInfo.DefaultValue:
- SkuInfo.DefaultValue = Value
- else:
- SkuInfo.HiiDefaultValue = Value
- for defaultstore in SkuInfo.DefaultStoreDict:
- SkuInfo.DefaultStoreDict[defaultstore] = Value
- if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
- if Pcd.DatumType == TAB_VOID:
- if not Pcd.MaxDatumSize:
- Pcd.MaxDatumSize = '0'
- CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
- OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
- MaxSize = max(CurrentSize, OptionSize)
- Pcd.MaxDatumSize = str(MaxSize)
- else:
- PcdInDec = self.DecPcds.get((Name,Guid))
- if PcdInDec:
- PcdInDec.PcdValueFromFdf = Value
- if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
- self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
- self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
- self._Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
- self._Pcds[Name, Guid].DefaultValue = Value
- return AllPcds
-
- def ParsePcdNameStruct(self,NamePart1,NamePart2):
- TokenSpaceCName = PcdCName = DimensionAttr = Field = ""
- if "." in NamePart1:
- TokenSpaceCName, TempPcdCName = NamePart1.split(".")
- if "[" in TempPcdCName:
- PcdCName = TempPcdCName[:TempPcdCName.index("[")]
- DimensionAttr = TempPcdCName[TempPcdCName.index("["):]
- else:
- PcdCName = TempPcdCName
- Field = NamePart2
- else:
- TokenSpaceCName = NamePart1
- if "[" in NamePart2:
- PcdCName = NamePart2[:NamePart2.index("[")]
- DimensionAttr = NamePart2[NamePart2.index("["):]
- else:
- PcdCName = NamePart2
-
- return TokenSpaceCName,PcdCName,DimensionAttr,Field
-
- def UpdateStructuredPcds(self, TypeList, AllPcds):
-
- DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
-
- Pcds = AllPcds
- DefaultStoreMgr = DefaultStore(self.DefaultStores)
- SkuIds = self.SkuIds
- self.SkuIdMgr.AvailableSkuIdSet.update({TAB_DEFAULT:0})
- DefaultStores = {storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict}
- DefaultStores.add(TAB_DEFAULT_STORES_DEFAULT)
-
- S_PcdSet = []
- # Find out all possible PCD candidates for self._Arch
- RecordList = []
-
- for Type in TypeList:
- RecordList.extend(self._RawData[Type, self._Arch])
-
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4, Dummy5 in RecordList:
- SkuName = SkuName.upper()
- default_store = default_store.upper()
- SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
- if SkuName not in SkuIds:
- continue
- TCName,PCName,DimensionAttr,Field = self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
- pcd_in_dec = self._DecPcds.get((PCName,TCName), None)
- if pcd_in_dec is None:
- EdkLogger.error('build', PARSER_ERROR,
- "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
- File=self.MetaFile, Line = Dummy5)
- if SkuName in SkuIds and ("." in TokenSpaceGuid or "[" in PcdCName):
- if not isinstance (pcd_in_dec, StructurePcd):
- EdkLogger.error('build', PARSER_ERROR,
- "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
- File=self.MetaFile, Line = Dummy5)
-
- S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
- ModuleScopeOverallValue = {}
- for m in self.Modules.values():
- mguid = m.Guid
- if m.StrPcdSet:
- S_PcdSet.extend(m.StrPcdSet)
- mguid = m.StrPcdSet[0][4]
- for (PCName,TCName) in m.StrPcdOverallValue:
- Value, dsc_file, lineNo = m.StrPcdOverallValue[(PCName,TCName)]
- ModuleScopeOverallValue.setdefault((PCName,TCName),{})[mguid] = Value, dsc_file, lineNo
- # handle pcd value override
- StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
- S_pcd_set = OrderedDict()
- for str_pcd in StrPcdSet:
- str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
- str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
- str_pcd_obj_str = StructurePcd()
- str_pcd_obj_str.copy(str_pcd_dec)
- if str_pcd_obj:
- str_pcd_obj_str.copy(str_pcd_obj)
- if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
- str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
- else:
- str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
- for str_pcd_data in StrPcdSet[str_pcd]:
- if str_pcd_data[4] in SkuIds:
- str_pcd_obj_str.AddOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] == TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
- elif GlobalData.gGuidPattern.match(str_pcd_data[4]):
- str_pcd_obj_str.AddComponentOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), str_pcd_data[4].replace("-","S"), self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
- PcdComponentValue = ModuleScopeOverallValue.get((str_pcd_obj_str.TokenCName,str_pcd_obj_str.TokenSpaceGuidCName))
- for module_guid in PcdComponentValue:
- str_pcd_obj_str.PcdValueFromComponents[module_guid.replace("-","S")] = PcdComponentValue[module_guid]
- S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
-
- # Add the Structure PCD that only defined in DEC, don't have override in DSC file
- for Pcd in self.DecPcds:
- if isinstance(self._DecPcds[Pcd], StructurePcd):
- if Pcd not in S_pcd_set:
- str_pcd_obj_str = StructurePcd()
- str_pcd_obj_str.copy(self._DecPcds[Pcd])
- str_pcd_obj = Pcds.get(Pcd, None)
- if str_pcd_obj:
- str_pcd_obj_str.copy(str_pcd_obj)
- if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
- str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
- else:
- str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
- S_pcd_set[Pcd] = str_pcd_obj_str
- if S_pcd_set:
- GlobalData.gStructurePcd[self.Arch] = S_pcd_set.copy()
- self.FilterStrcturePcd(S_pcd_set)
- for stru_pcd in S_pcd_set.values():
- for skuid in SkuIds:
- if skuid in stru_pcd.SkuOverrideValues:
- continue
- nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
- NoDefault = False
- if skuid not in stru_pcd.SkuOverrideValues:
- while nextskuid not in stru_pcd.SkuOverrideValues:
- if nextskuid == TAB_DEFAULT:
- NoDefault = True
- break
- nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
- stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {}) #{TAB_DEFAULT_STORES_DEFAULT:stru_pcd.DefaultValues})
- if not NoDefault:
- stru_pcd.ValueChain.add((skuid, ''))
- if 'DEFAULT' in stru_pcd.SkuOverrideValues and not GlobalData.gPcdSkuOverrides.get((stru_pcd.TokenCName, stru_pcd.TokenSpaceGuidCName)):
- GlobalData.gPcdSkuOverrides.update(
- {(stru_pcd.TokenCName, stru_pcd.TokenSpaceGuidCName): {'DEFAULT':stru_pcd.SkuOverrideValues['DEFAULT']}})
- if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
- for skuid in SkuIds:
- nextskuid = skuid
- NoDefault = False
- if skuid not in stru_pcd.SkuOverrideValues:
- while nextskuid not in stru_pcd.SkuOverrideValues:
- if nextskuid == TAB_DEFAULT:
- NoDefault = True
- break
- nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
- if NoDefault:
- continue
- PcdDefaultStoreSet = set(defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])
- mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
-
- for defaultstoreid in DefaultStores:
- if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
- stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
- stru_pcd.ValueChain.add((skuid, defaultstoreid))
- S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
- S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
-
- # Create a tool to caculate structure pcd value
- Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
-
- if Str_Pcd_Values:
- for (skuname, StoreName, PcdGuid, PcdName, PcdValue) in Str_Pcd_Values:
- str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
- if str_pcd_obj is None:
- print(PcdName, PcdGuid)
- raise
- if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
- if skuname not in str_pcd_obj.SkuInfoList:
- str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
- else:
- str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
- str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
- elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
- self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
- if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
- str_pcd_obj.DefaultValue = PcdValue
- else:
- #Module Scope Structure Pcd
- moduleguid = skuname.replace("S","-")
- if GlobalData.gGuidPattern.match(moduleguid):
- for component in self.Modules.values():
- if component.Guid == moduleguid:
- component.Pcds[(PcdName, PcdGuid)].DefaultValue = PcdValue
-
- else:
- if skuname not in str_pcd_obj.SkuInfoList:
- nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
- NoDefault = False
- while nextskuid not in str_pcd_obj.SkuInfoList:
- if nextskuid == TAB_DEFAULT:
- NoDefault = True
- break
- nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
- str_pcd_obj.SkuInfoList[skuname] = copy.deepcopy(str_pcd_obj.SkuInfoList[nextskuid]) if not NoDefault else SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue)
- str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
- str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
- else:
- str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
- for str_pcd_obj in S_pcd_set.values():
- if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
- continue
- PcdDefaultStoreSet = set(defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict)
- DefaultStoreObj = DefaultStore(self._GetDefaultStores())
- mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
- str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
-
- for str_pcd_obj in S_pcd_set.values():
-
- str_pcd_obj.MaxDatumSize = DscBuildData.GetStructurePcdMaxSize(str_pcd_obj)
- Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
- Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName].CustomAttribute['IsStru']=True
-
- for pcdkey in Pcds:
- pcd = Pcds[pcdkey]
- if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
- pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
- del pcd.SkuInfoList[TAB_COMMON]
- elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
- del pcd.SkuInfoList[TAB_COMMON]
-
- list(map(self.FilterSkuSettings, [Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType]))
- return Pcds
- @cached_property
- def PlatformUsedPcds(self):
- FdfInfList = []
- if GlobalData.gFdfParser:
- FdfInfList = GlobalData.gFdfParser.Profile.InfList
- FdfModuleList = [PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch) for Inf in FdfInfList]
- AllModulePcds = set()
- ModuleSet = set(list(self._Modules.keys()) + FdfModuleList)
- for ModuleFile in ModuleSet:
- ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
- AllModulePcds = AllModulePcds | ModuleData.PcdsName
- for ModuleFile in self.LibraryInstances:
- ModuleData = self._Bdb.CreateBuildObject(ModuleFile, self._Arch, self._Target, self._Toolchain)
- AllModulePcds = AllModulePcds | ModuleData.PcdsName
- return AllModulePcds
-
- #Filter the StrucutrePcd that is not used by any module in dsc file and fdf file.
- def FilterStrcturePcd(self, S_pcd_set):
- UnusedStruPcds = set(S_pcd_set.keys()) - self.PlatformUsedPcds
- for (Token, TokenSpaceGuid) in UnusedStruPcds:
- del S_pcd_set[(Token, TokenSpaceGuid)]
-
- ## Retrieve non-dynamic PCD settings
- #
- # @param Type PCD type
- #
- # @retval a dict object contains settings of given PCD type
- #
- def _GetPcd(self, Type):
- Pcds = OrderedDict()
- #
- # tdict is a special dict kind of type, used for selecting correct
- # PCD settings for certain ARCH
- #
- AvailableSkuIdSet = copy.copy(self.SkuIds)
-
- PcdDict = tdict(True, 4)
- PcdList = []
- # Find out all possible PCD candidates for self._Arch
- RecordList = self._RawData[Type, self._Arch]
- PcdValueDict = OrderedDict()
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
- SkuName = SkuName.upper()
- SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
- if SkuName not in AvailableSkuIdSet:
- EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
- File=self.MetaFile, Line=Dummy5)
- if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
- if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
- PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
- PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
-
- for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
- Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
- if Setting is None:
- continue
- PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
- if MaxDatumSize:
- if int(MaxDatumSize, 0) > 0xFFFF:
- EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
- File=self.MetaFile, Line=Dummy4)
- if int(MaxDatumSize, 0) < 0:
- EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
- File=self.MetaFile, Line=Dummy4)
- if (PcdCName, TokenSpaceGuid) in PcdValueDict:
- PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize,Dummy4)
- else:
- PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize,Dummy4)}
-
- for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.items():
- if self.SkuIdMgr.SystemSkuId in PcdSetting:
- PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[self.SkuIdMgr.SystemSkuId]
- elif TAB_DEFAULT in PcdSetting:
- PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[TAB_DEFAULT]
- elif TAB_COMMON in PcdSetting:
- PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[TAB_COMMON]
- else:
- PcdValue = None
- DatumType = None
- MaxDatumSize = None
-
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- PcdValue,
- '',
- MaxDatumSize,
- {},
- False,
- None,
- IsDsc=True)
- for SkuName in PcdValueDict[PcdCName, TokenSpaceGuid]:
- Settings = PcdValueDict[PcdCName, TokenSpaceGuid][SkuName]
- if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
- Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
- Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
- Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = Settings[0]
- Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Settings[3])
- return Pcds
-
- @staticmethod
- def GetStructurePcdMaxSize(str_pcd):
- pcd_default_value = str_pcd.DefaultValue
- sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [DscBuildData._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], DscBuildData._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]
- sku_values.append(pcd_default_value)
-
- def get_length(value):
- Value = value.strip()
- if len(value) > 1:
- if Value.startswith(TAB_GUID) and Value.endswith(')'):
- return 16
- if Value.startswith('L"') and Value.endswith('"'):
- return len(Value[2:-1])
- if Value[0] == '"' and Value[-1] == '"':
- return len(Value) - 2
- if Value.strip().startswith("{CODE("):
- tmpValue = RemoveCComments(Value)
- return len(tmpValue.split(","))
- if (Value[0] == '{' and Value[-1] == '}'):
- return len(Value.split(","))
- if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
- return len(list(Value[2:-1]))
- if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
- return len(Value) - 2
- return len(Value)
-
- return str(max(get_length(item) for item in sku_values))
-
- @staticmethod
- def ExecuteCommand (Command):
- try:
- Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
- except:
- EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
- Result = Process.communicate()
- return Process.returncode, Result[0].decode(errors='ignore'), Result[1].decode(errors='ignore')
-
- @staticmethod
- def IntToCString(Value, ValueSize):
- Result = '"'
- if not isinstance (Value, str):
- for Index in range(0, ValueSize):
- Result = Result + '\\x%02x' % (Value & 0xff)
- Value = Value >> 8
- Result = Result + '"'
- return Result
-
- def GenerateSizeFunction(self, Pcd):
- CApp = "// Default Value in Dec \n"
- CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
-
- if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
- CApp += " *Size = (sizeof (%s) > *Size ? sizeof (%s) : *Size);\n" % (Pcd.DatumType,Pcd.DatumType)
- else:
- if "{CODE(" in Pcd.DefaultValueFromDec:
- CApp += " *Size = (sizeof (%s_%s_INIT_Value) > *Size ? sizeof (%s_%s_INIT_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Pcd.TokenSpaceGuidCName,Pcd.TokenCName)
- if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
- for skuname in Pcd.SkuInfoList:
- skuobj = Pcd.SkuInfoList[skuname]
- if skuobj.VariableName:
- for defaultstore in skuobj.DefaultStoreDict:
- pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,defaultstore)
- if pcddef:
- if "{CODE(" in pcddef:
- CApp += " *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
- else:
- CApp += " *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
- else:
- pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,TAB_DEFAULT_STORES_DEFAULT)
- if pcddef:
- if "{CODE(" in pcddef:
- CApp += " *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT)
- else:
- CApp += " *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
- else:
- pcddef = self.GetPcdDscRawDefaultValue(Pcd,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
- if pcddef:
- if "{CODE(" in pcddef:
- CApp += " *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
- else:
- CApp += " *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
- ActualCap = []
- for index in Pcd.DefaultValues:
- if index:
- ActualCap.append(index)
- FieldList = Pcd.DefaultValues[index]
- if not FieldList:
- continue
- for FieldName in FieldList:
- FieldName = "." + FieldName
- IsArray = _IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
- if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
- try:
- Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
- Value, ValueSize = ParseFieldValue(Value)
- if not Pcd.IsArray():
- CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
- else:
- NewFieldName = ''
- FieldName_ori = FieldName.strip('.')
- while '[' in FieldName:
- NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
- Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
- FieldName = FieldName.split(']', 1)[1]
- FieldName = NewFieldName + FieldName
- while '[' in FieldName and not Pcd.IsArray():
- FieldName = FieldName.rsplit('[', 1)[0]
- CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
- flexisbale_size_statement_cache = set()
- for skuname in Pcd.SkuOverrideValues:
- if skuname == TAB_COMMON:
- continue
- for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
- CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
- for index in Pcd.SkuOverrideValues[skuname][defaultstorenameitem]:
- if index:
- ActualCap.append(index)
- for FieldList in [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]:
- if not FieldList:
- continue
- for FieldName in FieldList:
- fieldinfo = tuple(FieldList[FieldName])
- if fieldinfo in flexisbale_size_statement_cache:
- continue
- flexisbale_size_statement_cache.add(fieldinfo)
- FieldName = "." + FieldName
- IsArray = _IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
- if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
- try:
- Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
- Value, ValueSize = ParseFieldValue(Value)
- if not Pcd.IsArray():
- CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
- else:
- NewFieldName = ''
- FieldName_ori = FieldName.strip('.')
- while '[' in FieldName:
- NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
- Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
- FieldName = FieldName.split(']', 1)[1]
- FieldName = NewFieldName + FieldName
- while '[' in FieldName and not Pcd.IsArray():
- FieldName = FieldName.rsplit('[', 1)[0]
- CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
- if Pcd.PcdFieldValueFromFdf:
- CApp = CApp + "// From fdf \n"
- for FieldName in Pcd.PcdFieldValueFromFdf:
- FieldName = "." + FieldName
- IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
- if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):
- try:
- Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))
- Value, ValueSize = ParseFieldValue(Value)
- if not Pcd.IsArray():
- CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0]);
- else:
- NewFieldName = ''
- FieldName_ori = FieldName.strip('.')
- while '[' in FieldName:
- NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
- Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
- FieldName = FieldName.split(']', 1)[1]
- FieldName = NewFieldName + FieldName
- while '[' in FieldName:
- FieldName = FieldName.rsplit('[', 1)[0]
- CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
- if Pcd.PcdFieldValueFromComm:
- CApp = CApp + "// From Command Line \n"
- for FieldName in Pcd.PcdFieldValueFromComm:
- FieldName = "." + FieldName
- IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
- if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
- try:
- Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
- Value, ValueSize = ParseFieldValue(Value)
- if not Pcd.IsArray():
- CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]);
- else:
- NewFieldName = ''
- FieldName_ori = FieldName.strip('.')
- while '[' in FieldName:
- NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
- Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
- FieldName = FieldName.split(']', 1)[1]
- FieldName = NewFieldName + FieldName
- while '[' in FieldName and not Pcd.IsArray():
- FieldName = FieldName.rsplit('[', 1)[0]
- CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
- if Pcd.GetPcdMaxSize():
- CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
- ArraySizeByAssign = self.CalculateActualCap(ActualCap)
- if ArraySizeByAssign > 1:
- CApp = CApp + " *Size = (%d > *Size ? %d : *Size); \n" % (ArraySizeByAssign, ArraySizeByAssign)
- CApp = CApp + "}\n"
- return CApp
- def CalculateActualCap(self,ActualCap):
- if not ActualCap:
- return 1
- maxsize = 1
- for item in ActualCap:
- index_elements = ArrayIndex.findall(item)
- rt = 1
- for index_e in index_elements:
- index_num = index_e.lstrip("[").rstrip("]").strip()
- if not index_num:
- # Not support flexiable pcd array assignment
- return 1
- index_num = int(index_num,16) if index_num.startswith(("0x","0X")) else int(index_num)
- rt = rt * (index_num+1)
- if rt >maxsize:
- maxsize = rt
-
- return maxsize
-
- @staticmethod
- def GenerateSizeStatments(Pcd,skuname,defaultstorename):
- if Pcd.IsArray():
- r_datatype = [Pcd.BaseDatumType]
- lastoneisEmpty = False
- for dem in Pcd.Capacity:
- if lastoneisEmpty:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName))))
- if dem == '0' or dem == "-1":
- r_datatype.append("[1]")
- lastoneisEmpty = True
- else:
- r_datatype.append("[" + dem + "]")
-
- if Pcd.Type in [MODEL_PCD_DYNAMIC_EX_HII, MODEL_PCD_DYNAMIC_HII]:
- PcdDefValue = Pcd.SkuInfoList.get(skuname).DefaultStoreDict.get(defaultstorename)
- elif Pcd.Type in [MODEL_PCD_DYNAMIC_EX_DEFAULT,MODEL_PCD_DYNAMIC_VPD,MODEL_PCD_DYNAMIC_DEFAULT,MODEL_PCD_DYNAMIC_EX_VPD]:
- PcdDefValue = Pcd.SkuInfoList.get(skuname).DefaultValue
- else:
- PcdDefValue = Pcd.DefaultValue
- if lastoneisEmpty:
- if "{CODE(" not in PcdDefValue:
- sizebasevalue_plus = "(%s / sizeof(%s) + 1)" % ((DscBuildData.GetStructurePcdMaxSize(Pcd), Pcd.BaseDatumType))
- sizebasevalue = "(%s / sizeof(%s))" % ((DscBuildData.GetStructurePcdMaxSize(Pcd), Pcd.BaseDatumType))
- sizeof = "sizeof(%s)" % Pcd.BaseDatumType
- CApp = ' int ArraySize = %s %% %s ? %s : %s ;\n' % ( (DscBuildData.GetStructurePcdMaxSize(Pcd), sizeof, sizebasevalue_plus, sizebasevalue))
- CApp += ' Size = ArraySize * sizeof(%s); \n' % Pcd.BaseDatumType
- else:
- CApp = " Size = 0;\n"
- else:
- CApp = ' Size = sizeof(%s);\n' % ("".join(r_datatype) )
- else:
- CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)
- CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- return CApp
-
- def GetIndicator(self,index,FieldName,Pcd):
- def cleanupindex(indexstr):
- return indexstr.strip("[").strip("]").strip()
- index_elements = ArrayIndex.findall(index)
- pcd_capacity = Pcd.Capacity
- if index:
- indicator = "(Pcd"
- if len(pcd_capacity)>2:
- for i in range(0,len(index_elements)):
- index_ele = index_elements[i]
- index_num = index_ele.strip("[").strip("]").strip()
- if i == len(index_elements) -2:
- indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[i+1])),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]), cleanupindex(index_elements[i]))
- break
- else:
- indicator += " + %d*%s*Size/sizeof(%s)/%d" %(int(cleanupindex(index_elements[i])),reduce(lambda x,y: int(x)*int(y),pcd_capacity[i+1:-1]),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]))
- elif len(pcd_capacity) == 2:
- indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[0])),Pcd.BaseDatumType,int(pcd_capacity[0]), index_elements[1].strip("[").strip("]").strip())
- elif len(pcd_capacity) == 1:
- index_ele = index_elements[0]
- index_num = index_ele.strip("[").strip("]").strip()
- indicator += " + %s)" % (index_num)
- else:
- indicator = "Pcd"
- if FieldName:
- indicator += "->" + FieldName
- return indicator
-
- def GetStarNum(self,Pcd):
- if not Pcd.IsArray():
- return 1
- elif Pcd.IsSimpleTypeArray():
- return len(Pcd.Capacity)
- else:
- return len(Pcd.Capacity) + 1
- def GenerateDefaultValueAssignFunction(self, Pcd):
- CApp = "// Default value in Dec \n"
- CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
- CApp = CApp + ' UINT32 FieldSize;\n'
- CApp = CApp + ' CHAR8 *Value;\n'
- CApp = CApp + ' UINT32 PcdArraySize;\n'
- DefaultValueFromDec = Pcd.DefaultValueFromDec
- IsArray = _IsFieldValueAnArray(Pcd.DefaultValueFromDec)
- if IsArray:
- try:
- DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
- except BadExpression:
- EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
- (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
- DefaultValueFromDec = StringToArray(DefaultValueFromDec)
- Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
- if IsArray:
- #
- # Use memcpy() to copy value into field
- #
- if Pcd.IsArray():
- pcdarraysize = Pcd.PcdArraySize()
- if "{CODE(" in Pcd.DefaultValueFromDec:
- if Pcd.Capacity[-1] != "-1":
- CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_INIT_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
- CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- CApp = CApp + ' memcpy (Pcd, %s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- else:
- if Pcd.Capacity[-1] != "-1":
- CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
- CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
- CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
- CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n'
- else:
- if "{CODE(" in Pcd.DefaultValueFromDec:
- CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- CApp = CApp + ' memcpy (Pcd, &%s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- else:
- CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
- CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
- elif isinstance(Value, str):
- CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
- for index in Pcd.DefaultValues:
- FieldList = Pcd.DefaultValues[index]
- if not FieldList:
- continue
- for FieldName in FieldList:
- IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
- if IsArray:
- try:
- FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
-
- try:
- Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
- except Exception:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
-
- indicator = self.GetIndicator(index, FieldName,Pcd)
- if IsArray:
- #
- # Use memcpy() to copy value into field
- #
- CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
- CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
- elif isinstance(Value, str):
- CApp = CApp + ' %s = %s; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- else:
- if '[' in FieldName and ']' in FieldName:
- Index = int(FieldName.split('[')[1].split(']')[0])
- CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
- if ValueSize > 4:
- CApp = CApp + ' %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- else:
- CApp = CApp + ' %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + "}\n"
- return CApp
-
- @staticmethod
- def GenerateDefaultValueAssignStatement(Pcd):
- CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- return CApp
-
- def GetPcdDscRawDefaultValue(self,Pcd, SkuName,DefaultStoreName):
- if Pcd.Type in PCD_DYNAMIC_TYPE_SET or Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
- if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
- pcddefaultvalue = Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT) if Pcd.DefaultFromDSC else None
- else:
- pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
- else:
- pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(TAB_DEFAULT_STORES_DEFAULT)
-
- return pcddefaultvalue
- def GetPcdDscRawValueInfo(self,Pcd, SkuName,DefaultStoreName):
- DscValueInfo = Pcd.DscRawValueInfo.get(SkuName, {}).get(DefaultStoreName)
- if DscValueInfo:
- dscfilepath,lineno = DscValueInfo
- else:
- dscfilepath = self.MetaFile.File
- lineno = ""
- return dscfilepath,lineno
-
- def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
- CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
- CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.BaseDatumType)
- CApp = CApp + ' UINT32 FieldSize;\n'
- CApp = CApp + ' CHAR8 *Value;\n'
- CApp = CApp + ' UINT32 PcdArraySize;\n'
-
- CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
- inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
- dscfilepath,lineno = self.GetPcdDscRawValueInfo(Pcd, SkuName, DefaultStoreName)
- if lineno:
- valuefrom = "%s Line %s" % (dscfilepath,str(lineno))
- else:
- valuefrom = dscfilepath
-
- pcddefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, SkuName, DefaultStoreName)
- if pcddefaultvalue:
- FieldList = pcddefaultvalue
- IsArray = _IsFieldValueAnArray(FieldList)
- if IsArray:
- if "{CODE(" not in FieldList:
- try:
- FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
- except BadExpression:
- EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
- (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
- Value, ValueSize = ParseFieldValue (FieldList)
-
- if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
- if isinstance(Value, str):
- if "{CODE(" in Value:
- if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
- pcdarraysize = Pcd.PcdArraySize()
- CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType, valuefrom)
- CApp = CApp+ ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- else:
- CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- if Pcd.IsArray():
- pcdarraysize = Pcd.PcdArraySize()
- if "{CODE(" in pcddefaultvalue:
- if Pcd.Capacity[-1] != "-1":
- CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
- CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- else:
- if Pcd.Capacity[-1] != "-1":
- CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
- CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
- CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
- CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n'
- else:
- if "{CODE(" in pcddefaultvalue:
- CApp = CApp + ' PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' % (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
- CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- else:
- CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
- CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
- else:
- if isinstance(Value, str):
- if "{CODE(" in Value:
- if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
- pcdarraysize = Pcd.PcdArraySize()
- CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
- CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n '% (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- else:
- CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- if Pcd.IsArray():
- pcdarraysize = Pcd.PcdArraySize()
- if "{CODE(" in pcddefaultvalue:
- if Pcd.Capacity[-1] != "-1":
- CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
- CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- else:
- if Pcd.Capacity[-1] != "-1":
- CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
- CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
- CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
- CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n'
- else:
- if "{CODE(" in pcddefaultvalue:
- CApp = CApp + ' PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' % (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
- CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
- else:
- CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
- CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
-
- inheritvalue = inherit_OverrideValues.get(DefaultStoreName)
- if not inheritvalue:
- inheritvalue = []
- for index in inheritvalue:
- FieldList = inheritvalue[index]
- if not FieldList:
- continue
- if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
- for FieldName in FieldList:
- indicator = self.GetIndicator(index, FieldName,Pcd)
- IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
- if IsArray:
- try:
- FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
- try:
- Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
- except Exception:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
- if isinstance(Value, str):
- CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
- CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
- else:
- if '[' in FieldName and ']' in FieldName:
- Index = int(FieldName.split('[')[1].split(']')[0])
- CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
- if ValueSize > 4:
- CApp = CApp + ' %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- else:
- CApp = CApp + ' %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + "}\n"
- return CApp
-
- @staticmethod
- def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):
- CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)
- return CApp
-
- def GenerateCommandLineValue(self, Pcd):
- CApp = "// Value in CommandLine\n"
- CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
- CApp = CApp + ' UINT32 FieldSize;\n'
- CApp = CApp + ' CHAR8 *Value;\n'
-
- pcddefaultvalue = Pcd.PcdValueFromComm
- for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:
- if not FieldList:
- continue
- if pcddefaultvalue and FieldList == pcddefaultvalue:
- IsArray = _IsFieldValueAnArray(FieldList)
- if IsArray:
- try:
- FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
- except BadExpression:
- EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
- (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
- Value, ValueSize = ParseFieldValue (FieldList)
-
- if isinstance(Value, str):
- CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- CApp = CApp + ' Value = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))
- CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
- continue
- for FieldName in FieldList:
- IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
- if IsArray:
- try:
- FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
- except:
- print("error")
- try:
- Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
- except Exception:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
- if isinstance(Value, str):
- CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
- CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
- else:
- if '[' in FieldName and ']' in FieldName:
- Index = int(FieldName.split('[')[1].split(']')[0])
- CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
- if ValueSize > 4:
- CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- else:
- CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + "}\n"
- return CApp
-
- def GenerateModuleScopeValue(self, Pcd):
- CApp = "// Value in Dsc Module scope \n"
- for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
-
- CApp = CApp + "void Assign_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, ModuleGuid,Pcd.BaseDatumType)
- CApp = CApp + ' UINT32 FieldSize;\n'
- CApp = CApp + ' CHAR8 *Value;\n'
- pcddefaultvalue, file_path,lineNo = Pcd.PcdValueFromComponents.get(ModuleGuid,(None,None,None))
-
- if pcddefaultvalue:
- IsArray = _IsFieldValueAnArray(pcddefaultvalue)
- if IsArray:
- try:
- FieldList = ValueExpressionEx(pcddefaultvalue, TAB_VOID)(True)
- except BadExpression:
- EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from %s Line %s: %s" %
- (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, file_path, lineNo, FieldList))
- Value, ValueSize = ParseFieldValue (FieldList)
-
- if isinstance(Value, str):
- CApp = CApp + ' Pcd = %s; // From %s Line %s \n' % (Value, file_path, lineNo)
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- CApp = CApp + ' Value = %s; // From %s Line %s.\n' % (DscBuildData.IntToCString(Value, ValueSize), file_path, lineNo)
- CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
-
-
- PcdFiledValue = Pcd.PcdFiledValueFromDscComponent.get(ModuleGuid)
- for index in PcdFiledValue:
- FieldList = PcdFiledValue[index]
- if not FieldList:
- continue
- for FieldName in FieldList:
- IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
- if IsArray:
- try:
- FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
- except:
- print("error")
- try:
- Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
- except Exception:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
- if isinstance(Value, str):
- CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
- CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
- else:
- if '[' in FieldName and ']' in FieldName:
- Index = int(FieldName.split('[')[1].split(']')[0])
- CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
- if ValueSize > 4:
- CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- else:
- CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + "}\n"
- return CApp
-
- @staticmethod
- def GenerateCommandLineValueStatement(Pcd):
- CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- return CApp
- def GenerateFdfValue(self,Pcd):
- CApp = "// Value in Fdf\n"
- CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.BaseDatumType)
- CApp = CApp + ' UINT32 FieldSize;\n'
- CApp = CApp + ' CHAR8 *Value;\n'
-
- pcddefaultvalue = Pcd.PcdValueFromFdf
- for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
- if not FieldList:
- continue
- if pcddefaultvalue and FieldList == pcddefaultvalue:
- IsArray = _IsFieldValueAnArray(FieldList)
- if IsArray:
- try:
- FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
- except BadExpression:
- EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
- (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
- Value, ValueSize = ParseFieldValue (FieldList)
-
- if isinstance(Value, str):
- CApp = CApp + ' Pcd = %s; // From Fdf \n' % (Value)
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- CApp = CApp + ' Value = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
- CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
- continue
- for FieldName in FieldList:
- IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
- if IsArray:
- try:
- FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
- except BadExpression:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
- (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
- except:
- print("error")
- try:
- Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
- except Exception:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
- if isinstance(Value, str):
- CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- elif IsArray:
- #
- # Use memcpy() to copy value into field
- #
- CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
- CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
- else:
- if '[' in FieldName and ']' in FieldName:
- Index = int(FieldName.split('[')[1].split(']')[0])
- CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
- if ValueSize > 4:
- CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- else:
- CApp = CApp + ' Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
- CApp = CApp + "}\n"
- return CApp
-
- @staticmethod
- def GenerateFdfValueStatement(Pcd):
- CApp = ' Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- return CApp
-
- @staticmethod
- def GenerateModuleValueStatement(module_guid, Pcd):
- CApp = " Assign_%s_%s_%s_Value(Pcd);\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, module_guid)
- return CApp
- def GenerateModuleScopeInitializeFunc(self,SkuName, Pcd, InitByteValue, CApp):
- for module_guid in Pcd.PcdFiledValueFromDscComponent:
- CApp = CApp + 'void\n'
- CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- CApp = CApp + ' void\n'
- CApp = CApp + ' )\n'
- CApp = CApp + '{\n'
- CApp = CApp + ' UINT32 Size;\n'
- CApp = CApp + ' UINT32 FieldSize;\n'
- CApp = CApp + ' CHAR8 *Value;\n'
- CApp = CApp + ' UINT32 OriginalSize;\n'
- CApp = CApp + ' VOID *OriginalPcd;\n'
-
- CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
-
- CApp = CApp + '\n'
-
- PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip())
- InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
- #
- # Get current PCD value and size
- #
- CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
-
- #
- # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
- # the correct value. For structures with a flexible array member, the flexible
- # array member is detected, and the size is based on the highest index used with
- # the flexible array member. The flexible array member must be the last field
- # in a structure. The size formula for this case is:
- # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
- #
- CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd,SkuName,TAB_DEFAULT_STORES_DEFAULT)
- if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
- CApp = CApp + ' OriginalSize = OriginalSize < sizeof(%s) * %d? OriginalSize:sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySize())
- CApp = CApp + ' Size = sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize())
-
- #
- # Allocate and zero buffer for the PCD
- # Must handle cases where current value is smaller, larger, or same size
- # Always keep that larger one as the current size
- #
- CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
- CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.BaseDatumType,)
- CApp = CApp + ' memset (Pcd, 0, Size);\n'
-
- #
- # Copy current PCD value into allocated buffer.
- #
- CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
-
- #
- # Assign field values in PCD
- #
- CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
-
- CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
- CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
- CApp = CApp + DscBuildData.GenerateModuleValueStatement(module_guid,Pcd)
- CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
- CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
-
- #
- # Set new PCD value and size
- #
- CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
-
- #
- # Free PCD
- #
- CApp = CApp + ' free (Pcd);\n'
- CApp = CApp + '}\n'
- CApp = CApp + '\n'
- return InitByteValue,CApp
-
- def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
- OverrideValues = {DefaultStore:{}}
- if Pcd.SkuOverrideValues:
- OverrideValues = Pcd.SkuOverrideValues[SkuName]
- if not OverrideValues:
- OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}
- for DefaultStoreName in OverrideValues:
- CApp = CApp + 'void\n'
- CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- CApp = CApp + ' void\n'
- CApp = CApp + ' )\n'
- CApp = CApp + '{\n'
- CApp = CApp + ' UINT32 Size;\n'
- CApp = CApp + ' UINT32 FieldSize;\n'
- CApp = CApp + ' CHAR8 *Value;\n'
- CApp = CApp + ' UINT32 OriginalSize;\n'
- CApp = CApp + ' VOID *OriginalPcd;\n'
-
- CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
-
- CApp = CApp + '\n'
-
- PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip())
-
- InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
-
- #
- # Get current PCD value and size
- #
- CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
-
- #
- # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
- # the correct value. For structures with a flexible array member, the flexible
- # array member is detected, and the size is based on the highest index used with
- # the flexible array member. The flexible array member must be the last field
- # in a structure. The size formula for this case is:
- # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
- #
- CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd,SkuName,DefaultStoreName)
- if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
- CApp = CApp + ' OriginalSize = OriginalSize < sizeof(%s) * %d? OriginalSize:sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySize())
- CApp = CApp + ' Size = sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize())
-
- #
- # Allocate and zero buffer for the PCD
- # Must handle cases where current value is smaller, larger, or same size
- # Always keep that larger one as the current size
- #
- CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
- CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.BaseDatumType,)
- CApp = CApp + ' memset (Pcd, 0, Size);\n'
-
- #
- # Copy current PCD value into allocated buffer.
- #
- CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
-
- #
- # Assign field values in PCD
- #
- CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
- if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
- self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
- for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
- storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]
- for defaultstorenameitem in storeset:
- CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
- CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)
- if skuname == SkuName:
- break
- else:
- CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
- CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
- CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
- CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
- #
- # Set new PCD value and size
- #
- CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
-
- #
- # Free PCD
- #
- CApp = CApp + ' free (Pcd);\n'
- CApp = CApp + '}\n'
- CApp = CApp + '\n'
- return InitByteValue, CApp
-
- def GenerateArrayAssignment(self, Pcd):
- CApp = ""
- if not Pcd:
- return CApp
- Demesion = ""
- for d in Pcd.Capacity:
- Demesion += "[]"
-
- Value = Pcd.DefaultValueFromDec
- if "{CODE(" in Pcd.DefaultValueFromDec:
- realvalue = Pcd.DefaultValueFromDec.strip()[6:-2] # "{CODE(").rstrip(")}"
- CApp += "static %s %s_%s_INIT_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demesion,realvalue)
-
- if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
- for skuname in Pcd.SkuInfoList:
- skuinfo = Pcd.SkuInfoList[skuname]
- if skuinfo.VariableName:
- for defaultstore in skuinfo.DefaultStoreDict:
- pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, skuname, defaultstore)
- if pcddscrawdefaultvalue:
- Value = skuinfo.DefaultStoreDict[defaultstore]
- if "{CODE(" in Value:
- realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
- CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Demesion,realvalue)
- else:
- pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, skuname, TAB_DEFAULT_STORES_DEFAULT)
- if pcddscrawdefaultvalue:
- Value = skuinfo.DefaultValue
- if "{CODE(" in Value:
- realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
- CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Demesion,realvalue)
- else:
- pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
- if pcddscrawdefaultvalue:
- if "{CODE(" in Pcd.DefaultValue:
- realvalue = Pcd.DefaultValue.strip()[6:-2] # "{CODE(").rstrip(")}"
- CApp += "static %s %s_%s_DEFAULT_STANDARD_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demesion,realvalue)
-
- return CApp
-
- def SkuOverrideValuesEmpty(self,OverrideValues):
- if not OverrideValues:
- return True
- for key in OverrideValues:
- if OverrideValues[key]:
- return False
- return True
-
- def ParseCCFlags(self, ccflag):
- ccflags = set()
- ccflaglist = ccflag.split(" ")
- i = 0
- while i < len(ccflaglist):
- item = ccflaglist[i].strip()
- if item in (r"/D", r"/U","-D","-U"):
- ccflags.add(" ".join((ccflaglist[i],ccflaglist[i+1])))
- i = i+1
- elif item.startswith((r"/D", r"/U","-D","-U")):
- ccflags.add(item)
- i +=1
- return ccflags
-
- def GetStructurePcdSet (self, OutputValueFile):
- if not os.path.isfile(OutputValueFile):
- EdkLogger.error("GetStructurePcdSet", FILE_NOT_FOUND, "Output.txt doesn't exist", ExtraData=OutputValueFile)
- return []
- File = open (OutputValueFile, 'r')
- FileBuffer = File.readlines()
- File.close()
-
- #start update structure pcd final value
- StructurePcdSet = []
- for Pcd in FileBuffer:
- PcdValue = Pcd.split ('|')
- PcdInfo = PcdValue[0].split ('.')
- StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
- return StructurePcdSet
-
- def GetBuildOptionsValueList(self):
- CC_FLAGS = LinuxCFLAGS
- if sys.platform == "win32":
- CC_FLAGS = WindowsCFLAGS
- BuildOptions = OrderedDict()
- for Options in self.BuildOptions:
- if Options[2] != EDKII_NAME:
- continue
- Family = Options[0]
- if Family and Family != self.ToolChainFamily:
- continue
- Target, Tag, Arch, Tool, Attr = Options[1].split("_")
- if Tool != 'CC':
- continue
- if Attr != "FLAGS":
- continue
- if Target == TAB_STAR or Target == self._Target:
- if Tag == TAB_STAR or Tag == self._Toolchain:
- if 'COMMON' not in BuildOptions:
- BuildOptions['COMMON'] = set()
- if Arch == TAB_STAR:
- BuildOptions['COMMON']|= self.ParseCCFlags(self.BuildOptions[Options])
- if Arch in self.SupArchList:
- if Arch not in BuildOptions:
- BuildOptions[Arch] = set()
- BuildOptions[Arch] |= self.ParseCCFlags(self.BuildOptions[Options])
-
- if BuildOptions:
- ArchBuildOptions = {arch:flags for arch,flags in BuildOptions.items() if arch != 'COMMON'}
- if len(ArchBuildOptions.keys()) == 1:
- BuildOptions['COMMON'] |= (list(ArchBuildOptions.values())[0])
- elif len(ArchBuildOptions.keys()) > 1:
- CommonBuildOptions = reduce(lambda x,y: x&y, ArchBuildOptions.values())
- BuildOptions['COMMON'] |= CommonBuildOptions
- ValueList = [item for item in BuildOptions['COMMON'] if item.startswith((r"/U","-U"))]
- ValueList.extend([item for item in BuildOptions['COMMON'] if item.startswith((r"/D", "-D"))])
- CC_FLAGS += " ".join(ValueList)
- return CC_FLAGS
-
-
- def GenerateByteArrayValue (self, StructuredPcds):
- #
- # Generate/Compile/Run C application to determine if there are any flexible array members
- #
- if not StructuredPcds:
- return
-
- StructuredPcdsData = {}
- StoredStructuredPcdObjectPaths = {}
- SkipPcdValueInit = False
-
- CC_FLAGS = self.GetBuildOptionsValueList()
-
- for PcdName in StructuredPcds:
- Pcd = StructuredPcds[PcdName]
- TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
- TokenCName = Pcd.TokenCName
-
- # Create a key using TokenSpaceGuidCName and TokenCName
- StructuredPcdsData[f"{TokenSpaceGuidCName}_{TokenCName}"] = {
- "DefaultValueFromDec": Pcd.DefaultValueFromDec,
- "DefaultValues": Pcd.DefaultValues,
- "PcdFieldValueFromComm": Pcd.PcdFieldValueFromComm,
- "PcdFieldValueFromFdf": Pcd.PcdFieldValueFromFdf,
- "DefaultFromDSC": Pcd.DefaultFromDSC,
- "PcdFiledValueFromDscComponent": Pcd.PcdFiledValueFromDscComponent
- }
-
- # Store the CC Flags
- StructuredPcdsData["CC_FLAGS"] = CC_FLAGS
- #
- # If the output path doesn't exists then create it
- #
- if not os.path.exists(self.OutputPath):
- os.makedirs(self.OutputPath)
-
- StructuredPcdsDataPath = os.path.join(self.OutputPath, self._Arch, StructuredPcdsDataName)
- PcdRecordOutputValueFile = os.path.join(self.OutputPath, self._Arch, 'Output.txt')
-
- if not os.path.exists(os.path.dirname(StructuredPcdsDataPath)):
- os.makedirs(os.path.dirname(StructuredPcdsDataPath))
- #
- # Check if the StructuredPcdsData.json exists or not
- # if exits then it might be a incremental build then check if the StructuredPcdsData has been changed or not.
- # if changed then proceed further, if not changed then return the stored data from earlier build
- #
- if os.path.isfile(StructuredPcdsDataPath):
- with open(StructuredPcdsDataPath, 'r') as file:
- StoredStructuredPcdsData = json.load(file)
- # OBJECTS will have the modified time, which needs to be checked later
- StoredStructuredPcdObjectPaths = StoredStructuredPcdsData.pop("OBJECTS", {})
-
- if StructuredPcdsData == StoredStructuredPcdsData:
- SkipPcdValueInit = True
- for filename, file_mtime in StoredStructuredPcdObjectPaths.items():
- f_mtime = os.path.getmtime(filename)
- #
- # check if the include_file are modified or not,
- # if modified then generate the PcdValueInit
- #
- if f_mtime != file_mtime:
- SkipPcdValueInit = False
- break
-
- if SkipPcdValueInit:
- return self.GetStructurePcdSet(PcdRecordOutputValueFile)
-
- InitByteValue = ""
- CApp = PcdMainCHeader
-
- IncludeFiles = set()
- for PcdName in StructuredPcds:
- Pcd = StructuredPcds[PcdName]
- for IncludeFile in Pcd.StructuredPcdIncludeFile:
- if IncludeFile not in IncludeFiles:
- IncludeFiles.add(IncludeFile)
- CApp = CApp + '#include <%s>\n' % (IncludeFile)
- CApp = CApp + '\n'
- for Pcd in StructuredPcds.values():
- CApp = CApp + self.GenerateArrayAssignment(Pcd)
- for PcdName in sorted(StructuredPcds.keys()):
- Pcd = StructuredPcds[PcdName]
-
- #create void void Cal_tocken_cname_Size functions
- CApp = CApp + self.GenerateSizeFunction(Pcd)
-
- #create void Assign_ functions
-
- # From DEC
- CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
- # From Fdf
- CApp = CApp + self.GenerateFdfValue(Pcd)
- # From CommandLine
- CApp = CApp + self.GenerateCommandLineValue(Pcd)
-
- # From Dsc Global setting
- if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
- self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
- CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
- else:
- for SkuName in self.SkuIdMgr.SkuOverrideOrder():
- if SkuName not in Pcd.SkuOverrideValues:
- continue
- for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
- CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
-
- # From Dsc module scope setting
- CApp = CApp + self.GenerateModuleScopeValue(Pcd)
-
- #create Initialize_ functions
- if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
- self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
- InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
- InitByteValue, CApp = self.GenerateModuleScopeInitializeFunc(self.SkuIdMgr.SystemSkuId,Pcd,InitByteValue,CApp)
- else:
- for SkuName in self.SkuIdMgr.SkuOverrideOrder():
- if SkuName not in Pcd.SkuOverrideValues:
- continue
- for DefaultStoreName in Pcd.DefaultStoreName:
- Pcd = StructuredPcds[PcdName]
- InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
-
- CApp = CApp + 'VOID\n'
- CApp = CApp + 'PcdEntryPoint(\n'
- CApp = CApp + ' VOID\n'
- CApp = CApp + ' )\n'
- CApp = CApp + '{\n'
- for Pcd in StructuredPcds.values():
- if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
- CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
- CApp += " Initialize_%s_%s_%s_%s();\n" % (ModuleGuid,TAB_DEFAULT_STORES_DEFAULT ,Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- else:
- for SkuName in self.SkuIdMgr.SkuOverrideOrder():
- if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
- continue
- for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
- CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
- CApp = CApp + '}\n'
-
- CApp = CApp + PcdMainCEntry + '\n'
-
- CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
- SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
-
- # start generating makefile
- MakeApp = PcdMakefileHeader
- if sys.platform == "win32":
- MakeApp = MakeApp + 'APPFILE = %s\\%s.exe\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\\%s.obj %s.obj\n' % (self.OutputPath, PcdValueInitName, os.path.join(self.OutputPath, PcdValueCommonName)) + 'INC = '
- else:
- MakeApp = MakeApp + PcdGccMakefile
- MakeApp = MakeApp + 'APPFILE = %s/%s\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o %s.o\n' % (self.OutputPath, PcdValueInitName, os.path.join(self.OutputPath, PcdValueCommonName)) + \
- 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'TOOL_INCLUDE +='
-
- IncSearchList = []
- PlatformInc = OrderedDict()
- for Cache in self._Bdb._CACHE_.values():
- if Cache.MetaFile.Ext.lower() != '.dec':
- continue
- if Cache.Includes:
- if str(Cache.MetaFile.Path) not in PlatformInc:
- PlatformInc[str(Cache.MetaFile.Path)] = []
- PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
- PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
-
- PcdDependDEC = []
- for Pcd in StructuredPcds.values():
- for PackageDec in Pcd.PackageDecs:
- Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
- if not os.path.exists(Package):
- EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
- if Package not in PcdDependDEC:
- PcdDependDEC.append(Package)
-
- if PlatformInc and PcdDependDEC:
- for pkg in PcdDependDEC:
- if pkg in PlatformInc:
- for inc in PlatformInc[pkg]:
- #
- # Get list of files in potential -I include path
- #
- FileList = os.listdir (str(inc))
- #
- # Skip -I include path if one of the include files required
- # by PcdValueInit.c are present in the include paths from
- # the DEC file. PcdValueInit.c must use the standard include
- # files from the host compiler.
- #
- if 'stdio.h' in FileList:
- continue
- if 'stdlib.h' in FileList:
- continue
- if 'string.h' in FileList:
- continue
- MakeApp += '-I' + str(inc) + ' '
- IncSearchList.append(inc)
- MakeApp = MakeApp + '\n'
-
- MakeApp += CC_FLAGS
-
- if sys.platform == "win32":
- MakeApp = MakeApp + PcdMakefileEnd
- MakeApp = MakeApp + AppTarget % ("""\tcopy $(APPLICATION) $(APPFILE) /y """)
- else:
- MakeApp = MakeApp + AppTarget % ("""\tcp -p $(APPLICATION) $(APPFILE) """)
- MakeApp = MakeApp + '\n'
- IncludeFileFullPaths = []
- for includefile in IncludeFiles:
- for includepath in IncSearchList:
- includefullpath = os.path.join(str(includepath), includefile)
- if os.path.exists(includefullpath):
- IncludeFileFullPaths.append(os.path.normpath(includefullpath))
- break
- SearchPathList = []
- SearchPathList.append(os.path.normpath(mws.join(GlobalData.gGlobalDefines["EDK_TOOLS_PATH"], "BaseTools/Source/C/Include")))
- SearchPathList.append(os.path.normpath(mws.join(GlobalData.gGlobalDefines["EDK_TOOLS_PATH"], "BaseTools/Source/C/Common")))
- SearchPathList.extend(str(item) for item in IncSearchList)
- IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)
- StructuredPcdsData["OBJECTS"] = {}
- for include_file in IncFileList:
- StructuredPcdsData["OBJECTS"][include_file] = os.path.getmtime(include_file)
- MakeApp += "$(OBJECTS) : %s\n" % include_file
- if sys.platform == "win32":
- PcdValueCommonPath = os.path.normpath(mws.join(GlobalData.gGlobalDefines["EDK_TOOLS_PATH"], "Source\\C\\Common\\PcdValueCommon.c"))
- MakeApp = MakeApp + '%s\\PcdValueCommon.c : %s\n' % (self.OutputPath, PcdValueCommonPath)
- MakeApp = MakeApp + '\tcopy /y %s $@\n' % (PcdValueCommonPath)
- else:
- PcdValueCommonPath = os.path.normpath(mws.join(GlobalData.gGlobalDefines["EDK_TOOLS_PATH"], "Source/C/Common/PcdValueCommon.c"))
- MakeApp = MakeApp + '%s/PcdValueCommon.c : %s\n' % (self.OutputPath, PcdValueCommonPath)
- MakeApp = MakeApp + '\tcp -p -f %s %s/PcdValueCommon.c\n' % (PcdValueCommonPath, self.OutputPath)
- MakeFileName = os.path.join(self.OutputPath, 'Makefile')
- MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
- SaveFileOnChange(MakeFileName, MakeApp, False)
-
- # start generating input file
- InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
- OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
- SaveFileOnChange(InputValueFile, InitByteValue, False)
-
- Dest_PcdValueInitExe = PcdValueInitName
- if not sys.platform == "win32":
- Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName)
- else:
- Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName) +".exe"
-
- #start building the structure pcd value tool
- Messages = ''
- if sys.platform == "win32":
- MakeCommand = 'nmake -f %s' % (MakeFileName)
- returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
- Messages = StdOut
- else:
- MakeCommand = 'make -f %s' % (MakeFileName)
- returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
- Messages = StdErr
-
- EdkLogger.verbose ('%s\n%s\n%s' % (MakeCommand, StdOut, StdErr))
- Messages = Messages.split('\n')
- MessageGroup = []
- if returncode != 0:
- CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
- File = open (CAppBaseFileName + '.c', 'r')
- FileData = File.readlines()
- File.close()
- for Message in Messages:
- if " error" in Message or "warning" in Message:
- try:
- FileInfo = Message.strip().split('(')
- if len (FileInfo) > 1:
- FileName = FileInfo [0]
- FileLine = FileInfo [1].split (')')[0]
- else:
- FileInfo = Message.strip().split(':')
- if len(FileInfo) < 2:
- continue
- FileName = FileInfo [0]
- FileLine = FileInfo [1]
- except:
- continue
- if "PcdValueInit.c" not in FileName:
- continue
- if FileLine.isdigit():
- error_line = FileData[int (FileLine) - 1]
- if r"//" in error_line:
- c_line, dsc_line = error_line.split(r"//")
- else:
- dsc_line = error_line
- message_itmes = Message.split(":")
- Index = 0
- if "PcdValueInit.c" not in Message:
- if not MessageGroup:
- MessageGroup.append(Message)
- break
- else:
- for item in message_itmes:
- if "PcdValueInit.c" in item:
- Index = message_itmes.index(item)
- message_itmes[Index] = dsc_line.strip()
- break
- MessageGroup.append(":".join(message_itmes[Index:]).strip())
- continue
- else:
- MessageGroup.append(Message)
- if MessageGroup:
- EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
- else:
- EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s\n%s\n%s' % (MakeCommand, StdOut, StdErr))
-
- #start executing the structure pcd value tool
- if DscBuildData.NeedUpdateOutput(OutputValueFile, Dest_PcdValueInitExe, InputValueFile):
- Command = Dest_PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
- returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
- EdkLogger.verbose ('%s\n%s\n%s' % (Command, StdOut, StdErr))
- if returncode != 0:
- EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s\n%s\n%s\n' % (Command, StdOut, StdErr))
-
- #
- # In 1st build create the StructuredPcdsData.json
- # update the record as PCD Input has been changed if its incremental build
- #
- with open(StructuredPcdsDataPath, 'w') as file:
- json.dump(StructuredPcdsData, file, indent=2)
-
- # Copy update output file for each Arch
- shutil.copyfile(OutputValueFile, PcdRecordOutputValueFile)
-
- #start update structure pcd final value
- return self.GetStructurePcdSet(OutputValueFile)
-
- @staticmethod
- def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):
- if not os.path.exists(OutputFile):
- return True
- if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
- return True
- if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
- return True
- return False
-
- ## Retrieve dynamic PCD settings
- #
- # @param Type PCD type
- #
- # @retval a dict object contains settings of given PCD type
- #
- def _GetDynamicPcd(self, Type):
-
-
- Pcds = OrderedDict()
- #
- # tdict is a special dict kind of type, used for selecting correct
- # PCD settings for certain ARCH and SKU
- #
- PcdDict = tdict(True, 4)
- PcdList = []
- # Find out all possible PCD candidates for self._Arch
- RecordList = self._RawData[Type, self._Arch]
- AvailableSkuIdSet = copy.copy(self.SkuIds)
-
-
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
- SkuName = SkuName.upper()
- SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
- if SkuName not in AvailableSkuIdSet:
- EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
- File=self.MetaFile, Line=Dummy5)
- if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
- PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
- PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
-
- # Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
-
- Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
- if Setting is None:
- continue
-
- PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
- if MaxDatumSize:
- if int(MaxDatumSize, 0) > 0xFFFF:
- EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
- File=self.MetaFile, Line=Dummy4)
- if int(MaxDatumSize, 0) < 0:
- EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
- File=self.MetaFile, Line=Dummy4)
- SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
- if (PcdCName, TokenSpaceGuid) in Pcds:
- pcdObject = Pcds[PcdCName, TokenSpaceGuid]
- pcdObject.SkuInfoList[SkuName] = SkuInfo
- if MaxDatumSize.strip():
- CurrentMaxSize = int(MaxDatumSize.strip(), 0)
- else:
- CurrentMaxSize = 0
- if pcdObject.MaxDatumSize:
- PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
- else:
- PcdMaxSize = 0
- if CurrentMaxSize > PcdMaxSize:
- pcdObject.MaxDatumSize = str(CurrentMaxSize)
- else:
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- PcdValue,
- '',
- MaxDatumSize,
- OrderedDict({SkuName : SkuInfo}),
- False,
- None,
- IsDsc=True)
-
- if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
- Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
- Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
- Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
- Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4)
-
- for pcd in Pcds.values():
- pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
- # Only fix the value while no value provided in DSC file.
- for sku in pcd.SkuInfoList.values():
- if not sku.DefaultValue:
- sku.DefaultValue = pcdDecObject.DefaultValue
- if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
- valuefromDec = pcdDecObject.DefaultValue
- SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)
- pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
- elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
- pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
- del pcd.SkuInfoList[TAB_COMMON]
- elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
- del pcd.SkuInfoList[TAB_COMMON]
-
- list(map(self.FilterSkuSettings, Pcds.values()))
-
- return Pcds
-
- def FilterSkuSettings(self, PcdObj):
-
- if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
- if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:
- PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]
- PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
- PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT
- PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'
-
- elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
- PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}
-
- return PcdObj
-
- @staticmethod
- def CompareVarAttr(Attr1, Attr2):
- if not Attr1 or not Attr2: # for empty string
- return True
- Attr1s = [attr.strip() for attr in Attr1.split(",")]
- Attr1Set = set(Attr1s)
- Attr2s = [attr.strip() for attr in Attr2.split(",")]
- Attr2Set = set(Attr2s)
- if Attr2Set == Attr1Set:
- return True
- else:
- return False
-
- def CompletePcdValues(self, PcdSet):
- Pcds = OrderedDict()
- DefaultStoreObj = DefaultStore(self._GetDefaultStores())
- SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}
- DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)
- for PcdCName, TokenSpaceGuid in PcdSet:
- PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
-
- if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
- self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
- Pcds[PcdCName, TokenSpaceGuid]= PcdObj
- continue
- PcdType = PcdObj.Type
- if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
- for skuid in PcdObj.SkuInfoList:
- skuobj = PcdObj.SkuInfoList[skuid]
- mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
- for defaultstorename in DefaultStores:
- if defaultstorename not in skuobj.DefaultStoreDict:
- skuobj.DefaultStoreDict[defaultstorename] = skuobj.DefaultStoreDict[mindefaultstorename]
- skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
- for skuname, skuid in SkuIds.items():
- if skuname not in PcdObj.SkuInfoList:
- nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
- while nextskuid not in PcdObj.SkuInfoList:
- nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
- PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
- PcdObj.SkuInfoList[skuname].SkuId = skuid
- PcdObj.SkuInfoList[skuname].SkuIdName = skuname
- if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
- PcdObj.DefaultValue = list(PcdObj.SkuInfoList.values())[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue
- Pcds[PcdCName, TokenSpaceGuid]= PcdObj
- return Pcds
- ## Retrieve dynamic HII PCD settings
- #
- # @param Type PCD type
- #
- # @retval a dict object contains settings of given PCD type
- #
- def _GetDynamicHiiPcd(self, Type):
-
- VariableAttrs = {}
-
- Pcds = OrderedDict()
- UserDefinedDefaultStores = []
- #
- # tdict is a special dict kind of type, used for selecting correct
- # PCD settings for certain ARCH and SKU
- #
- PcdDict = tdict(True, 5)
- PcdList = []
- RecordList = self._RawData[Type, self._Arch]
- # Find out all possible PCD candidates for self._Arch
- AvailableSkuIdSet = copy.copy(self.SkuIds)
- DefaultStoresDefine = self._GetDefaultStores()
-
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:
- SkuName = SkuName.upper()
- SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
- DefaultStore = DefaultStore.upper()
- if DefaultStore == TAB_COMMON:
- DefaultStore = TAB_DEFAULT_STORES_DEFAULT
- else:
- #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
- UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))
- if SkuName not in AvailableSkuIdSet:
- EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
- File=self.MetaFile, Line=Dummy5)
- if DefaultStore not in DefaultStoresDefine:
- EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
- File=self.MetaFile, Line=Dummy5)
- if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5) not in PcdList:
- PcdList.append((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
- PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
-
-
- # Remove redundant PCD candidates, per the ARCH and SKU
- for index,(PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4) in enumerate(PcdList):
-
- Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]
- if Setting is None:
- continue
- VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
-
- rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
- if not rt:
- EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
- ExtraData="[%s]" % VarAttribute)
- ExceedMax = False
- FormatCorrect = True
- if VariableOffset.isdigit():
- if int(VariableOffset, 10) > 0xFFFF:
- ExceedMax = True
- elif variablePattern.match(VariableOffset):
- if int(VariableOffset, 16) > 0xFFFF:
- ExceedMax = True
- # For Offset written in "A.B"
- elif VariableOffset.find('.') > -1:
- VariableOffsetList = VariableOffset.split(".")
- if not (len(VariableOffsetList) == 2
- and IsValidWord(VariableOffsetList[0])
- and IsValidWord(VariableOffsetList[1])):
- FormatCorrect = False
- else:
- FormatCorrect = False
- if not FormatCorrect:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
-
- if ExceedMax:
- EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
- if (VariableName, VariableGuid) not in VariableAttrs:
- VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
- else:
- if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
- EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))
-
- pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
- if (PcdCName, TokenSpaceGuid) in Pcds:
- pcdObject = Pcds[PcdCName, TokenSpaceGuid]
- if SkuName in pcdObject.SkuInfoList:
- Skuitem = pcdObject.SkuInfoList[SkuName]
- Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
- else:
- SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
- pcdObject.SkuInfoList[SkuName] = SkuInfo
- else:
- SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
- PcdClassObj = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- '',
- DefaultValue,
- '',
- '',
- OrderedDict({SkuName : SkuInfo}),
- False,
- None,
- pcdDecObject.validateranges,
- pcdDecObject.validlists,
- pcdDecObject.expressions,
- IsDsc=True)
- if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:
- PcdClassObj.UserDefinedDefaultStoresFlag = True
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
-
- Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = index
- if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
- Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
- Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
- Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
- Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][DefaultStore] = (self.MetaFile.File,Dummy4)
- for pcd in Pcds.values():
- pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
- pcd.DatumType = pcdDecObject.DatumType
- # Only fix the value while no value provided in DSC file.
- for sku in pcd.SkuInfoList.values():
- if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
- sku.HiiDefaultValue = pcdDecObject.DefaultValue
- for default_store in sku.DefaultStoreDict:
- sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
- pcd.DefaultValue = pcdDecObject.DefaultValue
- if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
- SkuInfoObj = list(pcd.SkuInfoList.values())[0]
- valuefromDec = pcdDecObject.DefaultValue
- SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})
- pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
- elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
- pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
- del pcd.SkuInfoList[TAB_COMMON]
- elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
- del pcd.SkuInfoList[TAB_COMMON]
-
- if pcd.MaxDatumSize.strip():
- MaxSize = int(pcd.MaxDatumSize, 0)
- else:
- MaxSize = 0
- if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
- for (_, skuobj) in pcd.SkuInfoList.items():
- datalen = 0
- skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
- datalen = len(skuobj.HiiDefaultValue.split(","))
- if datalen > MaxSize:
- MaxSize = datalen
- for defaultst in skuobj.DefaultStoreDict:
- skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
- pcd.DefaultValue = StringToArray(pcd.DefaultValue)
- pcd.MaxDatumSize = str(MaxSize)
- rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)
- if not rt:
- invalidpcd = ",".join(invalidhii)
- EdkLogger.error('build', PCD_VARIABLE_INFO_ERROR, Message='The same HII PCD must map to the same EFI variable for all SKUs', File=self.MetaFile, ExtraData=invalidpcd)
-
- list(map(self.FilterSkuSettings, Pcds.values()))
-
- return Pcds
-
- @staticmethod
- def CheckVariableNameAssignment(Pcds):
- invalidhii = []
- for pcdname in Pcds:
- pcd = Pcds[pcdname]
- varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())
- if len(varnameset) > 1:
- invalidhii.append(".".join((pcdname[1], pcdname[0])))
- if len(invalidhii):
- return False, invalidhii
- else:
- return True, []
- ## Retrieve dynamic VPD PCD settings
- #
- # @param Type PCD type
- #
- # @retval a dict object contains settings of given PCD type
- #
- def _GetDynamicVpdPcd(self, Type):
-
-
- Pcds = OrderedDict()
- #
- # tdict is a special dict kind of type, used for selecting correct
- # PCD settings for certain ARCH and SKU
- #
- PcdDict = tdict(True, 4)
- PcdList = []
-
- # Find out all possible PCD candidates for self._Arch
- RecordList = self._RawData[Type, self._Arch]
- AvailableSkuIdSet = copy.copy(self.SkuIds)
-
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
- SkuName = SkuName.upper()
- SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
- if SkuName not in AvailableSkuIdSet:
- EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
- File=self.MetaFile, Line=Dummy5)
- if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
- PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
- PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
-
- # Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
- Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
- if Setting is None:
- continue
- #
- # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
- # For the Integer & Boolean type, the optional data can only be InitialValue.
- # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
- # until the DEC parser has been called.
- #
- VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
- if MaxDatumSize:
- if int(MaxDatumSize, 0) > 0xFFFF:
- EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
- File=self.MetaFile, Line=Dummy4)
- if int(MaxDatumSize, 0) < 0:
- EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
- File=self.MetaFile, Line=Dummy4)
- SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
- if (PcdCName, TokenSpaceGuid) in Pcds:
- pcdObject = Pcds[PcdCName, TokenSpaceGuid]
- pcdObject.SkuInfoList[SkuName] = SkuInfo
- if MaxDatumSize.strip():
- CurrentMaxSize = int(MaxDatumSize.strip(), 0)
- else:
- CurrentMaxSize = 0
- if pcdObject.MaxDatumSize:
- PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
- else:
- PcdMaxSize = 0
- if CurrentMaxSize > PcdMaxSize:
- pcdObject.MaxDatumSize = str(CurrentMaxSize)
- else:
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- '',
- InitialValue,
- '',
- MaxDatumSize,
- OrderedDict({SkuName : SkuInfo}),
- False,
- None,
- IsDsc=True)
-
- if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
- Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
- Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
- Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
- Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4)
- for pcd in Pcds.values():
- pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
- pcd.DatumType = pcdDecObject.DatumType
- # Only fix the value while no value provided in DSC file.
- for sku in pcd.SkuInfoList.values():
- if not sku.DefaultValue:
- sku.DefaultValue = pcdDecObject.DefaultValue
- if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
- SkuInfoObj = list(pcd.SkuInfoList.values())[0]
- valuefromDec = pcdDecObject.DefaultValue
- SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
- pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
- elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
- pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
- del pcd.SkuInfoList[TAB_COMMON]
- elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
- del pcd.SkuInfoList[TAB_COMMON]
-
- #For the same one VOID* pcd, if the default value type of one SKU is "Unicode string",
- #the other SKUs are "OtherVOID*"(ASCII string or byte array),Then convert "Unicode string" to "byte array".
- for pcd in Pcds.values():
- PcdValueTypeSet = set()
- for sku in pcd.SkuInfoList.values():
- PcdValueTypeSet.add("UnicodeString" if sku.DefaultValue.startswith(('L"',"L'")) else "OtherVOID*")
- if len(PcdValueTypeSet) > 1:
- for sku in pcd.SkuInfoList.values():
- sku.DefaultValue = StringToArray(sku.DefaultValue) if sku.DefaultValue.startswith(('L"',"L'")) else sku.DefaultValue
-
- list(map(self.FilterSkuSettings, Pcds.values()))
- return Pcds
-
- ## Add external modules
- #
- # The external modules are mostly those listed in FDF file, which don't
- # need "build".
- #
- # @param FilePath The path of module description file
- #
- def AddModule(self, FilePath):
- FilePath = NormPath(FilePath)
- if FilePath not in self.Modules:
- Module = ModuleBuildClassObject()
- Module.MetaFile = FilePath
- self.Modules.append(Module)
-
- @property
- def ToolChainFamily(self):
- self._ToolChainFamily = TAB_COMPILER_MSFT
- TargetObj = TargetTxtDict()
- TargetTxt = TargetObj.Target
- BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, gDefaultTargetTxtFile))
- if os.path.isfile(BuildConfigurationFile) == True:
- ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
- if ToolDefinitionFile == '':
- ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', gDefaultToolsDefFile))
- if os.path.isfile(ToolDefinitionFile) == True:
- ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
- ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase
- if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
- or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
- or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
- self._ToolChainFamily = TAB_COMPILER_MSFT
- else:
- self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
- return self._ToolChainFamily
-
- ## Add external PCDs
- #
- # The external PCDs are mostly those listed in FDF file to specify address
- # or offset information.
- #
- # @param Name Name of the PCD
- # @param Guid Token space guid of the PCD
- # @param Value Value of the PCD
- #
- def AddPcd(self, Name, Guid, Value):
- if (Name, Guid) not in self.Pcds:
- self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
- self.Pcds[Name, Guid].DefaultValue = Value
-
- @property
- def DecPcds(self):
- if self._DecPcds is None:
- FdfInfList = []
- if GlobalData.gFdfParser:
- FdfInfList = GlobalData.gFdfParser.Profile.InfList
- PkgSet = set()
- for Inf in FdfInfList:
- ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
- if ModuleFile in self._Modules:
- continue
- ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
- PkgSet.update(ModuleData.Packages)
- if self.Packages:
- PkgSet.update(self.Packages)
- self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
- self._GuidDict.update(GlobalData.gPlatformPcds)
- return self._DecPcds
+## @file
+# This file is used to create a database used by build tool
+#
+# Copyright (c) 2008 - 2020, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+## Platform build information from DSC file
+#
+# This class is used to retrieve information stored in database and convert them
+# into PlatformBuildClassObject form for easier use for AutoGen.
+#
+from __future__ import print_function
+from __future__ import absolute_import
+from Common.StringUtils import *
+from Common.DataType import *
+from Common.Misc import *
+from types import *
+from Common.Expression import *
+from CommonDataClass.CommonClass import SkuInfoClass
+from Common.TargetTxtClassObject import TargetTxtDict,gDefaultTargetTxtFile
+from Common.ToolDefClassObject import ToolDefDict,gDefaultToolsDefFile
+from .MetaDataTable import *
+from .MetaFileTable import *
+from .MetaFileParser import *
+
+from .WorkspaceCommon import GetDeclaredPcd
+from Common.Misc import AnalyzeDscPcd
+from Common.Misc import ProcessDuplicatedInf,RemoveCComments,ArrayIndex
+import re
+from Common.Parsing import IsValidWord
+from Common.VariableAttributes import VariableAttributes
+import Common.GlobalData as GlobalData
+import subprocess
+from functools import reduce
+from Common.Misc import SaveFileOnChange
+from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
+from collections import OrderedDict, defaultdict
+import json
+import shutil
+
+def _IsFieldValueAnArray (Value):
+ Value = Value.strip()
+ if Value.startswith(TAB_GUID) and Value.endswith(')'):
+ return True
+ if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:
+ return True
+ if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
+ return True
+ if Value[0] == '{' and Value[-1] == '}':
+ return True
+ if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
+ return True
+ if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
+ return True
+ return False
+
+PcdValueInitName = 'PcdValueInit'
+PcdValueCommonName = 'PcdValueCommon'
+StructuredPcdsDataName = 'StructuredPcdsData.json'
+
+PcdMainCHeader = '''
+/**
+ DO NOT EDIT
+ FILE auto-generated
+**/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <PcdValueCommon.h>
+'''
+
+PcdMainCEntry = '''
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ return PcdValueMain (argc, argv);
+}
+'''
+
+PcdMakefileHeader = '''
+#
+# DO NOT EDIT
+# This file is auto-generated by build utility
+#
+
+'''
+
+WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
+LinuxCFLAGS = 'CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
+PcdMakefileEnd = r'''
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
+'''
+
+AppTarget = '''
+all: $(APPFILE)
+$(APPLICATION): $(OBJECTS)
+$(APPFILE): $(APPLICATION)
+%s
+'''
+
+PcdGccMakefile = '''
+MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
+LIBS = -lCommon
+'''
+
+variablePattern = re.compile(r'[\t\s]*0[xX][a-fA-F0-9]+$')
+SkuIdPattern = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
+## regular expressions for finding decimal and hex numbers
+Pattern = re.compile(r'^[1-9]\d*|0$')
+HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
+## Regular expression for finding header file inclusions
+from AutoGen.GenMake import gIncludePattern
+
+## Find dependencies for one source file
+#
+# By searching recursively "#include" directive in file, find out all the
+# files needed by given source file. The dependecies will be only searched
+# in given search path list.
+#
+# @param SearchPathList The list of search path
+#
+# @retval list The list of files the given source file depends on
+#
+def GetDependencyList(FileStack, SearchPathList):
+ DepDb = dict()
+ DependencySet = set(FileStack)
+ while len(FileStack) > 0:
+ F = FileStack.pop()
+ FullPathDependList = []
+ CurrentFileDependencyList = []
+ if F in DepDb:
+ CurrentFileDependencyList = DepDb[F]
+ else:
+ try:
+ Fd = open(F, 'r')
+ FileContent = Fd.read()
+ except BaseException as X:
+ EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X))
+ finally:
+ if "Fd" in dir(locals()):
+ Fd.close()
+
+ if len(FileContent) == 0:
+ continue
+
+ try:
+ if FileContent[0] == 0xff or FileContent[0] == 0xfe:
+ FileContent = FileContent.decode('utf-16')
+ else:
+ FileContent = FileContent.decode()
+ except:
+ # The file is not txt file. for example .mcb file
+ continue
+ IncludedFileList = gIncludePattern.findall(FileContent)
+
+ for Inc in IncludedFileList:
+ Inc = Inc.strip()
+ Inc = os.path.normpath(Inc)
+ CurrentFileDependencyList.append(Inc)
+ DepDb[F] = CurrentFileDependencyList
+
+ CurrentFilePath = os.path.dirname(F)
+ PathList = [CurrentFilePath] + SearchPathList
+ for Inc in CurrentFileDependencyList:
+ for SearchPath in PathList:
+ FilePath = os.path.join(SearchPath, Inc)
+ if not os.path.exists(FilePath):
+ continue
+ if FilePath not in DependencySet:
+ FileStack.append(FilePath)
+ FullPathDependList.append(FilePath)
+ break
+ DependencySet.update(FullPathDependList)
+ DependencyList = list(DependencySet) # remove duplicate ones
+
+ return DependencyList
+
+class DscBuildData(PlatformBuildClassObject):
+
+ # dict used to convert part of [Defines] to members of DscBuildData directly
+ _PROPERTY_ = {
+ #
+ # Required Fields
+ #
+ TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",
+ TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",
+ TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",
+ TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",
+ # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
+ # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
+ # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
+ TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
+ # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
+ TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
+ TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
+ TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
+ TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
+ # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
+ # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
+ }
+
+ # used to compose dummy library class name for those forced library instances
+ _NullLibraryNumber = 0
+
+ ## Constructor of DscBuildData
+ #
+ # Initialize object of DscBuildData
+ #
+ # @param FilePath The path of platform description file
+ # @param RawData The raw data of DSC file
+ # @param BuildDataBase Database used to retrieve module/package information
+ # @param Arch The target architecture
+ # @param Platform (not used for DscBuildData)
+ # @param Macros Macros used for replacement in DSC file
+ #
+ def __init__(self, FilePath, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
+ self.MetaFile = FilePath
+ self._RawData = RawData
+ self._Bdb = BuildDataBase
+ self._Arch = Arch
+ self._Target = Target
+ self._Toolchain = Toolchain
+ self._ToolChainFamily = None
+ self._Clear()
+ self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else ""
+ self.DefaultStores = None
+ self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)
+ self.UpdatePcdTypeDict()
+ @property
+ def OutputPath(self):
+ if os.getenv("WORKSPACE"):
+ return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain, PcdValueInitName)
+ else:
+ return os.path.dirname(self.DscFile)
+
+ ## 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 DscBuildData to None
+ def _Clear(self):
+ self._Header = None
+ self._PlatformName = None
+ self._Guid = None
+ self._Version = None
+ self._DscSpecification = None
+ self._OutputDirectory = None
+ self._SupArchList = None
+ self._BuildTargets = None
+ self._SkuName = None
+ self._PcdInfoFlag = None
+ self._VarCheckFlag = None
+ self._FlashDefinition = None
+ self._Prebuild = None
+ self._Postbuild = None
+ self._BuildNumber = None
+ self._MakefileName = None
+ self._BsBaseAddress = None
+ self._RtBaseAddress = None
+ self._SkuIds = None
+ self._Modules = None
+ self._LibraryInstances = None
+ self._LibraryClasses = None
+ self._Pcds = None
+ self._DecPcds = None
+ self._BuildOptions = None
+ self._ModuleTypeOptions = None
+ self._LoadFixAddress = None
+ self._RFCLanguages = None
+ self._ISOLanguages = None
+ self._VpdToolGuid = None
+ self._MacroDict = None
+ self.DefaultStores = None
+
+ ## Get current effective macros
+ @property
+ def _Macros(self):
+ if self._MacroDict is None:
+ self._MacroDict = {}
+ self._MacroDict.update(GlobalData.gPlatformDefines)
+ self._MacroDict.update(GlobalData.gGlobalDefines)
+ self._MacroDict.update(GlobalData.gCommandLineDefines)
+ return self._MacroDict
+
+ ## Get architecture
+ @property
+ def Arch(self):
+ return self._Arch
+ @property
+ def Dir(self):
+ return self.MetaFile.Dir
+
+ ## 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]
+ # items defined _PROPERTY_ don't need additional processing
+
+ # some special items in [Defines] section need special treatment
+ if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
+ self._OutputDirectory = NormPath(Record[2], self._Macros)
+ if ' ' in self._OutputDirectory:
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
+ File=self.MetaFile, Line=Record[-1],
+ ExtraData=self._OutputDirectory)
+ elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
+ self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
+ ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
+ ExtraData=ErrorInfo)
+ elif Name == TAB_DSC_PREBUILD:
+ PrebuildValue = Record[2]
+ if Record[2][0] == '"':
+ if Record[2][-1] != '"':
+ EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,
+ File=self.MetaFile, Line=Record[-1])
+ PrebuildValue = Record[2][1:-1]
+ self._Prebuild = PrebuildValue
+ elif Name == TAB_DSC_POSTBUILD:
+ PostbuildValue = Record[2]
+ if Record[2][0] == '"':
+ if Record[2][-1] != '"':
+ EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,
+ File=self.MetaFile, Line=Record[-1])
+ PostbuildValue = Record[2][1:-1]
+ self._Postbuild = PostbuildValue
+ elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
+ self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
+ elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
+ self._BuildTargets = GetSplitValueList(Record[2])
+ elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
+ if self._SkuName is None:
+ self._SkuName = Record[2]
+ if GlobalData.gSKUID_CMD:
+ self._SkuName = GlobalData.gSKUID_CMD
+ elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
+ self._PcdInfoFlag = Record[2]
+ elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
+ self._VarCheckFlag = Record[2]
+ elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
+ try:
+ self._LoadFixAddress = int (Record[2], 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
+ elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
+ if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageCodes = Record[2][1:-1]
+ if not LanguageCodes:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)
+ # check whether there is empty entries in the list
+ if None in LanguageList:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ self._RFCLanguages = LanguageList
+ elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
+ if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageCodes = Record[2][1:-1]
+ if not LanguageCodes:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ if len(LanguageCodes) % 3:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageList = []
+ for i in range(0, len(LanguageCodes), 3):
+ LanguageList.append(LanguageCodes[i:i + 3])
+ self._ISOLanguages = LanguageList
+ elif Name == TAB_DSC_DEFINES_VPD_AUTHENTICATED_VARIABLE_STORE:
+ if TAB_DSC_DEFINES_VPD_AUTHENTICATED_VARIABLE_STORE not in gCommandLineDefines:
+ gCommandLineDefines[TAB_DSC_DEFINES_VPD_AUTHENTICATED_VARIABLE_STORE] = Record[2].strip()
+
+ elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
+ #
+ # try to convert GUID to a real UUID value to see whether the GUID is format
+ # for VPD_TOOL_GUID is correct.
+ #
+ try:
+ uuid.UUID(Record[2])
+ except:
+ EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
+ self._VpdToolGuid = Record[2]
+ elif Name == TAB_DSC_DEFINES_PCD_DYNAMIC_AS_DYNAMICEX:
+ if TAB_DSC_DEFINES_PCD_DYNAMIC_AS_DYNAMICEX not in gCommandLineDefines:
+ gCommandLineDefines[TAB_DSC_DEFINES_PCD_DYNAMIC_AS_DYNAMICEX] = Record[2].strip()
+ elif Name in self:
+ self[Name] = Record[2]
+ # set _Header to non-None in order to avoid database re-querying
+ self._Header = 'DUMMY'
+
+ ## Retrieve platform name
+ @property
+ def PlatformName(self):
+ if self._PlatformName is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._PlatformName is None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)
+ return self._PlatformName
+
+ @property
+ def Platform(self):
+ return self.PlatformName
+
+ ## Retrieve file guid
+ @property
+ def Guid(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 PLATFORM_GUID", File=self.MetaFile)
+ return self._Guid
+
+ ## Retrieve platform version
+ @property
+ def Version(self):
+ if self._Version is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._Version is None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)
+ return self._Version
+
+ ## Retrieve platform description file version
+ @property
+ def DscSpecification(self):
+ if self._DscSpecification is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._DscSpecification is None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)
+ return self._DscSpecification
+
+ ## Retrieve OUTPUT_DIRECTORY
+ @property
+ def OutputDirectory(self):
+ if self._OutputDirectory is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._OutputDirectory is None:
+ self._OutputDirectory = os.path.join("Build", self._PlatformName)
+ return self._OutputDirectory
+
+ ## Retrieve SUPPORTED_ARCHITECTURES
+ @property
+ def SupArchList(self):
+ if self._SupArchList is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._SupArchList is None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)
+ return self._SupArchList
+
+ ## Retrieve BUILD_TARGETS
+ @property
+ def BuildTargets(self):
+ if self._BuildTargets is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._BuildTargets is None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
+ return self._BuildTargets
+
+ @property
+ def PcdInfoFlag(self):
+ if self._PcdInfoFlag is None or self._PcdInfoFlag.upper() == 'FALSE':
+ return False
+ elif self._PcdInfoFlag.upper() == 'TRUE':
+ return True
+ else:
+ return False
+
+ @property
+ def VarCheckFlag(self):
+ if self._VarCheckFlag is None or self._VarCheckFlag.upper() == 'FALSE':
+ return False
+ elif self._VarCheckFlag.upper() == 'TRUE':
+ return True
+ else:
+ return False
+
+ # # Retrieve SKUID_IDENTIFIER
+ @property
+ def SkuName(self):
+ if self._SkuName is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._SkuName is None:
+ self._SkuName = TAB_DEFAULT
+ return self._SkuName
+
+ ## Override SKUID_IDENTIFIER
+ @SkuName.setter
+ def SkuName(self, Value):
+ self._SkuName = Value
+
+ @property
+ def FlashDefinition(self):
+ if self._FlashDefinition is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._FlashDefinition is None:
+ self._FlashDefinition = ''
+ return self._FlashDefinition
+
+ @property
+ def Prebuild(self):
+ if self._Prebuild is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._Prebuild is None:
+ self._Prebuild = ''
+ return self._Prebuild
+
+ @property
+ def Postbuild(self):
+ if self._Postbuild is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._Postbuild is None:
+ self._Postbuild = ''
+ return self._Postbuild
+
+ ## Retrieve FLASH_DEFINITION
+ @property
+ def BuildNumber(self):
+ if self._BuildNumber is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._BuildNumber is None:
+ self._BuildNumber = ''
+ return self._BuildNumber
+
+ ## Retrieve MAKEFILE_NAME
+ @property
+ def MakefileName(self):
+ if self._MakefileName is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._MakefileName is None:
+ self._MakefileName = ''
+ return self._MakefileName
+
+ ## Retrieve BsBaseAddress
+ @property
+ def BsBaseAddress(self):
+ if self._BsBaseAddress is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._BsBaseAddress is None:
+ self._BsBaseAddress = ''
+ return self._BsBaseAddress
+
+ ## Retrieve RtBaseAddress
+ @property
+ def RtBaseAddress(self):
+ if self._RtBaseAddress is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._RtBaseAddress is None:
+ self._RtBaseAddress = ''
+ return self._RtBaseAddress
+
+ ## Retrieve the top address for the load fix address
+ @property
+ def LoadFixAddress(self):
+ if self._LoadFixAddress is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+
+ if self._LoadFixAddress is None:
+ self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
+
+ try:
+ self._LoadFixAddress = int (self._LoadFixAddress, 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
+
+ #
+ # If command line defined, should override the value in DSC file.
+ #
+ if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines:
+ try:
+ self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))
+
+ if self._LoadFixAddress < 0:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
+ if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
+
+ return self._LoadFixAddress
+
+ ## Retrieve RFCLanguage filter
+ @property
+ def RFCLanguages(self):
+ if self._RFCLanguages is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._RFCLanguages is None:
+ self._RFCLanguages = []
+ return self._RFCLanguages
+
+ ## Retrieve ISOLanguage filter
+ @property
+ def ISOLanguages(self):
+ if self._ISOLanguages is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._ISOLanguages is None:
+ self._ISOLanguages = []
+ return self._ISOLanguages
+
+ ## Retrieve the GUID string for VPD tool
+ @property
+ def VpdToolGuid(self):
+ if self._VpdToolGuid is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._VpdToolGuid is None:
+ self._VpdToolGuid = ''
+ return self._VpdToolGuid
+
+ ## Retrieve [SkuIds] section information
+ @property
+ def SkuIds(self):
+ if self._SkuIds is None:
+ self._SkuIds = OrderedDict()
+ RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
+ for Record in RecordList:
+ if not Record[0]:
+ EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
+ File=self.MetaFile, Line=Record[-1])
+ if not Record[1]:
+ EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',
+ File=self.MetaFile, Line=Record[-1])
+ if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]):
+ EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",
+ File=self.MetaFile, Line=Record[-1])
+ if not SkuIdPattern.match(Record[1]) or (Record[2] and not SkuIdPattern.match(Record[2])):
+ EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z_)(a-zA-Z0-9_)*'",
+ File=self.MetaFile, Line=Record[-1])
+ self._SkuIds[Record[1].upper()] = (str(DscBuildData.ToInt(Record[0])), Record[1].upper(), Record[2].upper())
+ if TAB_DEFAULT not in self._SkuIds:
+ self._SkuIds[TAB_DEFAULT] = ("0", TAB_DEFAULT, TAB_DEFAULT)
+ if TAB_COMMON not in self._SkuIds:
+ self._SkuIds[TAB_COMMON] = ("0", TAB_DEFAULT, TAB_DEFAULT)
+ return self._SkuIds
+
+ @staticmethod
+ def ToInt(intstr):
+ return int(intstr, 16) if intstr.upper().startswith("0X") else int(intstr)
+
+ def _GetDefaultStores(self):
+ if self.DefaultStores is None:
+ self.DefaultStores = OrderedDict()
+ RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]
+ for Record in RecordList:
+ if not Record[0]:
+ EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',
+ File=self.MetaFile, Line=Record[-1])
+ if not Record[1]:
+ EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',
+ File=self.MetaFile, Line=Record[-1])
+ if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]):
+ EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",
+ File=self.MetaFile, Line=Record[-1])
+ if not IsValidWord(Record[1]):
+ EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
+ File=self.MetaFile, Line=Record[-1])
+ self.DefaultStores[Record[1].upper()] = (DscBuildData.ToInt(Record[0]), Record[1].upper())
+ if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:
+ self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0, TAB_DEFAULT_STORES_DEFAULT)
+ GlobalData.gDefaultStores = sorted(self.DefaultStores.keys())
+ return self.DefaultStores
+
+ def OverrideDuplicateModule(self):
+ RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
+ Macros = self._Macros
+ Components = {}
+ for Record in RecordList:
+ ModuleId = Record[6]
+ file_guid = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
+ file_guid_str = file_guid[0][2] if file_guid else "NULL"
+ ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ if self._Arch != TAB_ARCH_COMMON and (file_guid_str,str(ModuleFile)) in Components:
+ self._RawData.DisableOverrideComponent(Components[(file_guid_str,str(ModuleFile))])
+ Components[(file_guid_str,str(ModuleFile))] = ModuleId
+ self._RawData._PostProcessed = False
+
+ ## Retrieve packages this Platform depends on
+ @cached_property
+ def Packages(self):
+ RetVal = set()
+ RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch]
+ Macros = self._Macros
+ for Record in RecordList:
+ File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate('.dec')
+ if ErrorCode != 0:
+ LineNo = Record[-1]
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+ # parse this package now. we need it to get protocol/ppi/guid value
+ RetVal.add(self._Bdb[File, self._Arch, self._Target, self._Toolchain])
+ return RetVal
+
+ ## Retrieve [Components] section information
+ @property
+ def Modules(self):
+ if self._Modules is not None:
+ return self._Modules
+ self.OverrideDuplicateModule()
+ self._Modules = OrderedDict()
+ RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
+ Macros = self._Macros
+ for Record in RecordList:
+ ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ ModuleId = Record[6]
+ LineNo = Record[7]
+
+ # check the file validation
+ ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
+ ExtraData=ErrorInfo)
+
+ ModuleBuildData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
+ Module = ModuleBuildClassObject()
+ Module.MetaFile = ModuleFile
+ Module.Guid = ModuleBuildData.Guid
+ # get module private library instance
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
+ for Record in RecordList:
+ LibraryClass = Record[0]
+ LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ LineNo = Record[-1]
+
+ # check the file validation
+ ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
+ ExtraData=ErrorInfo)
+
+ if LibraryClass == '' or LibraryClass == 'NULL':
+ self._NullLibraryNumber += 1
+ LibraryClass = 'NULL%d' % self._NullLibraryNumber
+ EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
+ Module.LibraryClasses[LibraryClass] = LibraryPath
+ if LibraryPath not in self.LibraryInstances:
+ self.LibraryInstances.append(LibraryPath)
+ S_PcdSet = []
+ # get module private PCD setting
+ for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \
+ MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
+ RecordList = self._RawData[Type, self._Arch, None, ModuleId]
+ for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
+ TokenList = GetSplitValueList(Setting)
+ DefaultValue = TokenList[0]
+ # the format is PcdName| Value | VOID* | MaxDatumSize
+ if len(TokenList) > 2:
+ MaxDatumSize = TokenList[2]
+ else:
+ MaxDatumSize = ''
+ TypeString = self._PCD_TYPE_STRING_[Type]
+
+ TCName,PCName,DimensionAttr,Field = self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
+
+ if ("." in TokenSpaceGuid or "[" in PcdCName):
+ S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, ModuleBuildData.Guid, "", Dummy5, AnalyzePcdExpression(Setting)[0]])
+ DefaultValue = ''
+ if ( PCName,TCName) not in Module.Pcds:
+ Pcd = PcdClassObject(
+ PCName,
+ TCName,
+ TypeString,
+ '',
+ DefaultValue,
+ '',
+ MaxDatumSize,
+ {},
+ False,
+ None,
+ IsDsc=True)
+ Module.Pcds[PCName, TCName] = Pcd
+
+ Module.StrPcdSet = S_PcdSet
+ for TCName,PCName, _,_,_,_,_,_ in S_PcdSet:
+ if (PCName,TCName) in Module.Pcds:
+ Module.StrPcdOverallValue[(PCName,TCName)] = Module.Pcds[(PCName,TCName)].DefaultValue, self.MetaFile,Dummy5
+ # get module private build options
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
+ for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
+ if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
+ Module.BuildOptions[ToolChainFamily, ToolChain] = Option
+ else:
+ OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
+ Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
+
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
+ if RecordList:
+ if len(RecordList) != 1:
+ EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',
+ File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
+ ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
+ ModuleFile.Arch = self._Arch
+ Module.Guid = RecordList[0][2]
+ for item in Module.StrPcdSet:
+ item[4] = RecordList[0][2]
+ self._Modules[ModuleFile] = Module
+ return self._Modules
+
+ ## Retrieve all possible library instances used in this platform
+ @property
+ def LibraryInstances(self):
+ if self._LibraryInstances is None:
+ self.LibraryClasses
+ return self._LibraryInstances
+
+ ## Retrieve [LibraryClasses] information
+ @property
+ def LibraryClasses(self):
+ if self._LibraryClasses is None:
+ self._LibraryInstances = []
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # library instance for given library class and module type
+ #
+ LibraryClassDict = tdict(True, 3)
+ # track all library class names
+ LibraryClassSet = set()
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
+ Macros = self._Macros
+ for Record in RecordList:
+ LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, Dummy, LineNo = Record
+ if LibraryClass == '' or LibraryClass == 'NULL':
+ self._NullLibraryNumber += 1
+ LibraryClass = 'NULL%d' % self._NullLibraryNumber
+ EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
+ LibraryClassSet.add(LibraryClass)
+ LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ # check the file validation
+ ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
+ ExtraData=ErrorInfo)
+
+ if ModuleType != TAB_COMMON and ModuleType not in SUP_MODULE_LIST:
+ EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
+ File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
+ LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
+ if LibraryInstance not in self._LibraryInstances:
+ self._LibraryInstances.append(LibraryInstance)
+
+ # resolve the specific library instance for each class and each module type
+ self._LibraryClasses = tdict(True)
+ for LibraryClass in LibraryClassSet:
+ # try all possible module types
+ for ModuleType in SUP_MODULE_LIST:
+ LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
+ if LibraryInstance is None:
+ continue
+ self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
+
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
+ for Record in RecordList:
+ File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ LineNo = Record[-1]
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate('.inf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
+ ExtraData=ErrorInfo)
+ if File not in self._LibraryInstances:
+ self._LibraryInstances.append(File)
+ #
+ # we need the module name as the library class name, so we have
+ # to parse it here. (self._Bdb[] will trigger a file parse if it
+ # hasn't been parsed)
+ #
+ Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
+ self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
+ return self._LibraryClasses
+
+ def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
+ if not self._DecPcds:
+
+ FdfInfList = []
+ if GlobalData.gFdfParser:
+ FdfInfList = GlobalData.gFdfParser.Profile.InfList
+
+ PkgSet = set()
+ for Inf in FdfInfList:
+ ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
+ if ModuleFile in self._Modules:
+ continue
+ ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
+ PkgSet.update(ModuleData.Packages)
+ if self.Packages:
+ PkgSet.update(self.Packages)
+ self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
+ self._GuidDict.update(GlobalData.gPlatformPcds)
+
+ if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
+ EdkLogger.error('build', PARSER_ERROR,
+ "Pcd (%s.%s) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
+ File=self.MetaFile, Line=LineNo)
+ ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
+ if not IsValid:
+ if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
+ EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
+ ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
+ else:
+ if ValueList[2] == '-1':
+ EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
+ ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
+ if ValueList[Index]:
+ DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
+ if "{CODE(" not in ValueList[Index]:
+ try:
+ ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
+ except BadExpression as Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
+ ExtraData="PCD [%s.%s] Value \"%s\" " % (
+ TokenSpaceGuid, PcdCName, ValueList[Index]))
+ except EvaluationException as Excpt:
+ if hasattr(Excpt, 'Pcd'):
+ if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
+ " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
+ " of the DSC file" % Excpt.Pcd,
+ File=self.MetaFile, Line=LineNo)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
+ File=self.MetaFile, Line=LineNo)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
+ File=self.MetaFile, Line=LineNo)
+
+ if ValueList[Index]:
+ Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
+ if not Valid:
+ EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
+ ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
+ if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):
+ if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():
+ DecPcd = self._DecPcds[PcdCName, TokenSpaceGuid]
+ EdkLogger.error('build', FORMAT_INVALID,
+ "Pcd datumtype used in DSC file is not the same as its declaration. DatumType:%s"%DecPcd.DatumType,
+ File=self.MetaFile, Line=LineNo,
+ ExtraData="Dsc:%s.%s|%s\n Dec:%s.%s|%s|%s|%s" % (TokenSpaceGuid, PcdCName, Setting, TokenSpaceGuid, \
+ PcdCName, DecPcd.DefaultValue, DecPcd.DatumType, DecPcd.TokenValue))
+ if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:
+ if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:
+ GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
+ GlobalData.gPlatformFinalPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
+ return ValueList
+
+ def _FilterPcdBySkuUsage(self, Pcds):
+ available_sku = self.SkuIdMgr.AvailableSkuIdSet
+ sku_usage = self.SkuIdMgr.SkuUsageType
+ if sku_usage == SkuClass.SINGLE:
+ for pcdname in Pcds:
+ pcd = Pcds[pcdname]
+ Pcds[pcdname].SkuInfoList = {TAB_DEFAULT:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
+ if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
+ Pcds[pcdname].SkuOverrideValues = {TAB_DEFAULT:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
+ else:
+ for pcdname in Pcds:
+ pcd = Pcds[pcdname]
+ Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
+ if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
+ Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
+ return Pcds
+
+ def CompleteHiiPcdsDefaultStores(self, Pcds):
+ HiiPcd = [Pcds[pcd] for pcd in Pcds if Pcds[pcd].Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]]
+ DefaultStoreMgr = DefaultStore(self.DefaultStores)
+ for pcd in HiiPcd:
+ for skuid in pcd.SkuInfoList:
+ skuobj = pcd.SkuInfoList.get(skuid)
+ if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:
+ PcdDefaultStoreSet = set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict)
+ mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
+ skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = skuobj.DefaultStoreDict[mindefaultstorename]
+ return Pcds
+
+ def RecoverCommandLinePcd(self):
+ def UpdateCommandLineValue(pcd):
+ if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
+ pcd.PcdValueFromComm = pcd.DefaultValue
+ elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).HiiDefaultValue
+ else:
+ pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).DefaultValue
+ for pcd in self._Pcds:
+ if isinstance(self._Pcds[pcd], StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):
+ UpdateCommandLineValue(self._Pcds[pcd])
+
+ def __ParsePcdFromCommandLine(self):
+ if GlobalData.BuildOptionPcd:
+ for i, pcd in enumerate(GlobalData.BuildOptionPcd):
+ if isinstance(pcd, tuple):
+ continue
+ (pcdname, pcdvalue) = pcd.split('=')
+ if not pcdvalue:
+ EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
+ if '.' in pcdname:
+ (Name1, Name2) = pcdname.split('.', 1)
+ if "." in Name2:
+ (Name3, FieldName) = Name2.split(".", 1)
+ if ((Name3, Name1)) in self.DecPcds:
+ HasTokenSpace = True
+ TokenCName = Name3
+ TokenSpaceGuidCName = Name1
+ else:
+ FieldName = Name2
+ TokenCName = Name1
+ TokenSpaceGuidCName = ''
+ HasTokenSpace = False
+ else:
+ if ((Name2, Name1)) in self.DecPcds:
+ HasTokenSpace = True
+ TokenCName = Name2
+ TokenSpaceGuidCName = Name1
+ FieldName =""
+ else:
+ FieldName = Name2
+ TokenCName = Name1
+ TokenSpaceGuidCName = ''
+ HasTokenSpace = False
+ else:
+ FieldName = ""
+ TokenCName = pcdname
+ TokenSpaceGuidCName = ''
+ HasTokenSpace = False
+ TokenSpaceGuidCNameList = []
+ FoundFlag = False
+ PcdDatumType = ''
+ DisplayName = TokenCName
+ if FieldName:
+ DisplayName = TokenCName + '.' + FieldName
+ if not HasTokenSpace:
+ for key in self.DecPcds:
+ PcdItem = self.DecPcds[key]
+ if TokenCName == PcdItem.TokenCName:
+ if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
+ if len (TokenSpaceGuidCNameList) < 1:
+ TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
+ TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
+ PcdDatumType = PcdItem.DatumType
+ FoundFlag = True
+ else:
+ EdkLogger.error(
+ 'build',
+ AUTOGEN_ERROR,
+ "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
+ )
+ else:
+ if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
+ PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType
+ FoundFlag = True
+ if not FoundFlag:
+ if HasTokenSpace:
+ EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))
+ else:
+ EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))
+ pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
+ if FieldName:
+ pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)
+ else:
+ pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)
+ IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)
+ if not IsValid:
+ EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
+ GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, ("build command options", 1))
+
+ if GlobalData.BuildOptionPcd:
+ inf_objs = [item for item in self._Bdb._CACHE_.values() if item.Arch == self.Arch and item.MetaFile.Ext.lower() == '.inf']
+ for pcd in GlobalData.BuildOptionPcd:
+ (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, _) = pcd
+ for BuildData in inf_objs:
+ for key in BuildData.Pcds:
+ PcdItem = BuildData.Pcds[key]
+ if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
+ PcdItem.DefaultValue = pcdvalue
+ PcdItem.PcdValueFromComm = pcdvalue
+ #In command line, the latter full assign value in commandLine should override the former field assign value.
+ #For example, --pcd Token.pcd.field="" --pcd Token.pcd=H"{}"
+ delete_assign = []
+ field_assign = {}
+ if GlobalData.BuildOptionPcd:
+ for pcdTuple in GlobalData.BuildOptionPcd:
+ TokenSpaceGuid, Token, Field = pcdTuple[0], pcdTuple[1], pcdTuple[2]
+ if Field:
+ if (TokenSpaceGuid, Token) not in field_assign:
+ field_assign[TokenSpaceGuid, Token] = []
+ field_assign[TokenSpaceGuid, Token].append(pcdTuple)
+ else:
+ if (TokenSpaceGuid, Token) in field_assign:
+ delete_assign.extend(field_assign[TokenSpaceGuid, Token])
+ field_assign[TokenSpaceGuid, Token] = []
+ for item in delete_assign:
+ GlobalData.BuildOptionPcd.remove(item)
+
+ @staticmethod
+ def HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):
+ if FieldName:
+ IsArray = False
+ TokenCName += '.' + FieldName
+ if PcdValue.startswith('H'):
+ if FieldName and _IsFieldValueAnArray(PcdValue[1:]):
+ PcdDatumType = TAB_VOID
+ IsArray = True
+ if FieldName and not IsArray:
+ return PcdValue
+ try:
+ PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)
+ except BadExpression as Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
+ (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
+ elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
+ if FieldName and _IsFieldValueAnArray(PcdValue):
+ PcdDatumType = TAB_VOID
+ IsArray = True
+ if FieldName and not IsArray:
+ return PcdValue
+ try:
+ PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
+ except BadExpression as Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
+ (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
+ elif PcdValue.startswith('L'):
+ PcdValue = 'L"' + PcdValue[1:] + '"'
+ if FieldName and _IsFieldValueAnArray(PcdValue):
+ PcdDatumType = TAB_VOID
+ IsArray = True
+ if FieldName and not IsArray:
+ return PcdValue
+ try:
+ PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
+ except BadExpression as Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
+ (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
+ else:
+ if PcdValue.upper() == 'FALSE':
+ PcdValue = str(0)
+ if PcdValue.upper() == 'TRUE':
+ PcdValue = str(1)
+ if not FieldName:
+ if PcdDatumType not in TAB_PCD_NUMERIC_TYPES:
+ PcdValue = '"' + PcdValue + '"'
+ elif not PcdValue.isdigit() and not PcdValue.upper().startswith('0X'):
+ PcdValue = '"' + PcdValue + '"'
+ else:
+ IsArray = False
+ Base = 10
+ if PcdValue.upper().startswith('0X'):
+ Base = 16
+ try:
+ Num = int(PcdValue, Base)
+ except:
+ PcdValue = '"' + PcdValue + '"'
+ if _IsFieldValueAnArray(PcdValue):
+ PcdDatumType = TAB_VOID
+ IsArray = True
+ if not IsArray:
+ return PcdValue
+ try:
+ PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
+ except BadExpression as Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
+ (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
+ return PcdValue
+
+ ## Retrieve all PCD settings in platform
+ @property
+ def Pcds(self):
+ if self._Pcds is None:
+ self._Pcds = OrderedDict()
+ self.__ParsePcdFromCommandLine()
+ 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._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
+ self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
+ self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
+ self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
+ self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
+ self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
+
+ self._Pcds = self.CompletePcdValues(self._Pcds)
+ self._Pcds = self.OverrideByFdfOverAll(self._Pcds)
+ self._Pcds = self.OverrideByCommOverAll(self._Pcds)
+ self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
+ self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
+ self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
+
+ self.RecoverCommandLinePcd()
+ return self._Pcds
+
+ ## Retrieve [BuildOptions]
+ @property
+ def BuildOptions(self):
+ if self._BuildOptions is None:
+ self._BuildOptions = OrderedDict()
+ #
+ # Retrieve build option for EDKII and EDK style module
+ #
+ for CodeBase in (EDKII_NAME, EDK_NAME):
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
+ for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
+ if Dummy3.upper() != TAB_COMMON:
+ continue
+ CurKey = (ToolChainFamily, ToolChain, CodeBase)
+ #
+ # Only flags can be appended
+ #
+ if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
+ self._BuildOptions[CurKey] = Option
+ else:
+ if ' ' + Option not in self._BuildOptions[CurKey]:
+ self._BuildOptions[CurKey] += ' ' + Option
+ return self._BuildOptions
+ def GetBuildOptionsByPkg(self, Module, ModuleType):
+
+ local_pkg = os.path.split(Module.LocalPkg())[0]
+ if self._ModuleTypeOptions is None:
+ self._ModuleTypeOptions = OrderedDict()
+ if ModuleType not in self._ModuleTypeOptions:
+ options = OrderedDict()
+ self._ModuleTypeOptions[ ModuleType] = options
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
+ for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
+ if Dummy2 not in (TAB_COMMON,local_pkg.upper(),"EDKII"):
+ continue
+ Type = Dummy3
+ if Type.upper() == ModuleType.upper():
+ Key = (ToolChainFamily, ToolChain)
+ if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
+ options[Key] = Option
+ else:
+ if ' ' + Option not in options[Key]:
+ options[Key] += ' ' + Option
+ return self._ModuleTypeOptions[ModuleType]
+ def GetBuildOptionsByModuleType(self, Edk, ModuleType):
+ if self._ModuleTypeOptions is None:
+ self._ModuleTypeOptions = OrderedDict()
+ if (Edk, ModuleType) not in self._ModuleTypeOptions:
+ options = OrderedDict()
+ self._ModuleTypeOptions[Edk, ModuleType] = options
+ DriverType = '%s.%s' % (Edk, ModuleType)
+ CommonDriverType = '%s.%s' % (TAB_COMMON, ModuleType)
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
+ for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
+ Type = Dummy2 + '.' + Dummy3
+ if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
+ Key = (ToolChainFamily, ToolChain, Edk)
+ if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
+ options[Key] = Option
+ else:
+ if ' ' + Option not in options[Key]:
+ options[Key] += ' ' + Option
+ return self._ModuleTypeOptions[Edk, ModuleType]
+
+ @staticmethod
+ def GetStructurePcdInfo(PcdSet):
+ structure_pcd_data = defaultdict(list)
+ for item in PcdSet:
+ structure_pcd_data[(item[0], item[1])].append(item)
+
+ return structure_pcd_data
+
+ @staticmethod
+ def OverrideByFdf(StruPcds,workspace):
+ if GlobalData.gFdfParser is None:
+ return StruPcds
+ StructurePcdInFdf = OrderedDict()
+ fdfpcd = GlobalData.gFdfParser.Profile.PcdDict
+ fdfpcdlocation = GlobalData.gFdfParser.Profile.PcdLocalDict
+ for item in fdfpcd :
+ if len(item[2]) and (item[0],item[1]) in StruPcds:
+ StructurePcdInFdf[(item[1],item[0],item[2] )] = fdfpcd[item]
+ GlobalPcds = {(item[0],item[1]) for item in StructurePcdInFdf}
+ for Pcd in StruPcds.values():
+ if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
+ continue
+ FieldValues = OrderedDict()
+ for item in StructurePcdInFdf:
+ if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:
+ FieldValues[item[2]] = StructurePcdInFdf[item]
+ for field in FieldValues:
+ if field not in Pcd.PcdFieldValueFromFdf:
+ Pcd.PcdFieldValueFromFdf[field] = ["","",""]
+ Pcd.PcdFieldValueFromFdf[field][0] = FieldValues[field]
+ Pcd.PcdFieldValueFromFdf[field][1] = os.path.relpath(fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][0],workspace)
+ Pcd.PcdFieldValueFromFdf[field][2] = fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][1]
+
+ return StruPcds
+
+ @staticmethod
+ def OverrideByComm(StruPcds):
+ StructurePcdInCom = OrderedDict()
+ for item in GlobalData.BuildOptionPcd:
+ if len(item) == 5 and (item[1], item[0]) in StruPcds:
+ StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
+ GlobalPcds = {(item[0], item[1]) for item in StructurePcdInCom}
+ for Pcd in StruPcds.values():
+ if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in GlobalPcds:
+ continue
+ FieldValues = OrderedDict()
+ for item in StructurePcdInCom:
+ if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (item[0], item[1]) and item[2]:
+ FieldValues[item[2]] = StructurePcdInCom[item]
+ for field in FieldValues:
+ if field not in Pcd.PcdFieldValueFromComm:
+ Pcd.PcdFieldValueFromComm[field] = ["", "", ""]
+ Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]
+ Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]
+ Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]
+ return StruPcds
+
+ def OverrideByCommOverAll(self,AllPcds):
+ def CheckStructureInComm(commpcds):
+ if not commpcds:
+ return False
+ if len(commpcds[0]) == 5:
+ return True
+ return False
+ NoFiledValues = OrderedDict()
+ if CheckStructureInComm(GlobalData.BuildOptionPcd):
+ StructurePcdInCom = OrderedDict()
+ for item in GlobalData.BuildOptionPcd:
+ StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
+ for item in StructurePcdInCom:
+ if not item[2]:
+ NoFiledValues[(item[0], item[1])] = StructurePcdInCom[item]
+ else:
+ for item in GlobalData.BuildOptionPcd:
+ NoFiledValues[(item[0], item[1])] = [item[2]]
+ for Guid, Name in NoFiledValues:
+ if (Name, Guid) in AllPcds:
+ Pcd = AllPcds.get((Name, Guid))
+ if isinstance(self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), None), StructurePcd):
+ self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
+ else:
+ Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
+ Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
+ for sku in Pcd.SkuInfoList:
+ SkuInfo = Pcd.SkuInfoList[sku]
+ if SkuInfo.DefaultValue:
+ SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
+ else:
+ SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
+ for defaultstore in SkuInfo.DefaultStoreDict:
+ SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
+ if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
+ if Pcd.DatumType == TAB_VOID:
+ if not Pcd.MaxDatumSize:
+ Pcd.MaxDatumSize = '0'
+ CurrentSize = int(Pcd.MaxDatumSize, 16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
+ OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
+ MaxSize = max(CurrentSize, OptionSize)
+ Pcd.MaxDatumSize = str(MaxSize)
+ else:
+ PcdInDec = self.DecPcds.get((Name, Guid))
+ if PcdInDec:
+ PcdInDec.PcdValueFromComm = NoFiledValues[(Guid, Name)][0]
+ if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
+ self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
+ self._Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
+ self._Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid, Name)][0]
+ if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
+ self._Pcds[Name, Guid].SkuInfoList = {TAB_DEFAULT:SkuInfoClass(TAB_DEFAULT, self.SkuIds[TAB_DEFAULT][0], '', '', '', '', '', NoFiledValues[( Guid, Name)][0])}
+ return AllPcds
+
+ def OverrideByFdfOverAll(self,AllPcds):
+
+ if GlobalData.gFdfParser is None:
+ return AllPcds
+ NoFiledValues = GlobalData.gFdfParser.Profile.PcdDict
+ for Name,Guid,Field in NoFiledValues:
+ if len(Field):
+ continue
+ Value = NoFiledValues[(Name,Guid,Field)]
+ if (Name,Guid) in AllPcds:
+ Pcd = AllPcds.get((Name,Guid))
+ if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):
+ self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = Value
+ else:
+ Pcd.PcdValueFromComm = Value
+ Pcd.DefaultValue = Value
+ for sku in Pcd.SkuInfoList:
+ SkuInfo = Pcd.SkuInfoList[sku]
+ if SkuInfo.DefaultValue:
+ SkuInfo.DefaultValue = Value
+ else:
+ SkuInfo.HiiDefaultValue = Value
+ for defaultstore in SkuInfo.DefaultStoreDict:
+ SkuInfo.DefaultStoreDict[defaultstore] = Value
+ if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
+ if Pcd.DatumType == TAB_VOID:
+ if not Pcd.MaxDatumSize:
+ Pcd.MaxDatumSize = '0'
+ CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
+ OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
+ MaxSize = max(CurrentSize, OptionSize)
+ Pcd.MaxDatumSize = str(MaxSize)
+ else:
+ PcdInDec = self.DecPcds.get((Name,Guid))
+ if PcdInDec:
+ PcdInDec.PcdValueFromFdf = Value
+ if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
+ self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
+ self._Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
+ self._Pcds[Name, Guid].DefaultValue = Value
+ return AllPcds
+
+ def ParsePcdNameStruct(self,NamePart1,NamePart2):
+ TokenSpaceCName = PcdCName = DimensionAttr = Field = ""
+ if "." in NamePart1:
+ TokenSpaceCName, TempPcdCName = NamePart1.split(".")
+ if "[" in TempPcdCName:
+ PcdCName = TempPcdCName[:TempPcdCName.index("[")]
+ DimensionAttr = TempPcdCName[TempPcdCName.index("["):]
+ else:
+ PcdCName = TempPcdCName
+ Field = NamePart2
+ else:
+ TokenSpaceCName = NamePart1
+ if "[" in NamePart2:
+ PcdCName = NamePart2[:NamePart2.index("[")]
+ DimensionAttr = NamePart2[NamePart2.index("["):]
+ else:
+ PcdCName = NamePart2
+
+ return TokenSpaceCName,PcdCName,DimensionAttr,Field
+
+ def UpdateStructuredPcds(self, TypeList, AllPcds):
+
+ DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
+
+ Pcds = AllPcds
+ DefaultStoreMgr = DefaultStore(self.DefaultStores)
+ SkuIds = self.SkuIds
+ self.SkuIdMgr.AvailableSkuIdSet.update({TAB_DEFAULT:0})
+ DefaultStores = {storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict}
+ DefaultStores.add(TAB_DEFAULT_STORES_DEFAULT)
+
+ S_PcdSet = []
+ # Find out all possible PCD candidates for self._Arch
+ RecordList = []
+
+ for Type in TypeList:
+ RecordList.extend(self._RawData[Type, self._Arch])
+
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4, Dummy5 in RecordList:
+ SkuName = SkuName.upper()
+ default_store = default_store.upper()
+ SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
+ if SkuName not in SkuIds:
+ continue
+ TCName,PCName,DimensionAttr,Field = self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
+ pcd_in_dec = self._DecPcds.get((PCName,TCName), None)
+ if pcd_in_dec is None:
+ EdkLogger.error('build', PARSER_ERROR,
+ "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
+ File=self.MetaFile, Line = Dummy5)
+ if SkuName in SkuIds and ("." in TokenSpaceGuid or "[" in PcdCName):
+ if not isinstance (pcd_in_dec, StructurePcd):
+ EdkLogger.error('build', PARSER_ERROR,
+ "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
+ File=self.MetaFile, Line = Dummy5)
+
+ S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
+ ModuleScopeOverallValue = {}
+ for m in self.Modules.values():
+ mguid = m.Guid
+ if m.StrPcdSet:
+ S_PcdSet.extend(m.StrPcdSet)
+ mguid = m.StrPcdSet[0][4]
+ for (PCName,TCName) in m.StrPcdOverallValue:
+ Value, dsc_file, lineNo = m.StrPcdOverallValue[(PCName,TCName)]
+ ModuleScopeOverallValue.setdefault((PCName,TCName),{})[mguid] = Value, dsc_file, lineNo
+ # handle pcd value override
+ StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
+ S_pcd_set = OrderedDict()
+ for str_pcd in StrPcdSet:
+ str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
+ str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
+ str_pcd_obj_str = StructurePcd()
+ str_pcd_obj_str.copy(str_pcd_dec)
+ if str_pcd_obj:
+ str_pcd_obj_str.copy(str_pcd_obj)
+ if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
+ else:
+ str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
+ for str_pcd_data in StrPcdSet[str_pcd]:
+ if str_pcd_data[4] in SkuIds:
+ str_pcd_obj_str.AddOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] == TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
+ elif GlobalData.gGuidPattern.match(str_pcd_data[4]):
+ str_pcd_obj_str.AddComponentOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), str_pcd_data[4].replace("-","S"), self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
+ PcdComponentValue = ModuleScopeOverallValue.get((str_pcd_obj_str.TokenCName,str_pcd_obj_str.TokenSpaceGuidCName))
+ for module_guid in PcdComponentValue:
+ str_pcd_obj_str.PcdValueFromComponents[module_guid.replace("-","S")] = PcdComponentValue[module_guid]
+ S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
+
+ # Add the Structure PCD that only defined in DEC, don't have override in DSC file
+ for Pcd in self.DecPcds:
+ if isinstance(self._DecPcds[Pcd], StructurePcd):
+ if Pcd not in S_pcd_set:
+ str_pcd_obj_str = StructurePcd()
+ str_pcd_obj_str.copy(self._DecPcds[Pcd])
+ str_pcd_obj = Pcds.get(Pcd, None)
+ if str_pcd_obj:
+ str_pcd_obj_str.copy(str_pcd_obj)
+ if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
+ else:
+ str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
+ S_pcd_set[Pcd] = str_pcd_obj_str
+ if S_pcd_set:
+ GlobalData.gStructurePcd[self.Arch] = S_pcd_set.copy()
+ self.FilterStrcturePcd(S_pcd_set)
+ for stru_pcd in S_pcd_set.values():
+ for skuid in SkuIds:
+ if skuid in stru_pcd.SkuOverrideValues:
+ continue
+ nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
+ NoDefault = False
+ if skuid not in stru_pcd.SkuOverrideValues:
+ while nextskuid not in stru_pcd.SkuOverrideValues:
+ if nextskuid == TAB_DEFAULT:
+ NoDefault = True
+ break
+ nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
+ stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {}) #{TAB_DEFAULT_STORES_DEFAULT:stru_pcd.DefaultValues})
+ if not NoDefault:
+ stru_pcd.ValueChain.add((skuid, ''))
+ if 'DEFAULT' in stru_pcd.SkuOverrideValues and not GlobalData.gPcdSkuOverrides.get((stru_pcd.TokenCName, stru_pcd.TokenSpaceGuidCName)):
+ GlobalData.gPcdSkuOverrides.update(
+ {(stru_pcd.TokenCName, stru_pcd.TokenSpaceGuidCName): {'DEFAULT':stru_pcd.SkuOverrideValues['DEFAULT']}})
+ if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ for skuid in SkuIds:
+ nextskuid = skuid
+ NoDefault = False
+ if skuid not in stru_pcd.SkuOverrideValues:
+ while nextskuid not in stru_pcd.SkuOverrideValues:
+ if nextskuid == TAB_DEFAULT:
+ NoDefault = True
+ break
+ nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
+ if NoDefault:
+ continue
+ PcdDefaultStoreSet = set(defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])
+ mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
+
+ for defaultstoreid in DefaultStores:
+ if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
+ stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
+ stru_pcd.ValueChain.add((skuid, defaultstoreid))
+ S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
+ S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
+
+ # Create a tool to caculate structure pcd value
+ Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
+
+ if Str_Pcd_Values:
+ for (skuname, StoreName, PcdGuid, PcdName, PcdValue) in Str_Pcd_Values:
+ str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
+ if str_pcd_obj is None:
+ print(PcdName, PcdGuid)
+ raise
+ if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ if skuname not in str_pcd_obj.SkuInfoList:
+ str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
+ else:
+ str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
+ str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
+ elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
+ if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
+ str_pcd_obj.DefaultValue = PcdValue
+ else:
+ #Module Scope Structure Pcd
+ moduleguid = skuname.replace("S","-")
+ if GlobalData.gGuidPattern.match(moduleguid):
+ for component in self.Modules.values():
+ if component.Guid == moduleguid:
+ component.Pcds[(PcdName, PcdGuid)].DefaultValue = PcdValue
+
+ else:
+ if skuname not in str_pcd_obj.SkuInfoList:
+ nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
+ NoDefault = False
+ while nextskuid not in str_pcd_obj.SkuInfoList:
+ if nextskuid == TAB_DEFAULT:
+ NoDefault = True
+ break
+ nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
+ str_pcd_obj.SkuInfoList[skuname] = copy.deepcopy(str_pcd_obj.SkuInfoList[nextskuid]) if not NoDefault else SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue)
+ str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
+ str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
+ else:
+ str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
+ for str_pcd_obj in S_pcd_set.values():
+ if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ continue
+ PcdDefaultStoreSet = set(defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict)
+ DefaultStoreObj = DefaultStore(self._GetDefaultStores())
+ mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
+ str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
+
+ for str_pcd_obj in S_pcd_set.values():
+
+ str_pcd_obj.MaxDatumSize = DscBuildData.GetStructurePcdMaxSize(str_pcd_obj)
+ Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
+ Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName].CustomAttribute['IsStru']=True
+
+ for pcdkey in Pcds:
+ pcd = Pcds[pcdkey]
+ if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
+ pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
+ del pcd.SkuInfoList[TAB_COMMON]
+ elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
+ del pcd.SkuInfoList[TAB_COMMON]
+
+ list(map(self.FilterSkuSettings, [Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType]))
+ return Pcds
+ @cached_property
+ def PlatformUsedPcds(self):
+ FdfInfList = []
+ if GlobalData.gFdfParser:
+ FdfInfList = GlobalData.gFdfParser.Profile.InfList
+ FdfModuleList = [PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch) for Inf in FdfInfList]
+ AllModulePcds = set()
+ ModuleSet = set(list(self._Modules.keys()) + FdfModuleList)
+ for ModuleFile in ModuleSet:
+ ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
+ AllModulePcds = AllModulePcds | ModuleData.PcdsName
+ for ModuleFile in self.LibraryInstances:
+ ModuleData = self._Bdb.CreateBuildObject(ModuleFile, self._Arch, self._Target, self._Toolchain)
+ AllModulePcds = AllModulePcds | ModuleData.PcdsName
+ return AllModulePcds
+
+ #Filter the StrucutrePcd that is not used by any module in dsc file and fdf file.
+ def FilterStrcturePcd(self, S_pcd_set):
+ UnusedStruPcds = set(S_pcd_set.keys()) - self.PlatformUsedPcds
+ for (Token, TokenSpaceGuid) in UnusedStruPcds:
+ del S_pcd_set[(Token, TokenSpaceGuid)]
+
+ ## Retrieve non-dynamic PCD settings
+ #
+ # @param Type PCD type
+ #
+ # @retval a dict object contains settings of given PCD type
+ #
+ def _GetPcd(self, Type):
+ Pcds = OrderedDict()
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # PCD settings for certain ARCH
+ #
+ AvailableSkuIdSet = copy.copy(self.SkuIds)
+
+ PcdDict = tdict(True, 4)
+ PcdList = []
+ # Find out all possible PCD candidates for self._Arch
+ RecordList = self._RawData[Type, self._Arch]
+ PcdValueDict = OrderedDict()
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
+ SkuName = SkuName.upper()
+ SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
+ if SkuName not in AvailableSkuIdSet:
+ EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
+ File=self.MetaFile, Line=Dummy5)
+ if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
+ if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
+ PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
+ PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
+
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
+ Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
+ if Setting is None:
+ continue
+ PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ if MaxDatumSize:
+ if int(MaxDatumSize, 0) > 0xFFFF:
+ EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
+ File=self.MetaFile, Line=Dummy4)
+ if int(MaxDatumSize, 0) < 0:
+ EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
+ File=self.MetaFile, Line=Dummy4)
+ if (PcdCName, TokenSpaceGuid) in PcdValueDict:
+ PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize,Dummy4)
+ else:
+ PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize,Dummy4)}
+
+ for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.items():
+ if self.SkuIdMgr.SystemSkuId in PcdSetting:
+ PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[self.SkuIdMgr.SystemSkuId]
+ elif TAB_DEFAULT in PcdSetting:
+ PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[TAB_DEFAULT]
+ elif TAB_COMMON in PcdSetting:
+ PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[TAB_COMMON]
+ else:
+ PcdValue = None
+ DatumType = None
+ MaxDatumSize = None
+
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ DatumType,
+ PcdValue,
+ '',
+ MaxDatumSize,
+ {},
+ False,
+ None,
+ IsDsc=True)
+ for SkuName in PcdValueDict[PcdCName, TokenSpaceGuid]:
+ Settings = PcdValueDict[PcdCName, TokenSpaceGuid][SkuName]
+ if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = Settings[0]
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Settings[3])
+ return Pcds
+
+ @staticmethod
+ def GetStructurePcdMaxSize(str_pcd):
+ pcd_default_value = str_pcd.DefaultValue
+ sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [DscBuildData._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], DscBuildData._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]
+ sku_values.append(pcd_default_value)
+
+ def get_length(value):
+ Value = value.strip()
+ if len(value) > 1:
+ if Value.startswith(TAB_GUID) and Value.endswith(')'):
+ return 16
+ if Value.startswith('L"') and Value.endswith('"'):
+ return len(Value[2:-1])
+ if Value[0] == '"' and Value[-1] == '"':
+ return len(Value) - 2
+ if Value.strip().startswith("{CODE("):
+ tmpValue = RemoveCComments(Value)
+ return len(tmpValue.split(","))
+ if (Value[0] == '{' and Value[-1] == '}'):
+ return len(Value.split(","))
+ if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
+ return len(list(Value[2:-1]))
+ if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
+ return len(Value) - 2
+ return len(Value)
+
+ return str(max(get_length(item) for item in sku_values))
+
+ @staticmethod
+ def ExecuteCommand (Command):
+ try:
+ Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ except:
+ EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
+ Result = Process.communicate()
+ return Process.returncode, Result[0].decode(errors='ignore'), Result[1].decode(errors='ignore')
+
+ @staticmethod
+ def IntToCString(Value, ValueSize):
+ Result = '"'
+ if not isinstance (Value, str):
+ for Index in range(0, ValueSize):
+ Result = Result + '\\x%02x' % (Value & 0xff)
+ Value = Value >> 8
+ Result = Result + '"'
+ return Result
+
+ def GenerateSizeFunction(self, Pcd):
+ CApp = "// Default Value in Dec \n"
+ CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+ if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+ CApp += " *Size = (sizeof (%s) > *Size ? sizeof (%s) : *Size);\n" % (Pcd.DatumType,Pcd.DatumType)
+ else:
+ if "{CODE(" in Pcd.DefaultValueFromDec:
+ CApp += " *Size = (sizeof (%s_%s_INIT_Value) > *Size ? sizeof (%s_%s_INIT_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Pcd.TokenSpaceGuidCName,Pcd.TokenCName)
+ if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
+ for skuname in Pcd.SkuInfoList:
+ skuobj = Pcd.SkuInfoList[skuname]
+ if skuobj.VariableName:
+ for defaultstore in skuobj.DefaultStoreDict:
+ pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,defaultstore)
+ if pcddef:
+ if "{CODE(" in pcddef:
+ CApp += " *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
+ else:
+ CApp += " *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
+ else:
+ pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,TAB_DEFAULT_STORES_DEFAULT)
+ if pcddef:
+ if "{CODE(" in pcddef:
+ CApp += " *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT)
+ else:
+ CApp += " *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
+ else:
+ pcddef = self.GetPcdDscRawDefaultValue(Pcd,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
+ if pcddef:
+ if "{CODE(" in pcddef:
+ CApp += " *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
+ else:
+ CApp += " *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
+ ActualCap = []
+ for index in Pcd.DefaultValues:
+ if index:
+ ActualCap.append(index)
+ FieldList = Pcd.DefaultValues[index]
+ if not FieldList:
+ continue
+ for FieldName in FieldList:
+ FieldName = "." + FieldName
+ IsArray = _IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
+ if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
+ try:
+ Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
+ Value, ValueSize = ParseFieldValue(Value)
+ if not Pcd.IsArray():
+ CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
+ else:
+ NewFieldName = ''
+ FieldName_ori = FieldName.strip('.')
+ while '[' in FieldName:
+ NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
+ Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+ FieldName = FieldName.split(']', 1)[1]
+ FieldName = NewFieldName + FieldName
+ while '[' in FieldName and not Pcd.IsArray():
+ FieldName = FieldName.rsplit('[', 1)[0]
+ CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
+ flexisbale_size_statement_cache = set()
+ for skuname in Pcd.SkuOverrideValues:
+ if skuname == TAB_COMMON:
+ continue
+ for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
+ CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
+ for index in Pcd.SkuOverrideValues[skuname][defaultstorenameitem]:
+ if index:
+ ActualCap.append(index)
+ for FieldList in [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]:
+ if not FieldList:
+ continue
+ for FieldName in FieldList:
+ fieldinfo = tuple(FieldList[FieldName])
+ if fieldinfo in flexisbale_size_statement_cache:
+ continue
+ flexisbale_size_statement_cache.add(fieldinfo)
+ FieldName = "." + FieldName
+ IsArray = _IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
+ if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
+ try:
+ Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
+ Value, ValueSize = ParseFieldValue(Value)
+ if not Pcd.IsArray():
+ CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
+ else:
+ NewFieldName = ''
+ FieldName_ori = FieldName.strip('.')
+ while '[' in FieldName:
+ NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
+ Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+ FieldName = FieldName.split(']', 1)[1]
+ FieldName = NewFieldName + FieldName
+ while '[' in FieldName and not Pcd.IsArray():
+ FieldName = FieldName.rsplit('[', 1)[0]
+ CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
+ if Pcd.PcdFieldValueFromFdf:
+ CApp = CApp + "// From fdf \n"
+ for FieldName in Pcd.PcdFieldValueFromFdf:
+ FieldName = "." + FieldName
+ IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
+ if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):
+ try:
+ Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))
+ Value, ValueSize = ParseFieldValue(Value)
+ if not Pcd.IsArray():
+ CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0]);
+ else:
+ NewFieldName = ''
+ FieldName_ori = FieldName.strip('.')
+ while '[' in FieldName:
+ NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
+ Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+ FieldName = FieldName.split(']', 1)[1]
+ FieldName = NewFieldName + FieldName
+ while '[' in FieldName:
+ FieldName = FieldName.rsplit('[', 1)[0]
+ CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
+ if Pcd.PcdFieldValueFromComm:
+ CApp = CApp + "// From Command Line \n"
+ for FieldName in Pcd.PcdFieldValueFromComm:
+ FieldName = "." + FieldName
+ IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
+ if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
+ try:
+ Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
+ Value, ValueSize = ParseFieldValue(Value)
+ if not Pcd.IsArray():
+ CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]);
+ else:
+ NewFieldName = ''
+ FieldName_ori = FieldName.strip('.')
+ while '[' in FieldName:
+ NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
+ Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+ FieldName = FieldName.split(']', 1)[1]
+ FieldName = NewFieldName + FieldName
+ while '[' in FieldName and not Pcd.IsArray():
+ FieldName = FieldName.rsplit('[', 1)[0]
+ CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
+ if Pcd.GetPcdMaxSize():
+ CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
+ ArraySizeByAssign = self.CalculateActualCap(ActualCap)
+ if ArraySizeByAssign > 1:
+ CApp = CApp + " *Size = (%d > *Size ? %d : *Size); \n" % (ArraySizeByAssign, ArraySizeByAssign)
+ CApp = CApp + "}\n"
+ return CApp
+ def CalculateActualCap(self,ActualCap):
+ if not ActualCap:
+ return 1
+ maxsize = 1
+ for item in ActualCap:
+ index_elements = ArrayIndex.findall(item)
+ rt = 1
+ for index_e in index_elements:
+ index_num = index_e.lstrip("[").rstrip("]").strip()
+ if not index_num:
+ # Not support flexiable pcd array assignment
+ return 1
+ index_num = int(index_num,16) if index_num.startswith(("0x","0X")) else int(index_num)
+ rt = rt * (index_num+1)
+ if rt >maxsize:
+ maxsize = rt
+
+ return maxsize
+
+ @staticmethod
+ def GenerateSizeStatments(Pcd,skuname,defaultstorename):
+ if Pcd.IsArray():
+ r_datatype = [Pcd.BaseDatumType]
+ lastoneisEmpty = False
+ for dem in Pcd.Capacity:
+ if lastoneisEmpty:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName))))
+ if dem == '0' or dem == "-1":
+ r_datatype.append("[1]")
+ lastoneisEmpty = True
+ else:
+ r_datatype.append("[" + dem + "]")
+
+ if Pcd.Type in [MODEL_PCD_DYNAMIC_EX_HII, MODEL_PCD_DYNAMIC_HII]:
+ PcdDefValue = Pcd.SkuInfoList.get(skuname).DefaultStoreDict.get(defaultstorename)
+ elif Pcd.Type in [MODEL_PCD_DYNAMIC_EX_DEFAULT,MODEL_PCD_DYNAMIC_VPD,MODEL_PCD_DYNAMIC_DEFAULT,MODEL_PCD_DYNAMIC_EX_VPD]:
+ PcdDefValue = Pcd.SkuInfoList.get(skuname).DefaultValue
+ else:
+ PcdDefValue = Pcd.DefaultValue
+ if lastoneisEmpty:
+ if "{CODE(" not in PcdDefValue:
+ sizebasevalue_plus = "(%s / sizeof(%s) + 1)" % ((DscBuildData.GetStructurePcdMaxSize(Pcd), Pcd.BaseDatumType))
+ sizebasevalue = "(%s / sizeof(%s))" % ((DscBuildData.GetStructurePcdMaxSize(Pcd), Pcd.BaseDatumType))
+ sizeof = "sizeof(%s)" % Pcd.BaseDatumType
+ CApp = ' int ArraySize = %s %% %s ? %s : %s ;\n' % ( (DscBuildData.GetStructurePcdMaxSize(Pcd), sizeof, sizebasevalue_plus, sizebasevalue))
+ CApp += ' Size = ArraySize * sizeof(%s); \n' % Pcd.BaseDatumType
+ else:
+ CApp = " Size = 0;\n"
+ else:
+ CApp = ' Size = sizeof(%s);\n' % ("".join(r_datatype) )
+ else:
+ CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)
+ CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ return CApp
+
+ def GetIndicator(self,index,FieldName,Pcd):
+ def cleanupindex(indexstr):
+ return indexstr.strip("[").strip("]").strip()
+ index_elements = ArrayIndex.findall(index)
+ pcd_capacity = Pcd.Capacity
+ if index:
+ indicator = "(Pcd"
+ if len(pcd_capacity)>2:
+ for i in range(0,len(index_elements)):
+ index_ele = index_elements[i]
+ index_num = index_ele.strip("[").strip("]").strip()
+ if i == len(index_elements) -2:
+ indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[i+1])),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]), cleanupindex(index_elements[i]))
+ break
+ else:
+ indicator += " + %d*%s*Size/sizeof(%s)/%d" %(int(cleanupindex(index_elements[i])),reduce(lambda x,y: int(x)*int(y),pcd_capacity[i+1:-1]),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]))
+ elif len(pcd_capacity) == 2:
+ indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[0])),Pcd.BaseDatumType,int(pcd_capacity[0]), index_elements[1].strip("[").strip("]").strip())
+ elif len(pcd_capacity) == 1:
+ index_ele = index_elements[0]
+ index_num = index_ele.strip("[").strip("]").strip()
+ indicator += " + %s)" % (index_num)
+ else:
+ indicator = "Pcd"
+ if FieldName:
+ indicator += "->" + FieldName
+ return indicator
+
+ def GetStarNum(self,Pcd):
+ if not Pcd.IsArray():
+ return 1
+ elif Pcd.IsSimpleTypeArray():
+ return len(Pcd.Capacity)
+ else:
+ return len(Pcd.Capacity) + 1
+ def GenerateDefaultValueAssignFunction(self, Pcd):
+ CApp = "// Default value in Dec \n"
+ CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' CHAR8 *Value;\n'
+ CApp = CApp + ' UINT32 PcdArraySize;\n'
+ DefaultValueFromDec = Pcd.DefaultValueFromDec
+ IsArray = _IsFieldValueAnArray(Pcd.DefaultValueFromDec)
+ if IsArray:
+ try:
+ DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
+ except BadExpression:
+ EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
+ (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
+ DefaultValueFromDec = StringToArray(DefaultValueFromDec)
+ Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
+ if IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ if Pcd.IsArray():
+ pcdarraysize = Pcd.PcdArraySize()
+ if "{CODE(" in Pcd.DefaultValueFromDec:
+ if Pcd.Capacity[-1] != "-1":
+ CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_INIT_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
+ CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ CApp = CApp + ' memcpy (Pcd, %s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ else:
+ if Pcd.Capacity[-1] != "-1":
+ CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
+ CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
+ CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
+ CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n'
+ else:
+ if "{CODE(" in Pcd.DefaultValueFromDec:
+ CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ CApp = CApp + ' memcpy (Pcd, &%s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ else:
+ CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
+ CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
+ elif isinstance(Value, str):
+ CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
+ for index in Pcd.DefaultValues:
+ FieldList = Pcd.DefaultValues[index]
+ if not FieldList:
+ continue
+ for FieldName in FieldList:
+ IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
+ if IsArray:
+ try:
+ FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+
+ try:
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ except Exception:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+
+ indicator = self.GetIndicator(index, FieldName,Pcd)
+ if IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
+ CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
+ elif isinstance(Value, str):
+ CApp = CApp + ' %s = %s; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ if '[' in FieldName and ']' in FieldName:
+ Index = int(FieldName.split('[')[1].split(']')[0])
+ CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
+ if ValueSize > 4:
+ CApp = CApp + ' %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ CApp = CApp + ' %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + "}\n"
+ return CApp
+
+ @staticmethod
+ def GenerateDefaultValueAssignStatement(Pcd):
+ CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ return CApp
+
+ def GetPcdDscRawDefaultValue(self,Pcd, SkuName,DefaultStoreName):
+ if Pcd.Type in PCD_DYNAMIC_TYPE_SET or Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
+ if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
+ pcddefaultvalue = Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT) if Pcd.DefaultFromDSC else None
+ else:
+ pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
+ else:
+ pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(TAB_DEFAULT_STORES_DEFAULT)
+
+ return pcddefaultvalue
+ def GetPcdDscRawValueInfo(self,Pcd, SkuName,DefaultStoreName):
+ DscValueInfo = Pcd.DscRawValueInfo.get(SkuName, {}).get(DefaultStoreName)
+ if DscValueInfo:
+ dscfilepath,lineno = DscValueInfo
+ else:
+ dscfilepath = self.MetaFile.File
+ lineno = ""
+ return dscfilepath,lineno
+
+ def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
+ CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
+ CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.BaseDatumType)
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' CHAR8 *Value;\n'
+ CApp = CApp + ' UINT32 PcdArraySize;\n'
+
+ CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
+ inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
+ dscfilepath,lineno = self.GetPcdDscRawValueInfo(Pcd, SkuName, DefaultStoreName)
+ if lineno:
+ valuefrom = "%s Line %s" % (dscfilepath,str(lineno))
+ else:
+ valuefrom = dscfilepath
+
+ pcddefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, SkuName, DefaultStoreName)
+ if pcddefaultvalue:
+ FieldList = pcddefaultvalue
+ IsArray = _IsFieldValueAnArray(FieldList)
+ if IsArray:
+ if "{CODE(" not in FieldList:
+ try:
+ FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
+ except BadExpression:
+ EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
+ (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
+ Value, ValueSize = ParseFieldValue (FieldList)
+
+ if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
+ if isinstance(Value, str):
+ if "{CODE(" in Value:
+ if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+ pcdarraysize = Pcd.PcdArraySize()
+ CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType, valuefrom)
+ CApp = CApp+ ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ else:
+ CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ if Pcd.IsArray():
+ pcdarraysize = Pcd.PcdArraySize()
+ if "{CODE(" in pcddefaultvalue:
+ if Pcd.Capacity[-1] != "-1":
+ CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+ CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ else:
+ if Pcd.Capacity[-1] != "-1":
+ CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+ CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
+ CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
+ CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n'
+ else:
+ if "{CODE(" in pcddefaultvalue:
+ CApp = CApp + ' PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' % (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
+ CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ else:
+ CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
+ CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
+ else:
+ if isinstance(Value, str):
+ if "{CODE(" in Value:
+ if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+ pcdarraysize = Pcd.PcdArraySize()
+ CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+ CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n '% (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ else:
+ CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ if Pcd.IsArray():
+ pcdarraysize = Pcd.PcdArraySize()
+ if "{CODE(" in pcddefaultvalue:
+ if Pcd.Capacity[-1] != "-1":
+ CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+ CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ else:
+ if Pcd.Capacity[-1] != "-1":
+ CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+ CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
+ CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
+ CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n'
+ else:
+ if "{CODE(" in pcddefaultvalue:
+ CApp = CApp + ' PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' % (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
+ CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+ else:
+ CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
+ CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
+
+ inheritvalue = inherit_OverrideValues.get(DefaultStoreName)
+ if not inheritvalue:
+ inheritvalue = []
+ for index in inheritvalue:
+ FieldList = inheritvalue[index]
+ if not FieldList:
+ continue
+ if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
+ for FieldName in FieldList:
+ indicator = self.GetIndicator(index, FieldName,Pcd)
+ IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
+ if IsArray:
+ try:
+ FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+ try:
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ except Exception:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
+ CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
+ else:
+ if '[' in FieldName and ']' in FieldName:
+ Index = int(FieldName.split('[')[1].split(']')[0])
+ CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
+ if ValueSize > 4:
+ CApp = CApp + ' %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ CApp = CApp + ' %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + "}\n"
+ return CApp
+
+ @staticmethod
+ def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):
+ CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)
+ return CApp
+
+ def GenerateCommandLineValue(self, Pcd):
+ CApp = "// Value in CommandLine\n"
+ CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' CHAR8 *Value;\n'
+
+ pcddefaultvalue = Pcd.PcdValueFromComm
+ for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:
+ if not FieldList:
+ continue
+ if pcddefaultvalue and FieldList == pcddefaultvalue:
+ IsArray = _IsFieldValueAnArray(FieldList)
+ if IsArray:
+ try:
+ FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
+ except BadExpression:
+ EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
+ (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
+ Value, ValueSize = ParseFieldValue (FieldList)
+
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' Value = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))
+ CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
+ continue
+ for FieldName in FieldList:
+ IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
+ if IsArray:
+ try:
+ FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+ except:
+ print("error")
+ try:
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ except Exception:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
+ CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
+ else:
+ if '[' in FieldName and ']' in FieldName:
+ Index = int(FieldName.split('[')[1].split(']')[0])
+ CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
+ if ValueSize > 4:
+ CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + "}\n"
+ return CApp
+
+ def GenerateModuleScopeValue(self, Pcd):
+ CApp = "// Value in Dsc Module scope \n"
+ for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
+
+ CApp = CApp + "void Assign_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, ModuleGuid,Pcd.BaseDatumType)
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' CHAR8 *Value;\n'
+ pcddefaultvalue, file_path,lineNo = Pcd.PcdValueFromComponents.get(ModuleGuid,(None,None,None))
+
+ if pcddefaultvalue:
+ IsArray = _IsFieldValueAnArray(pcddefaultvalue)
+ if IsArray:
+ try:
+ FieldList = ValueExpressionEx(pcddefaultvalue, TAB_VOID)(True)
+ except BadExpression:
+ EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from %s Line %s: %s" %
+ (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, file_path, lineNo, FieldList))
+ Value, ValueSize = ParseFieldValue (FieldList)
+
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd = %s; // From %s Line %s \n' % (Value, file_path, lineNo)
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' Value = %s; // From %s Line %s.\n' % (DscBuildData.IntToCString(Value, ValueSize), file_path, lineNo)
+ CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
+
+
+ PcdFiledValue = Pcd.PcdFiledValueFromDscComponent.get(ModuleGuid)
+ for index in PcdFiledValue:
+ FieldList = PcdFiledValue[index]
+ if not FieldList:
+ continue
+ for FieldName in FieldList:
+ IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
+ if IsArray:
+ try:
+ FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+ except:
+ print("error")
+ try:
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ except Exception:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
+ CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
+ else:
+ if '[' in FieldName and ']' in FieldName:
+ Index = int(FieldName.split('[')[1].split(']')[0])
+ CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
+ if ValueSize > 4:
+ CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + "}\n"
+ return CApp
+
+ @staticmethod
+ def GenerateCommandLineValueStatement(Pcd):
+ CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ return CApp
+ def GenerateFdfValue(self,Pcd):
+ CApp = "// Value in Fdf\n"
+ CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.BaseDatumType)
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' CHAR8 *Value;\n'
+
+ pcddefaultvalue = Pcd.PcdValueFromFdf
+ for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
+ if not FieldList:
+ continue
+ if pcddefaultvalue and FieldList == pcddefaultvalue:
+ IsArray = _IsFieldValueAnArray(FieldList)
+ if IsArray:
+ try:
+ FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
+ except BadExpression:
+ EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
+ (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
+ Value, ValueSize = ParseFieldValue (FieldList)
+
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd = %s; // From Fdf \n' % (Value)
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' Value = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
+ CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
+ continue
+ for FieldName in FieldList:
+ IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
+ if IsArray:
+ try:
+ FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
+ except BadExpression:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+ (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+ except:
+ print("error")
+ try:
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ except Exception:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
+ CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
+ else:
+ if '[' in FieldName and ']' in FieldName:
+ Index = int(FieldName.split('[')[1].split(']')[0])
+ CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
+ if ValueSize > 4:
+ CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ CApp = CApp + ' Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + "}\n"
+ return CApp
+
+ @staticmethod
+ def GenerateFdfValueStatement(Pcd):
+ CApp = ' Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ return CApp
+
+ @staticmethod
+ def GenerateModuleValueStatement(module_guid, Pcd):
+ CApp = " Assign_%s_%s_%s_Value(Pcd);\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, module_guid)
+ return CApp
+ def GenerateModuleScopeInitializeFunc(self,SkuName, Pcd, InitByteValue, CApp):
+ for module_guid in Pcd.PcdFiledValueFromDscComponent:
+ CApp = CApp + 'void\n'
+ CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ CApp = CApp + ' void\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ CApp = CApp + ' UINT32 Size;\n'
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' CHAR8 *Value;\n'
+ CApp = CApp + ' UINT32 OriginalSize;\n'
+ CApp = CApp + ' VOID *OriginalPcd;\n'
+
+ CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
+
+ CApp = CApp + '\n'
+
+ PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip())
+ InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
+ #
+ # Get current PCD value and size
+ #
+ CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+ #
+ # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
+ # the correct value. For structures with a flexible array member, the flexible
+ # array member is detected, and the size is based on the highest index used with
+ # the flexible array member. The flexible array member must be the last field
+ # in a structure. The size formula for this case is:
+ # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
+ #
+ CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd,SkuName,TAB_DEFAULT_STORES_DEFAULT)
+ if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+ CApp = CApp + ' OriginalSize = OriginalSize < sizeof(%s) * %d? OriginalSize:sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySize())
+ CApp = CApp + ' Size = sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize())
+
+ #
+ # Allocate and zero buffer for the PCD
+ # Must handle cases where current value is smaller, larger, or same size
+ # Always keep that larger one as the current size
+ #
+ CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
+ CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.BaseDatumType,)
+ CApp = CApp + ' memset (Pcd, 0, Size);\n'
+
+ #
+ # Copy current PCD value into allocated buffer.
+ #
+ CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
+
+ #
+ # Assign field values in PCD
+ #
+ CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
+
+ CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
+ CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
+ CApp = CApp + DscBuildData.GenerateModuleValueStatement(module_guid,Pcd)
+ CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
+ CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
+
+ #
+ # Set new PCD value and size
+ #
+ CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+ #
+ # Free PCD
+ #
+ CApp = CApp + ' free (Pcd);\n'
+ CApp = CApp + '}\n'
+ CApp = CApp + '\n'
+ return InitByteValue,CApp
+
+ def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
+ OverrideValues = {DefaultStore:{}}
+ if Pcd.SkuOverrideValues:
+ OverrideValues = Pcd.SkuOverrideValues[SkuName]
+ if not OverrideValues:
+ OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}
+ for DefaultStoreName in OverrideValues:
+ CApp = CApp + 'void\n'
+ CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ CApp = CApp + ' void\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ CApp = CApp + ' UINT32 Size;\n'
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' CHAR8 *Value;\n'
+ CApp = CApp + ' UINT32 OriginalSize;\n'
+ CApp = CApp + ' VOID *OriginalPcd;\n'
+
+ CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
+
+ CApp = CApp + '\n'
+
+ PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip())
+
+ InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
+
+ #
+ # Get current PCD value and size
+ #
+ CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+ #
+ # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
+ # the correct value. For structures with a flexible array member, the flexible
+ # array member is detected, and the size is based on the highest index used with
+ # the flexible array member. The flexible array member must be the last field
+ # in a structure. The size formula for this case is:
+ # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
+ #
+ CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd,SkuName,DefaultStoreName)
+ if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+ CApp = CApp + ' OriginalSize = OriginalSize < sizeof(%s) * %d? OriginalSize:sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySize())
+ CApp = CApp + ' Size = sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize())
+
+ #
+ # Allocate and zero buffer for the PCD
+ # Must handle cases where current value is smaller, larger, or same size
+ # Always keep that larger one as the current size
+ #
+ CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
+ CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.BaseDatumType,)
+ CApp = CApp + ' memset (Pcd, 0, Size);\n'
+
+ #
+ # Copy current PCD value into allocated buffer.
+ #
+ CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
+
+ #
+ # Assign field values in PCD
+ #
+ CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
+ if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
+ for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
+ storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]
+ for defaultstorenameitem in storeset:
+ CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
+ CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)
+ if skuname == SkuName:
+ break
+ else:
+ CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
+ CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
+ CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
+ CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
+ #
+ # Set new PCD value and size
+ #
+ CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+ #
+ # Free PCD
+ #
+ CApp = CApp + ' free (Pcd);\n'
+ CApp = CApp + '}\n'
+ CApp = CApp + '\n'
+ return InitByteValue, CApp
+
+ def GenerateArrayAssignment(self, Pcd):
+ CApp = ""
+ if not Pcd:
+ return CApp
+ Demesion = ""
+ for d in Pcd.Capacity:
+ Demesion += "[]"
+
+ Value = Pcd.DefaultValueFromDec
+ if "{CODE(" in Pcd.DefaultValueFromDec:
+ realvalue = Pcd.DefaultValueFromDec.strip()[6:-2] # "{CODE(").rstrip(")}"
+ CApp += "static %s %s_%s_INIT_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demesion,realvalue)
+
+ if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
+ for skuname in Pcd.SkuInfoList:
+ skuinfo = Pcd.SkuInfoList[skuname]
+ if skuinfo.VariableName:
+ for defaultstore in skuinfo.DefaultStoreDict:
+ pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, skuname, defaultstore)
+ if pcddscrawdefaultvalue:
+ Value = skuinfo.DefaultStoreDict[defaultstore]
+ if "{CODE(" in Value:
+ realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
+ CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Demesion,realvalue)
+ else:
+ pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, skuname, TAB_DEFAULT_STORES_DEFAULT)
+ if pcddscrawdefaultvalue:
+ Value = skuinfo.DefaultValue
+ if "{CODE(" in Value:
+ realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
+ CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Demesion,realvalue)
+ else:
+ pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
+ if pcddscrawdefaultvalue:
+ if "{CODE(" in Pcd.DefaultValue:
+ realvalue = Pcd.DefaultValue.strip()[6:-2] # "{CODE(").rstrip(")}"
+ CApp += "static %s %s_%s_DEFAULT_STANDARD_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demesion,realvalue)
+
+ return CApp
+
+ def SkuOverrideValuesEmpty(self,OverrideValues):
+ if not OverrideValues:
+ return True
+ for key in OverrideValues:
+ if OverrideValues[key]:
+ return False
+ return True
+
+ def ParseCCFlags(self, ccflag):
+ ccflags = set()
+ ccflaglist = ccflag.split(" ")
+ i = 0
+ while i < len(ccflaglist):
+ item = ccflaglist[i].strip()
+ if item in (r"/D", r"/U","-D","-U"):
+ ccflags.add(" ".join((ccflaglist[i],ccflaglist[i+1])))
+ i = i+1
+ elif item.startswith((r"/D", r"/U","-D","-U")):
+ ccflags.add(item)
+ i +=1
+ return ccflags
+
+ def GetStructurePcdSet (self, OutputValueFile):
+ if not os.path.isfile(OutputValueFile):
+ EdkLogger.error("GetStructurePcdSet", FILE_NOT_FOUND, "Output.txt doesn't exist", ExtraData=OutputValueFile)
+ return []
+ File = open (OutputValueFile, 'r')
+ FileBuffer = File.readlines()
+ File.close()
+
+ #start update structure pcd final value
+ StructurePcdSet = []
+ for Pcd in FileBuffer:
+ PcdValue = Pcd.split ('|')
+ PcdInfo = PcdValue[0].split ('.')
+ StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
+ return StructurePcdSet
+
+ def GetBuildOptionsValueList(self):
+ CC_FLAGS = LinuxCFLAGS
+ if sys.platform == "win32":
+ CC_FLAGS = WindowsCFLAGS
+ BuildOptions = OrderedDict()
+ for Options in self.BuildOptions:
+ if Options[2] != EDKII_NAME:
+ continue
+ Family = Options[0]
+ if Family and Family != self.ToolChainFamily:
+ continue
+ Target, Tag, Arch, Tool, Attr = Options[1].split("_")
+ if Tool != 'CC':
+ continue
+ if Attr != "FLAGS":
+ continue
+ if Target == TAB_STAR or Target == self._Target:
+ if Tag == TAB_STAR or Tag == self._Toolchain:
+ if 'COMMON' not in BuildOptions:
+ BuildOptions['COMMON'] = set()
+ if Arch == TAB_STAR:
+ BuildOptions['COMMON']|= self.ParseCCFlags(self.BuildOptions[Options])
+ if Arch in self.SupArchList:
+ if Arch not in BuildOptions:
+ BuildOptions[Arch] = set()
+ BuildOptions[Arch] |= self.ParseCCFlags(self.BuildOptions[Options])
+
+ if BuildOptions:
+ ArchBuildOptions = {arch:flags for arch,flags in BuildOptions.items() if arch != 'COMMON'}
+ if len(ArchBuildOptions.keys()) == 1:
+ BuildOptions['COMMON'] |= (list(ArchBuildOptions.values())[0])
+ elif len(ArchBuildOptions.keys()) > 1:
+ CommonBuildOptions = reduce(lambda x,y: x&y, ArchBuildOptions.values())
+ BuildOptions['COMMON'] |= CommonBuildOptions
+ ValueList = [item for item in BuildOptions['COMMON'] if item.startswith((r"/U","-U"))]
+ ValueList.extend([item for item in BuildOptions['COMMON'] if item.startswith((r"/D", "-D"))])
+ CC_FLAGS += " ".join(ValueList)
+ return CC_FLAGS
+
+
+ def GenerateByteArrayValue (self, StructuredPcds):
+ #
+ # Generate/Compile/Run C application to determine if there are any flexible array members
+ #
+ if not StructuredPcds:
+ return
+
+ StructuredPcdsData = {}
+ StoredStructuredPcdObjectPaths = {}
+ SkipPcdValueInit = False
+
+ CC_FLAGS = self.GetBuildOptionsValueList()
+
+ for PcdName in StructuredPcds:
+ Pcd = StructuredPcds[PcdName]
+ TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
+ TokenCName = Pcd.TokenCName
+
+ # Create a key using TokenSpaceGuidCName and TokenCName
+ StructuredPcdsData[f"{TokenSpaceGuidCName}_{TokenCName}"] = {
+ "DefaultValueFromDec": Pcd.DefaultValueFromDec,
+ "DefaultValues": Pcd.DefaultValues,
+ "PcdFieldValueFromComm": Pcd.PcdFieldValueFromComm,
+ "PcdFieldValueFromFdf": Pcd.PcdFieldValueFromFdf,
+ "DefaultFromDSC": Pcd.DefaultFromDSC,
+ "PcdFiledValueFromDscComponent": Pcd.PcdFiledValueFromDscComponent
+ }
+
+ # Store the CC Flags
+ StructuredPcdsData["CC_FLAGS"] = CC_FLAGS
+ #
+ # If the output path doesn't exists then create it
+ #
+ if not os.path.exists(self.OutputPath):
+ os.makedirs(self.OutputPath)
+
+ StructuredPcdsDataPath = os.path.join(self.OutputPath, self._Arch, StructuredPcdsDataName)
+ PcdRecordOutputValueFile = os.path.join(self.OutputPath, self._Arch, 'Output.txt')
+
+ if not os.path.exists(os.path.dirname(StructuredPcdsDataPath)):
+ os.makedirs(os.path.dirname(StructuredPcdsDataPath))
+ #
+ # Check if the StructuredPcdsData.json exists or not
+ # if exits then it might be a incremental build then check if the StructuredPcdsData has been changed or not.
+ # if changed then proceed further, if not changed then return the stored data from earlier build
+ #
+ if os.path.isfile(StructuredPcdsDataPath):
+ with open(StructuredPcdsDataPath, 'r') as file:
+ StoredStructuredPcdsData = json.load(file)
+ # OBJECTS will have the modified time, which needs to be checked later
+ StoredStructuredPcdObjectPaths = StoredStructuredPcdsData.pop("OBJECTS", {})
+
+ if StructuredPcdsData == StoredStructuredPcdsData:
+ SkipPcdValueInit = True
+ for filename, file_mtime in StoredStructuredPcdObjectPaths.items():
+ f_mtime = os.path.getmtime(filename)
+ #
+ # check if the include_file are modified or not,
+ # if modified then generate the PcdValueInit
+ #
+ if f_mtime != file_mtime:
+ SkipPcdValueInit = False
+ break
+
+ if SkipPcdValueInit:
+ return self.GetStructurePcdSet(PcdRecordOutputValueFile)
+
+ InitByteValue = ""
+ CApp = PcdMainCHeader
+
+ IncludeFiles = set()
+ for PcdName in StructuredPcds:
+ Pcd = StructuredPcds[PcdName]
+ for IncludeFile in Pcd.StructuredPcdIncludeFile:
+ if IncludeFile not in IncludeFiles:
+ IncludeFiles.add(IncludeFile)
+ CApp = CApp + '#include <%s>\n' % (IncludeFile)
+ CApp = CApp + '\n'
+ for Pcd in StructuredPcds.values():
+ CApp = CApp + self.GenerateArrayAssignment(Pcd)
+ for PcdName in sorted(StructuredPcds.keys()):
+ Pcd = StructuredPcds[PcdName]
+
+ #create void void Cal_tocken_cname_Size functions
+ CApp = CApp + self.GenerateSizeFunction(Pcd)
+
+ #create void Assign_ functions
+
+ # From DEC
+ CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
+ # From Fdf
+ CApp = CApp + self.GenerateFdfValue(Pcd)
+ # From CommandLine
+ CApp = CApp + self.GenerateCommandLineValue(Pcd)
+
+ # From Dsc Global setting
+ if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
+ CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
+ else:
+ for SkuName in self.SkuIdMgr.SkuOverrideOrder():
+ if SkuName not in Pcd.SkuOverrideValues:
+ continue
+ for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
+ CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
+
+ # From Dsc module scope setting
+ CApp = CApp + self.GenerateModuleScopeValue(Pcd)
+
+ #create Initialize_ functions
+ if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
+ InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
+ InitByteValue, CApp = self.GenerateModuleScopeInitializeFunc(self.SkuIdMgr.SystemSkuId,Pcd,InitByteValue,CApp)
+ else:
+ for SkuName in self.SkuIdMgr.SkuOverrideOrder():
+ if SkuName not in Pcd.SkuOverrideValues:
+ continue
+ for DefaultStoreName in Pcd.DefaultStoreName:
+ Pcd = StructuredPcds[PcdName]
+ InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
+
+ CApp = CApp + 'VOID\n'
+ CApp = CApp + 'PcdEntryPoint(\n'
+ CApp = CApp + ' VOID\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ for Pcd in StructuredPcds.values():
+ if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
+ CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
+ CApp += " Initialize_%s_%s_%s_%s();\n" % (ModuleGuid,TAB_DEFAULT_STORES_DEFAULT ,Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ else:
+ for SkuName in self.SkuIdMgr.SkuOverrideOrder():
+ if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
+ continue
+ for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
+ CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ CApp = CApp + '}\n'
+
+ CApp = CApp + PcdMainCEntry + '\n'
+
+ CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
+ SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
+
+ # start generating makefile
+ MakeApp = PcdMakefileHeader
+ if sys.platform == "win32":
+ MakeApp = MakeApp + 'APPFILE = %s\\%s.exe\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\\%s.obj %s.obj\n' % (self.OutputPath, PcdValueInitName, os.path.join(self.OutputPath, PcdValueCommonName)) + 'INC = '
+ else:
+ MakeApp = MakeApp + PcdGccMakefile
+ MakeApp = MakeApp + 'APPFILE = %s/%s\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o %s.o\n' % (self.OutputPath, PcdValueInitName, os.path.join(self.OutputPath, PcdValueCommonName)) + \
+ 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'TOOL_INCLUDE +='
+
+ IncSearchList = []
+ PlatformInc = OrderedDict()
+ for Cache in self._Bdb._CACHE_.values():
+ if Cache.MetaFile.Ext.lower() != '.dec':
+ continue
+ if Cache.Includes:
+ if str(Cache.MetaFile.Path) not in PlatformInc:
+ PlatformInc[str(Cache.MetaFile.Path)] = []
+ PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
+ PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
+
+ PcdDependDEC = []
+ for Pcd in StructuredPcds.values():
+ for PackageDec in Pcd.PackageDecs:
+ Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
+ if not os.path.exists(Package):
+ EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ if Package not in PcdDependDEC:
+ PcdDependDEC.append(Package)
+
+ if PlatformInc and PcdDependDEC:
+ for pkg in PcdDependDEC:
+ if pkg in PlatformInc:
+ for inc in PlatformInc[pkg]:
+ #
+ # Get list of files in potential -I include path
+ #
+ FileList = os.listdir (str(inc))
+ #
+ # Skip -I include path if one of the include files required
+ # by PcdValueInit.c are present in the include paths from
+ # the DEC file. PcdValueInit.c must use the standard include
+ # files from the host compiler.
+ #
+ if 'stdio.h' in FileList:
+ continue
+ if 'stdlib.h' in FileList:
+ continue
+ if 'string.h' in FileList:
+ continue
+ MakeApp += '-I' + str(inc) + ' '
+ IncSearchList.append(inc)
+ MakeApp = MakeApp + '\n'
+
+ MakeApp += CC_FLAGS
+
+ if sys.platform == "win32":
+ MakeApp = MakeApp + PcdMakefileEnd
+ MakeApp = MakeApp + AppTarget % ("""\tcopy $(APPLICATION) $(APPFILE) /y """)
+ else:
+ MakeApp = MakeApp + AppTarget % ("""\tcp -p $(APPLICATION) $(APPFILE) """)
+ MakeApp = MakeApp + '\n'
+ IncludeFileFullPaths = []
+ for includefile in IncludeFiles:
+ for includepath in IncSearchList:
+ includefullpath = os.path.join(str(includepath), includefile)
+ if os.path.exists(includefullpath):
+ IncludeFileFullPaths.append(os.path.normpath(includefullpath))
+ break
+ SearchPathList = []
+ SearchPathList.append(os.path.normpath(mws.join(GlobalData.gGlobalDefines["EDK_TOOLS_PATH"], "BaseTools/Source/C/Include")))
+ SearchPathList.append(os.path.normpath(mws.join(GlobalData.gGlobalDefines["EDK_TOOLS_PATH"], "BaseTools/Source/C/Common")))
+ SearchPathList.extend(str(item) for item in IncSearchList)
+ IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)
+ StructuredPcdsData["OBJECTS"] = {}
+ for include_file in IncFileList:
+ StructuredPcdsData["OBJECTS"][include_file] = os.path.getmtime(include_file)
+ MakeApp += "$(OBJECTS) : %s\n" % include_file
+ if sys.platform == "win32":
+ PcdValueCommonPath = os.path.normpath(mws.join(GlobalData.gGlobalDefines["EDK_TOOLS_PATH"], "Source\\C\\Common\\PcdValueCommon.c"))
+ MakeApp = MakeApp + '%s\\PcdValueCommon.c : %s\n' % (self.OutputPath, PcdValueCommonPath)
+ MakeApp = MakeApp + '\tcopy /y %s $@\n' % (PcdValueCommonPath)
+ else:
+ PcdValueCommonPath = os.path.normpath(mws.join(GlobalData.gGlobalDefines["EDK_TOOLS_PATH"], "Source/C/Common/PcdValueCommon.c"))
+ MakeApp = MakeApp + '%s/PcdValueCommon.c : %s\n' % (self.OutputPath, PcdValueCommonPath)
+ MakeApp = MakeApp + '\tcp -p -f %s %s/PcdValueCommon.c\n' % (PcdValueCommonPath, self.OutputPath)
+ MakeFileName = os.path.join(self.OutputPath, 'Makefile')
+ MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
+ SaveFileOnChange(MakeFileName, MakeApp, False)
+
+ # start generating input file
+ InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
+ OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
+ SaveFileOnChange(InputValueFile, InitByteValue, False)
+
+ Dest_PcdValueInitExe = PcdValueInitName
+ if not sys.platform == "win32":
+ Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName)
+ else:
+ Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName) +".exe"
+
+ #start building the structure pcd value tool
+ Messages = ''
+ if sys.platform == "win32":
+ MakeCommand = 'nmake -f %s' % (MakeFileName)
+ returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
+ Messages = StdOut
+ else:
+ MakeCommand = 'make -f %s' % (MakeFileName)
+ returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
+ Messages = StdErr
+
+ EdkLogger.verbose ('%s\n%s\n%s' % (MakeCommand, StdOut, StdErr))
+ Messages = Messages.split('\n')
+ MessageGroup = []
+ if returncode != 0:
+ CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
+ File = open (CAppBaseFileName + '.c', 'r')
+ FileData = File.readlines()
+ File.close()
+ for Message in Messages:
+ if " error" in Message or "warning" in Message:
+ try:
+ FileInfo = Message.strip().split('(')
+ if len (FileInfo) > 1:
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1].split (')')[0]
+ else:
+ FileInfo = Message.strip().split(':')
+ if len(FileInfo) < 2:
+ continue
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1]
+ except:
+ continue
+ if "PcdValueInit.c" not in FileName:
+ continue
+ if FileLine.isdigit():
+ error_line = FileData[int (FileLine) - 1]
+ if r"//" in error_line:
+ c_line, dsc_line = error_line.split(r"//")
+ else:
+ dsc_line = error_line
+ message_itmes = Message.split(":")
+ Index = 0
+ if "PcdValueInit.c" not in Message:
+ if not MessageGroup:
+ MessageGroup.append(Message)
+ break
+ else:
+ for item in message_itmes:
+ if "PcdValueInit.c" in item:
+ Index = message_itmes.index(item)
+ message_itmes[Index] = dsc_line.strip()
+ break
+ MessageGroup.append(":".join(message_itmes[Index:]).strip())
+ continue
+ else:
+ MessageGroup.append(Message)
+ if MessageGroup:
+ EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
+ else:
+ EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s\n%s\n%s' % (MakeCommand, StdOut, StdErr))
+
+ #start executing the structure pcd value tool
+ if DscBuildData.NeedUpdateOutput(OutputValueFile, Dest_PcdValueInitExe, InputValueFile):
+ Command = Dest_PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
+ returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
+ EdkLogger.verbose ('%s\n%s\n%s' % (Command, StdOut, StdErr))
+ if returncode != 0:
+ EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s\n%s\n%s\n' % (Command, StdOut, StdErr))
+
+ #
+ # In 1st build create the StructuredPcdsData.json
+ # update the record as PCD Input has been changed if its incremental build
+ #
+ with open(StructuredPcdsDataPath, 'w') as file:
+ json.dump(StructuredPcdsData, file, indent=2)
+
+ # Copy update output file for each Arch
+ shutil.copyfile(OutputValueFile, PcdRecordOutputValueFile)
+
+ #start update structure pcd final value
+ return self.GetStructurePcdSet(OutputValueFile)
+
+ @staticmethod
+ def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):
+ if not os.path.exists(OutputFile):
+ return True
+ if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
+ return True
+ if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
+ return True
+ return False
+
+ ## Retrieve dynamic PCD settings
+ #
+ # @param Type PCD type
+ #
+ # @retval a dict object contains settings of given PCD type
+ #
+ def _GetDynamicPcd(self, Type):
+
+
+ Pcds = OrderedDict()
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # PCD settings for certain ARCH and SKU
+ #
+ PcdDict = tdict(True, 4)
+ PcdList = []
+ # Find out all possible PCD candidates for self._Arch
+ RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = copy.copy(self.SkuIds)
+
+
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
+ SkuName = SkuName.upper()
+ SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
+ if SkuName not in AvailableSkuIdSet:
+ EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
+ File=self.MetaFile, Line=Dummy5)
+ if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
+ PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
+ PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
+
+ # Remove redundant PCD candidates, per the ARCH and SKU
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
+
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
+ if Setting is None:
+ continue
+
+ PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ if MaxDatumSize:
+ if int(MaxDatumSize, 0) > 0xFFFF:
+ EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
+ File=self.MetaFile, Line=Dummy4)
+ if int(MaxDatumSize, 0) < 0:
+ EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
+ File=self.MetaFile, Line=Dummy4)
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
+ if (PcdCName, TokenSpaceGuid) in Pcds:
+ pcdObject = Pcds[PcdCName, TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ if MaxDatumSize.strip():
+ CurrentMaxSize = int(MaxDatumSize.strip(), 0)
+ else:
+ CurrentMaxSize = 0
+ if pcdObject.MaxDatumSize:
+ PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
+ else:
+ PcdMaxSize = 0
+ if CurrentMaxSize > PcdMaxSize:
+ pcdObject.MaxDatumSize = str(CurrentMaxSize)
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ DatumType,
+ PcdValue,
+ '',
+ MaxDatumSize,
+ OrderedDict({SkuName : SkuInfo}),
+ False,
+ None,
+ IsDsc=True)
+
+ if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4)
+
+ for pcd in Pcds.values():
+ pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
+ # Only fix the value while no value provided in DSC file.
+ for sku in pcd.SkuInfoList.values():
+ if not sku.DefaultValue:
+ sku.DefaultValue = pcdDecObject.DefaultValue
+ if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)
+ pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
+ elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
+ pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
+ del pcd.SkuInfoList[TAB_COMMON]
+ elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
+ del pcd.SkuInfoList[TAB_COMMON]
+
+ list(map(self.FilterSkuSettings, Pcds.values()))
+
+ return Pcds
+
+ def FilterSkuSettings(self, PcdObj):
+
+ if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
+ if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:
+ PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]
+ PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
+ PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT
+ PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'
+
+ elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
+ PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}
+
+ return PcdObj
+
+ @staticmethod
+ def CompareVarAttr(Attr1, Attr2):
+ if not Attr1 or not Attr2: # for empty string
+ return True
+ Attr1s = [attr.strip() for attr in Attr1.split(",")]
+ Attr1Set = set(Attr1s)
+ Attr2s = [attr.strip() for attr in Attr2.split(",")]
+ Attr2Set = set(Attr2s)
+ if Attr2Set == Attr1Set:
+ return True
+ else:
+ return False
+
+ def CompletePcdValues(self, PcdSet):
+ Pcds = OrderedDict()
+ DefaultStoreObj = DefaultStore(self._GetDefaultStores())
+ SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}
+ DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)
+ for PcdCName, TokenSpaceGuid in PcdSet:
+ PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
+
+ if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
+ Pcds[PcdCName, TokenSpaceGuid]= PcdObj
+ continue
+ PcdType = PcdObj.Type
+ if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ for skuid in PcdObj.SkuInfoList:
+ skuobj = PcdObj.SkuInfoList[skuid]
+ mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
+ for defaultstorename in DefaultStores:
+ if defaultstorename not in skuobj.DefaultStoreDict:
+ skuobj.DefaultStoreDict[defaultstorename] = skuobj.DefaultStoreDict[mindefaultstorename]
+ skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
+ for skuname, skuid in SkuIds.items():
+ if skuname not in PcdObj.SkuInfoList:
+ nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
+ while nextskuid not in PcdObj.SkuInfoList:
+ nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
+ PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
+ PcdObj.SkuInfoList[skuname].SkuId = skuid
+ PcdObj.SkuInfoList[skuname].SkuIdName = skuname
+ if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ PcdObj.DefaultValue = list(PcdObj.SkuInfoList.values())[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue
+ Pcds[PcdCName, TokenSpaceGuid]= PcdObj
+ return Pcds
+ ## Retrieve dynamic HII PCD settings
+ #
+ # @param Type PCD type
+ #
+ # @retval a dict object contains settings of given PCD type
+ #
+ def _GetDynamicHiiPcd(self, Type):
+
+ VariableAttrs = {}
+
+ Pcds = OrderedDict()
+ UserDefinedDefaultStores = []
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # PCD settings for certain ARCH and SKU
+ #
+ PcdDict = tdict(True, 5)
+ PcdList = []
+ RecordList = self._RawData[Type, self._Arch]
+ # Find out all possible PCD candidates for self._Arch
+ AvailableSkuIdSet = copy.copy(self.SkuIds)
+ DefaultStoresDefine = self._GetDefaultStores()
+
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:
+ SkuName = SkuName.upper()
+ SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
+ DefaultStore = DefaultStore.upper()
+ if DefaultStore == TAB_COMMON:
+ DefaultStore = TAB_DEFAULT_STORES_DEFAULT
+ else:
+ #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
+ UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))
+ if SkuName not in AvailableSkuIdSet:
+ EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
+ File=self.MetaFile, Line=Dummy5)
+ if DefaultStore not in DefaultStoresDefine:
+ EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
+ File=self.MetaFile, Line=Dummy5)
+ if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5) not in PcdList:
+ PcdList.append((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
+ PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
+
+
+ # Remove redundant PCD candidates, per the ARCH and SKU
+ for index,(PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4) in enumerate(PcdList):
+
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]
+ if Setting is None:
+ continue
+ VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+
+ rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
+ if not rt:
+ EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
+ ExtraData="[%s]" % VarAttribute)
+ ExceedMax = False
+ FormatCorrect = True
+ if VariableOffset.isdigit():
+ if int(VariableOffset, 10) > 0xFFFF:
+ ExceedMax = True
+ elif variablePattern.match(VariableOffset):
+ if int(VariableOffset, 16) > 0xFFFF:
+ ExceedMax = True
+ # For Offset written in "A.B"
+ elif VariableOffset.find('.') > -1:
+ VariableOffsetList = VariableOffset.split(".")
+ if not (len(VariableOffsetList) == 2
+ and IsValidWord(VariableOffsetList[0])
+ and IsValidWord(VariableOffsetList[1])):
+ FormatCorrect = False
+ else:
+ FormatCorrect = False
+ if not FormatCorrect:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
+
+ if ExceedMax:
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
+ if (VariableName, VariableGuid) not in VariableAttrs:
+ VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
+ else:
+ if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
+ EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))
+
+ pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
+ if (PcdCName, TokenSpaceGuid) in Pcds:
+ pcdObject = Pcds[PcdCName, TokenSpaceGuid]
+ if SkuName in pcdObject.SkuInfoList:
+ Skuitem = pcdObject.SkuInfoList[SkuName]
+ Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
+ else:
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ else:
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
+ PcdClassObj = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ '',
+ DefaultValue,
+ '',
+ '',
+ OrderedDict({SkuName : SkuInfo}),
+ False,
+ None,
+ pcdDecObject.validateranges,
+ pcdDecObject.validlists,
+ pcdDecObject.expressions,
+ IsDsc=True)
+ if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:
+ PcdClassObj.UserDefinedDefaultStoresFlag = True
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
+
+ Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = index
+ if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][DefaultStore] = (self.MetaFile.File,Dummy4)
+ for pcd in Pcds.values():
+ pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
+ pcd.DatumType = pcdDecObject.DatumType
+ # Only fix the value while no value provided in DSC file.
+ for sku in pcd.SkuInfoList.values():
+ if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
+ sku.HiiDefaultValue = pcdDecObject.DefaultValue
+ for default_store in sku.DefaultStoreDict:
+ sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
+ pcd.DefaultValue = pcdDecObject.DefaultValue
+ if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
+ SkuInfoObj = list(pcd.SkuInfoList.values())[0]
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})
+ pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
+ elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
+ pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
+ del pcd.SkuInfoList[TAB_COMMON]
+ elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
+ del pcd.SkuInfoList[TAB_COMMON]
+
+ if pcd.MaxDatumSize.strip():
+ MaxSize = int(pcd.MaxDatumSize, 0)
+ else:
+ MaxSize = 0
+ if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
+ for (_, skuobj) in pcd.SkuInfoList.items():
+ datalen = 0
+ skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
+ datalen = len(skuobj.HiiDefaultValue.split(","))
+ if datalen > MaxSize:
+ MaxSize = datalen
+ for defaultst in skuobj.DefaultStoreDict:
+ skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
+ pcd.DefaultValue = StringToArray(pcd.DefaultValue)
+ pcd.MaxDatumSize = str(MaxSize)
+ rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)
+ if not rt:
+ invalidpcd = ",".join(invalidhii)
+ EdkLogger.error('build', PCD_VARIABLE_INFO_ERROR, Message='The same HII PCD must map to the same EFI variable for all SKUs', File=self.MetaFile, ExtraData=invalidpcd)
+
+ list(map(self.FilterSkuSettings, Pcds.values()))
+
+ return Pcds
+
+ @staticmethod
+ def CheckVariableNameAssignment(Pcds):
+ invalidhii = []
+ for pcdname in Pcds:
+ pcd = Pcds[pcdname]
+ varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())
+ if len(varnameset) > 1:
+ invalidhii.append(".".join((pcdname[1], pcdname[0])))
+ if len(invalidhii):
+ return False, invalidhii
+ else:
+ return True, []
+ ## Retrieve dynamic VPD PCD settings
+ #
+ # @param Type PCD type
+ #
+ # @retval a dict object contains settings of given PCD type
+ #
+ def _GetDynamicVpdPcd(self, Type):
+
+
+ Pcds = OrderedDict()
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # PCD settings for certain ARCH and SKU
+ #
+ PcdDict = tdict(True, 4)
+ PcdList = []
+
+ # Find out all possible PCD candidates for self._Arch
+ RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = copy.copy(self.SkuIds)
+
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
+ SkuName = SkuName.upper()
+ SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
+ if SkuName not in AvailableSkuIdSet:
+ EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
+ File=self.MetaFile, Line=Dummy5)
+ if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
+ PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
+ PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
+
+ # Remove redundant PCD candidates, per the ARCH and SKU
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
+ if Setting is None:
+ continue
+ #
+ # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
+ # For the Integer & Boolean type, the optional data can only be InitialValue.
+ # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
+ # until the DEC parser has been called.
+ #
+ VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ if MaxDatumSize:
+ if int(MaxDatumSize, 0) > 0xFFFF:
+ EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
+ File=self.MetaFile, Line=Dummy4)
+ if int(MaxDatumSize, 0) < 0:
+ EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
+ File=self.MetaFile, Line=Dummy4)
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
+ if (PcdCName, TokenSpaceGuid) in Pcds:
+ pcdObject = Pcds[PcdCName, TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ if MaxDatumSize.strip():
+ CurrentMaxSize = int(MaxDatumSize.strip(), 0)
+ else:
+ CurrentMaxSize = 0
+ if pcdObject.MaxDatumSize:
+ PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
+ else:
+ PcdMaxSize = 0
+ if CurrentMaxSize > PcdMaxSize:
+ pcdObject.MaxDatumSize = str(CurrentMaxSize)
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ '',
+ InitialValue,
+ '',
+ MaxDatumSize,
+ OrderedDict({SkuName : SkuInfo}),
+ False,
+ None,
+ IsDsc=True)
+
+ if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
+ Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4)
+ for pcd in Pcds.values():
+ pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
+ pcd.DatumType = pcdDecObject.DatumType
+ # Only fix the value while no value provided in DSC file.
+ for sku in pcd.SkuInfoList.values():
+ if not sku.DefaultValue:
+ sku.DefaultValue = pcdDecObject.DefaultValue
+ if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
+ SkuInfoObj = list(pcd.SkuInfoList.values())[0]
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
+ pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
+ elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
+ pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
+ del pcd.SkuInfoList[TAB_COMMON]
+ elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
+ del pcd.SkuInfoList[TAB_COMMON]
+
+ #For the same one VOID* pcd, if the default value type of one SKU is "Unicode string",
+ #the other SKUs are "OtherVOID*"(ASCII string or byte array),Then convert "Unicode string" to "byte array".
+ for pcd in Pcds.values():
+ PcdValueTypeSet = set()
+ for sku in pcd.SkuInfoList.values():
+ PcdValueTypeSet.add("UnicodeString" if sku.DefaultValue.startswith(('L"',"L'")) else "OtherVOID*")
+ if len(PcdValueTypeSet) > 1:
+ for sku in pcd.SkuInfoList.values():
+ sku.DefaultValue = StringToArray(sku.DefaultValue) if sku.DefaultValue.startswith(('L"',"L'")) else sku.DefaultValue
+
+ list(map(self.FilterSkuSettings, Pcds.values()))
+ return Pcds
+
+ ## Add external modules
+ #
+ # The external modules are mostly those listed in FDF file, which don't
+ # need "build".
+ #
+ # @param FilePath The path of module description file
+ #
+ def AddModule(self, FilePath):
+ FilePath = NormPath(FilePath)
+ if FilePath not in self.Modules:
+ Module = ModuleBuildClassObject()
+ Module.MetaFile = FilePath
+ self.Modules.append(Module)
+
+ @property
+ def ToolChainFamily(self):
+ self._ToolChainFamily = TAB_COMPILER_MSFT
+ TargetObj = TargetTxtDict()
+ TargetTxt = TargetObj.Target
+ BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, gDefaultTargetTxtFile))
+ if os.path.isfile(BuildConfigurationFile) == True:
+ ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
+ if ToolDefinitionFile == '':
+ ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', gDefaultToolsDefFile))
+ if os.path.isfile(ToolDefinitionFile) == True:
+ ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
+ ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase
+ if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
+ or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
+ or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
+ self._ToolChainFamily = TAB_COMPILER_MSFT
+ else:
+ self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
+ return self._ToolChainFamily
+
+ ## Add external PCDs
+ #
+ # The external PCDs are mostly those listed in FDF file to specify address
+ # or offset information.
+ #
+ # @param Name Name of the PCD
+ # @param Guid Token space guid of the PCD
+ # @param Value Value of the PCD
+ #
+ def AddPcd(self, Name, Guid, Value):
+ if (Name, Guid) not in self.Pcds:
+ self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
+ self.Pcds[Name, Guid].DefaultValue = Value
+
+ @property
+ def DecPcds(self):
+ if self._DecPcds is None:
+ FdfInfList = []
+ if GlobalData.gFdfParser:
+ FdfInfList = GlobalData.gFdfParser.Profile.InfList
+ PkgSet = set()
+ for Inf in FdfInfList:
+ ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
+ if ModuleFile in self._Modules:
+ continue
+ ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
+ PkgSet.update(ModuleData.Packages)
+ if self.Packages:
+ PkgSet.update(self.Packages)
+ self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
+ self._GuidDict.update(GlobalData.gPlatformPcds)
+ return self._DecPcds
diff --git a/BaseTools/Source/Python/Workspace/InfBuildData.py b/BaseTools/Source/Python/Workspace/InfBuildData.py
index e4ff1c6686..ce6d3fa744 100644
--- a/BaseTools/Source/Python/Workspace/InfBuildData.py
+++ b/BaseTools/Source/Python/Workspace/InfBuildData.py
@@ -1,1100 +1,1100 @@
-## @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 __future__ import absolute_import
-from Common.DataType import *
-from Common.Misc import *
-from Common.caching import cached_property, cached_class_function
-from types import *
-from .MetaFileParser import *
-from collections import OrderedDict
-from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject
-from Common.Expression import ValueExpressionEx, PcdPattern
-
-## Get Protocol value from given packages
-#
-# @param CName The CName of the GUID
-# @param PackageList List of packages looking-up in
-# @param Inffile The driver file
-#
-# @retval GuidValue if the CName is found in any given package
-# @retval None if the CName is not found in all given packages
-#
-def _ProtocolValue(CName, PackageList, Inffile = None):
- for P in PackageList:
- ProtocolKeys = list(P.Protocols.keys())
- if Inffile and P._PrivateProtocols:
- if not Inffile.startswith(P.MetaFile.Dir):
- ProtocolKeys = [x for x in P.Protocols if x not in P._PrivateProtocols]
- if CName in ProtocolKeys:
- return P.Protocols[CName]
- return None
-
-## Get PPI value from given packages
-#
-# @param CName The CName of the GUID
-# @param PackageList List of packages looking-up in
-# @param Inffile The driver file
-#
-# @retval GuidValue if the CName is found in any given package
-# @retval None if the CName is not found in all given packages
-#
-def _PpiValue(CName, PackageList, Inffile = None):
- for P in PackageList:
- PpiKeys = list(P.Ppis.keys())
- if Inffile and P._PrivatePpis:
- if not Inffile.startswith(P.MetaFile.Dir):
- PpiKeys = [x for x in P.Ppis if x not in P._PrivatePpis]
- if CName in PpiKeys:
- return P.Ppis[CName]
- return None
-
-## Module build information from INF file
-#
-# This class is used to retrieve information stored in database and convert them
-# into ModuleBuildClassObject form for easier use for AutoGen.
-#
-class InfBuildData(ModuleBuildClassObject):
-
- # dict used to convert part of [Defines] to members of InfBuildData directly
- _PROPERTY_ = {
- #
- # Required Fields
- #
- TAB_INF_DEFINES_BASE_NAME : "_BaseName",
- TAB_INF_DEFINES_FILE_GUID : "_Guid",
- TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",
- #
- # Optional Fields
- #
- # TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
- TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",
- TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",
- # TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
- TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",
- TAB_INF_DEFINES_VERSION_NUMBER : "_Version",
- TAB_INF_DEFINES_VERSION_STRING : "_Version",
- TAB_INF_DEFINES_VERSION : "_Version",
- TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",
- TAB_INF_DEFINES_SHADOW : "_Shadow"
- }
-
- # regular expression for converting XXX_FLAGS in [nmake] section to new type
- _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)
- # dict used to convert old tool name used in [nmake] section to new ones
- _TOOL_CODE_ = {
- "C" : "CC",
- BINARY_FILE_TYPE_LIB : "SLINK",
- "LINK" : "DLINK",
- }
-
-
- ## Constructor of InfBuildData
- #
- # Initialize object of InfBuildData
- #
- # @param FilePath The path of platform description file
- # @param RawData The raw data of DSC file
- # @param BuildDataBase Database used to retrieve module/package information
- # @param Arch The target architecture
- # @param Platform The name of platform employing this module
- # @param Macros Macros used for replacement in DSC file
- #
- def __init__(self, FilePath, RawData, BuildDatabase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
- self.MetaFile = FilePath
- self._ModuleDir = FilePath.Dir
- self._RawData = RawData
- self._Bdb = BuildDatabase
- self._Arch = Arch
- self._Target = Target
- self._Toolchain = Toolchain
- self._Platform = TAB_COMMON
- self._TailComments = None
- self._BaseName = None
- self._DxsFile = None
- self._ModuleType = None
- self._ComponentType = None
- self._BuildType = None
- self._Guid = None
- self._Version = None
- self._PcdIsDriver = None
- self._BinaryModule = None
- self._Shadow = None
- self._MakefileName = None
- self._CustomMakefile = None
- self._Specification = None
- self._LibraryClass = None
- self._ModuleEntryPointList = None
- self._ModuleUnloadImageList = None
- self._ConstructorList = None
- self._DestructorList = None
- self._Defs = OrderedDict()
- self._ProtocolComments = None
- self._PpiComments = None
- self._GuidsUsedByPcd = OrderedDict()
- self._GuidComments = None
- self._PcdComments = None
- self._BuildOptions = None
- self._DependencyFileList = None
- self.UpdatePcdTypeDict()
- self.LibInstances = []
- self.ReferenceModules = set()
-
- def SetReferenceModule(self,Module):
- self.ReferenceModules.add(Module)
- return self
-
- ## 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_
-
- ## Get current effective macros
- @cached_property
- def _Macros(self):
- RetVal = {}
- return RetVal
-
- ## Get architecture
- @cached_property
- def Arch(self):
- return self._Arch
-
- ## Return the name of platform employing this module
- @cached_property
- def Platform(self):
- return self._Platform
-
- @cached_property
- def HeaderComments(self):
- return [a[0] for a in self._RawData[MODEL_META_DATA_HEADER_COMMENT]]
-
- @cached_property
- def TailComments(self):
- return [a[0] for a in self._RawData[MODEL_META_DATA_TAIL_COMMENT]]
-
- ## Retrieve all information in [Defines] section
- #
- # (Retrieving all [Defines] information in one-shot is just to save time.)
- #
- @cached_class_function
- def _GetHeaderInfo(self):
- RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
- for Record in RecordList:
- Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)
- # items defined _PROPERTY_ don't need additional processing
- if Name in self:
- self[Name] = Value
- self._Defs[Name] = Value
- self._Macros[Name] = Value
- # some special items in [Defines] section need special treatment
- elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
- if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
- Name = 'UEFI_SPECIFICATION_VERSION'
- if self._Specification is None:
- self._Specification = OrderedDict()
- self._Specification[Name] = GetHexVerValue(Value)
- if self._Specification[Name] is None:
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
- "'%s' format is not supported for %s" % (Value, Name),
- File=self.MetaFile, Line=Record[-1])
- elif Name == 'LIBRARY_CLASS':
- if self._LibraryClass is None:
- self._LibraryClass = []
- ValueList = GetSplitValueList(Value)
- LibraryClass = ValueList[0]
- if len(ValueList) > 1:
- SupModuleList = GetSplitValueList(ValueList[1], ' ')
- else:
- SupModuleList = SUP_MODULE_LIST
- self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))
- elif Name == 'ENTRY_POINT':
- if self._ModuleEntryPointList is None:
- self._ModuleEntryPointList = []
- self._ModuleEntryPointList.append(Value)
- elif Name == 'UNLOAD_IMAGE':
- if self._ModuleUnloadImageList is None:
- self._ModuleUnloadImageList = []
- if not Value:
- continue
- self._ModuleUnloadImageList.append(Value)
- elif Name == 'CONSTRUCTOR':
- if self._ConstructorList is None:
- self._ConstructorList = []
- if not Value:
- continue
- self._ConstructorList.append(Value)
- elif Name == 'DESTRUCTOR':
- if self._DestructorList is None:
- self._DestructorList = []
- if not Value:
- continue
- self._DestructorList.append(Value)
- elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:
- TokenList = GetSplitValueList(Value)
- if self._CustomMakefile is None:
- self._CustomMakefile = {}
- if len(TokenList) < 2:
- self._CustomMakefile[TAB_COMPILER_MSFT] = TokenList[0]
- self._CustomMakefile['GCC'] = TokenList[0]
- else:
- if TokenList[0] not in [TAB_COMPILER_MSFT, 'GCC']:
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
- "No supported family [%s]" % TokenList[0],
- File=self.MetaFile, Line=Record[-1])
- self._CustomMakefile[TokenList[0]] = TokenList[1]
- else:
- self._Defs[Name] = Value
- self._Macros[Name] = Value
-
- #
- # Retrieve information in sections specific to Edk.x modules
- #
- if not self._ModuleType:
- EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
- "MODULE_TYPE is not given", File=self.MetaFile)
- if self._ModuleType not in SUP_MODULE_LIST:
- RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
- for Record in RecordList:
- Name = Record[1]
- if Name == "MODULE_TYPE":
- LineNo = Record[6]
- break
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
- "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),
- File=self.MetaFile, Line=LineNo)
- if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
- if self._ModuleType == SUP_MODULE_SMM_CORE:
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)
- if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x00010032):
- if self._ModuleType == SUP_MODULE_MM_CORE_STANDALONE:
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)
- if self._ModuleType == SUP_MODULE_MM_STANDALONE:
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)
- if 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \
- and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:
- self._BuildType = 'UEFI_OPTIONROM'
- if 'PCI_COMPRESS' in self._Defs:
- if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):
- EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" % self.MetaFile)
-
- elif 'UEFI_HII_RESOURCE_SECTION' in self._Defs \
- and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
- self._BuildType = 'UEFI_HII'
- else:
- self._BuildType = self._ModuleType.upper()
-
- if self._DxsFile:
- File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,
- File=self.MetaFile, Line=LineNo)
- if not self._DependencyFileList:
- self._DependencyFileList = []
- self._DependencyFileList.append(File)
-
- ## Retrieve file version
- @cached_property
- def AutoGenVersion(self):
- RetVal = 0x00010000
- RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
- for Record in RecordList:
- if Record[1] == TAB_INF_DEFINES_INF_VERSION:
- if '.' in Record[2]:
- ValueList = Record[2].split('.')
- Major = '%04o' % int(ValueList[0], 0)
- Minor = '%04o' % int(ValueList[1], 0)
- RetVal = int('0x' + Major + Minor, 0)
- else:
- RetVal = int(Record[2], 0)
- break
- return RetVal
-
- ## Retrieve BASE_NAME
- @cached_property
- def BaseName(self):
- if self._BaseName is None:
- self._GetHeaderInfo()
- if self._BaseName is None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)
- return self._BaseName
-
- ## Retrieve DxsFile
- @cached_property
- def DxsFile(self):
- if self._DxsFile is None:
- self._GetHeaderInfo()
- if self._DxsFile is None:
- self._DxsFile = ''
- return self._DxsFile
-
- ## Retrieve MODULE_TYPE
- @cached_property
- def ModuleType(self):
- if self._ModuleType is None:
- self._GetHeaderInfo()
- if self._ModuleType is None:
- self._ModuleType = SUP_MODULE_BASE
- if self._ModuleType not in SUP_MODULE_LIST:
- self._ModuleType = SUP_MODULE_USER_DEFINED
- return self._ModuleType
-
- ## Retrieve COMPONENT_TYPE
- @cached_property
- def ComponentType(self):
- if self._ComponentType is None:
- self._GetHeaderInfo()
- if self._ComponentType is None:
- self._ComponentType = SUP_MODULE_USER_DEFINED
- return self._ComponentType
-
- ## Retrieve "BUILD_TYPE"
- @cached_property
- def BuildType(self):
- if self._BuildType is None:
- self._GetHeaderInfo()
- if not self._BuildType:
- self._BuildType = SUP_MODULE_BASE
- return self._BuildType
-
- ## Retrieve file guid
- @cached_property
- def Guid(self):
- if self._Guid is None:
- self._GetHeaderInfo()
- if self._Guid is None:
- self._Guid = '00000000-0000-0000-0000-000000000000'
- return self._Guid
-
- ## Retrieve module version
- @cached_property
- def Version(self):
- if self._Version is None:
- self._GetHeaderInfo()
- if self._Version is None:
- self._Version = '0.0'
- return self._Version
-
- ## Retrieve PCD_IS_DRIVER
- @cached_property
- def PcdIsDriver(self):
- if self._PcdIsDriver is None:
- self._GetHeaderInfo()
- if self._PcdIsDriver is None:
- self._PcdIsDriver = ''
- return self._PcdIsDriver
-
- ## Retrieve SHADOW
- @cached_property
- def Shadow(self):
- if self._Shadow is None:
- self._GetHeaderInfo()
- if self._Shadow and self._Shadow.upper() == 'TRUE':
- self._Shadow = True
- else:
- self._Shadow = False
- return self._Shadow
-
- ## Retrieve CUSTOM_MAKEFILE
- @cached_property
- def CustomMakefile(self):
- if self._CustomMakefile is None:
- self._GetHeaderInfo()
- if self._CustomMakefile is None:
- self._CustomMakefile = {}
- return self._CustomMakefile
-
- ## Retrieve EFI_SPECIFICATION_VERSION
- @cached_property
- def Specification(self):
- if self._Specification is None:
- self._GetHeaderInfo()
- if self._Specification is None:
- self._Specification = {}
- return self._Specification
-
- ## Retrieve LIBRARY_CLASS
- @cached_property
- def LibraryClass(self):
- if self._LibraryClass is None:
- self._GetHeaderInfo()
- if self._LibraryClass is None:
- self._LibraryClass = []
- return self._LibraryClass
-
- ## Retrieve ENTRY_POINT
- @cached_property
- def ModuleEntryPointList(self):
- if self._ModuleEntryPointList is None:
- self._GetHeaderInfo()
- if self._ModuleEntryPointList is None:
- self._ModuleEntryPointList = []
- return self._ModuleEntryPointList
-
- ## Retrieve UNLOAD_IMAGE
- @cached_property
- def ModuleUnloadImageList(self):
- if self._ModuleUnloadImageList is None:
- self._GetHeaderInfo()
- if self._ModuleUnloadImageList is None:
- self._ModuleUnloadImageList = []
- return self._ModuleUnloadImageList
-
- ## Retrieve CONSTRUCTOR
- @cached_property
- def ConstructorList(self):
- if self._ConstructorList is None:
- self._GetHeaderInfo()
- if self._ConstructorList is None:
- self._ConstructorList = []
- return self._ConstructorList
-
- ## Retrieve DESTRUCTOR
- @cached_property
- def DestructorList(self):
- if self._DestructorList is None:
- self._GetHeaderInfo()
- if self._DestructorList is None:
- self._DestructorList = []
- return self._DestructorList
-
- ## Retrieve definies other than above ones
- @cached_property
- def Defines(self):
- self._GetHeaderInfo()
- return self._Defs
-
- ## Retrieve binary files
- @cached_class_function
- def _GetBinaries(self):
- RetVal = []
- RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]
- Macros = self._Macros
- Macros['PROCESSOR'] = self._Arch
- for Record in RecordList:
- FileType = Record[0]
- LineNo = Record[-1]
- Target = TAB_COMMON
- FeatureFlag = []
- if Record[2]:
- TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
- if TokenList:
- Target = TokenList[0]
- if len(TokenList) > 1:
- FeatureFlag = Record[1:]
-
- File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate()
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
- RetVal.append(File)
- return RetVal
-
- ## Retrieve binary files with error check.
- @cached_property
- def Binaries(self):
- RetVal = self._GetBinaries()
- if GlobalData.gIgnoreSource and not RetVal:
- ErrorInfo = "The INF file does not contain any RetVal to use in creating the image\n"
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)
-
- return RetVal
-
- ## Retrieve source files
- @cached_property
- def Sources(self):
- self._GetHeaderInfo()
- # Ignore all source files in a binary build mode
- if GlobalData.gIgnoreSource:
- return []
-
- RetVal = []
- RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
- Macros = self._Macros
- for Record in RecordList:
- LineNo = Record[-1]
- ToolChainFamily = Record[1]
- # OptionsList := [TagName, ToolCode, FeatureFlag]
- OptionsList = ['', '', '']
- TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
- for Index in range(len(TokenList)):
- OptionsList[Index] = TokenList[Index]
- if OptionsList[2]:
- FeaturePcdExpression = self.CheckFeatureFlagPcd(OptionsList[2])
- if not FeaturePcdExpression:
- continue
- File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',
- '', False, self._Arch, ToolChainFamily, '', OptionsList[0], OptionsList[1])
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate()
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
-
- RetVal.append(File)
- # add any previously found dependency files to the source list
- if self._DependencyFileList:
- RetVal.extend(self._DependencyFileList)
- return RetVal
-
- ## Retrieve library classes employed by this module
- @cached_property
- def LibraryClasses(self):
- RetVal = OrderedDict()
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]
- for Record in RecordList:
- Lib = Record[0]
- Instance = Record[1]
- if Instance:
- Instance = NormPath(Instance, self._Macros)
- RetVal[Lib] = Instance
- else:
- RetVal[Lib] = None
- return RetVal
-
- ## Retrieve library names (for Edk.x style of modules)
- @cached_property
- def Libraries(self):
- RetVal = []
- RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]
- for Record in RecordList:
- LibraryName = ReplaceMacro(Record[0], self._Macros, False)
- # in case of name with '.lib' extension, which is unusual in Edk.x inf
- LibraryName = os.path.splitext(LibraryName)[0]
- if LibraryName not in RetVal:
- RetVal.append(LibraryName)
- return RetVal
-
- @cached_property
- def ProtocolComments(self):
- self.Protocols
- return self._ProtocolComments
-
- ## Retrieve protocols consumed/produced by this module
- @cached_property
- def Protocols(self):
- RetVal = OrderedDict()
- self._ProtocolComments = OrderedDict()
- RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
- for Record in RecordList:
- CName = Record[0]
- Value = _ProtocolValue(CName, self.Packages, self.MetaFile.Path)
- if Value is None:
- PackageList = "\n\t".join(str(P) for P in self.Packages)
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
- "Value of Protocol [%s] is not found under [Protocols] section in" % CName,
- ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
- RetVal[CName] = Value
- CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
- self._ProtocolComments[CName] = [a[0] for a in CommentRecords]
- return RetVal
-
- @cached_property
- def PpiComments(self):
- self.Ppis
- return self._PpiComments
-
- ## Retrieve PPIs consumed/produced by this module
- @cached_property
- def Ppis(self):
- RetVal = OrderedDict()
- self._PpiComments = OrderedDict()
- RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
- for Record in RecordList:
- CName = Record[0]
- Value = _PpiValue(CName, self.Packages, self.MetaFile.Path)
- if Value is None:
- PackageList = "\n\t".join(str(P) for P in self.Packages)
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
- "Value of PPI [%s] is not found under [Ppis] section in " % CName,
- ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
- RetVal[CName] = Value
- CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
- self._PpiComments[CName] = [a[0] for a in CommentRecords]
- return RetVal
-
- @cached_property
- def GuidComments(self):
- self.Guids
- return self._GuidComments
-
- ## Retrieve GUIDs consumed/produced by this module
- @cached_property
- def Guids(self):
- RetVal = OrderedDict()
- self._GuidComments = OrderedDict()
- RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
- for Record in RecordList:
- CName = Record[0]
- Value = GuidValue(CName, self.Packages, self.MetaFile.Path)
- if Value is None:
- PackageList = "\n\t".join(str(P) for P in self.Packages)
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
- "Value of Guid [%s] is not found under [Guids] section in" % CName,
- ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
- RetVal[CName] = Value
- CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
- self._GuidComments[CName] = [a[0] for a in CommentRecords]
-
- for Type in [MODEL_PCD_FIXED_AT_BUILD,MODEL_PCD_PATCHABLE_IN_MODULE,MODEL_PCD_FEATURE_FLAG,MODEL_PCD_DYNAMIC,MODEL_PCD_DYNAMIC_EX]:
- RecordList = self._RawData[Type, self._Arch, self._Platform]
- for TokenSpaceGuid, _, _, _, _, _, LineNo in RecordList:
- # get the guid value
- if TokenSpaceGuid not in RetVal:
- Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)
- if Value is None:
- PackageList = "\n\t".join(str(P) for P in self.Packages)
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
- "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,
- ExtraData=PackageList, File=self.MetaFile, Line=LineNo)
- RetVal[TokenSpaceGuid] = Value
- self._GuidsUsedByPcd[TokenSpaceGuid] = Value
- return RetVal
-
- ## Retrieve include paths necessary for this module (for Edk.x style of modules)
- @cached_property
- def Includes(self):
- RetVal = []
- Macros = self._Macros
- Macros['PROCESSOR'] = GlobalData.gEdkGlobal.get('PROCESSOR', self._Arch)
- RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]
- for Record in RecordList:
- File = NormPath(Record[0], Macros)
- if File[0] == '.':
- File = os.path.join(self._ModuleDir, File)
- else:
- File = mws.join(GlobalData.gWorkspace, File)
- File = RealPath(os.path.normpath(File))
- if File:
- RetVal.append(File)
- return RetVal
-
- ## Retrieve packages this module depends on
- @cached_property
- def Packages(self):
- RetVal = []
- RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]
- Macros = self._Macros
- for Record in RecordList:
- File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate('.dec')
- if ErrorCode != 0:
- LineNo = Record[-1]
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
- # parse this package now. we need it to get protocol/ppi/guid value
- RetVal.append(self._Bdb[File, self._Arch, self._Target, self._Toolchain])
- return RetVal
-
- ## Retrieve PCD comments
- @cached_property
- def PcdComments(self):
- self.Pcds
- return self._PcdComments
-
- ## Retrieve PCDs used in this module
- @cached_property
- def Pcds(self):
- self._PcdComments = OrderedDict()
- RetVal = OrderedDict()
- RetVal.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
- RetVal.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
- RetVal.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
- RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC))
- RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
- return RetVal
-
- @cached_property
- def ModulePcdList(self):
- RetVal = self.Pcds
- return RetVal
- @cached_property
- def LibraryPcdList(self):
- if bool(self.LibraryClass):
- return []
- RetVal = {}
- Pcds = set()
- for Library in self.LibInstances:
- PcdsInLibrary = OrderedDict()
- for Key in Library.Pcds:
- if Key in self.Pcds or Key in Pcds:
- continue
- Pcds.add(Key)
- PcdsInLibrary[Key] = copy.copy(Library.Pcds[Key])
- RetVal[Library] = PcdsInLibrary
- return RetVal
- @cached_property
- def PcdsName(self):
- PcdsName = set()
- for Type in (MODEL_PCD_FIXED_AT_BUILD,MODEL_PCD_PATCHABLE_IN_MODULE,MODEL_PCD_FEATURE_FLAG,MODEL_PCD_DYNAMIC,MODEL_PCD_DYNAMIC_EX):
- RecordList = self._RawData[Type, self._Arch, self._Platform]
- for TokenSpaceGuid, PcdCName, _, _, _, _, _ in RecordList:
- PcdsName.add((PcdCName, TokenSpaceGuid))
- return PcdsName
-
- ## Retrieve build options specific to this module
- @cached_property
- def BuildOptions(self):
- if self._BuildOptions is None:
- self._BuildOptions = OrderedDict()
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]
- for Record in RecordList:
- ToolChainFamily = Record[0]
- ToolChain = Record[1]
- Option = Record[2]
- if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):
- self._BuildOptions[ToolChainFamily, ToolChain] = Option
- else:
- # concatenate the option string if they're for the same tool
- OptionString = self._BuildOptions[ToolChainFamily, ToolChain]
- self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
- return self._BuildOptions
-
- ## Retrieve dependency expression
- @cached_property
- def Depex(self):
- RetVal = tdict(False, 2)
-
- # If the module has only Binaries and no Sources, then ignore [Depex]
- if not self.Sources and self.Binaries:
- return RetVal
-
- RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
- # PEIM and DXE drivers must have a valid [Depex] section
- if len(self.LibraryClass) == 0 and len(RecordList) == 0:
- if self.ModuleType == SUP_MODULE_DXE_DRIVER or self.ModuleType == SUP_MODULE_PEIM or self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER or \
- self.ModuleType == SUP_MODULE_DXE_SAL_DRIVER or self.ModuleType == SUP_MODULE_DXE_RUNTIME_DRIVER:
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
- % self.ModuleType, File=self.MetaFile)
-
- if len(RecordList) != 0 and (self.ModuleType == SUP_MODULE_USER_DEFINED or self.ModuleType == SUP_MODULE_HOST_APPLICATION):
- for Record in RecordList:
- if Record[4] not in [SUP_MODULE_PEIM, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER]:
- EdkLogger.error('build', FORMAT_INVALID,
- "'%s' module must specify the type of [Depex] section" % self.ModuleType,
- File=self.MetaFile)
-
- TemporaryDictionary = OrderedDict()
- for Record in RecordList:
- DepexStr = ReplaceMacro(Record[0], self._Macros, False)
- Arch = Record[3]
- ModuleType = Record[4]
- TokenList = DepexStr.split()
- if (Arch, ModuleType) not in TemporaryDictionary:
- TemporaryDictionary[Arch, ModuleType] = []
- DepexList = TemporaryDictionary[Arch, ModuleType]
- for Token in TokenList:
- if Token in DEPEX_SUPPORTED_OPCODE_SET:
- DepexList.append(Token)
- elif Token.endswith(".inf"): # module file name
- ModuleFile = os.path.normpath(Token)
- Module = self.BuildDatabase[ModuleFile]
- if Module is None:
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",
- ExtraData=Token, File=self.MetaFile, Line=Record[-1])
- DepexList.append(Module.Guid)
- else:
- # it use the Fixed PCD format
- if '.' in Token:
- if tuple(Token.split('.')[::-1]) not in self.Pcds:
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "PCD [{}] used in [Depex] section should be listed in module PCD section".format(Token), File=self.MetaFile, Line=Record[-1])
- else:
- if self.Pcds[tuple(Token.split('.')[::-1])].DatumType != TAB_VOID:
- EdkLogger.error('build', FORMAT_INVALID, "PCD [{}] used in [Depex] section should be VOID* datum type".format(Token), File=self.MetaFile, Line=Record[-1])
- Value = Token
- else:
- # get the GUID value now
- Value = _ProtocolValue(Token, self.Packages, self.MetaFile.Path)
- if Value is None:
- Value = _PpiValue(Token, self.Packages, self.MetaFile.Path)
- if Value is None:
- Value = GuidValue(Token, self.Packages, self.MetaFile.Path)
-
- if Value is None:
- PackageList = "\n\t".join(str(P) for P in self.Packages)
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
- "Value of [%s] is not found in" % Token,
- ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
- DepexList.append(Value)
- for Arch, ModuleType in TemporaryDictionary:
- RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]
- return RetVal
-
- ## Retrieve dependency expression
- @cached_property
- def DepexExpression(self):
- RetVal = tdict(False, 2)
- RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
- TemporaryDictionary = OrderedDict()
- for Record in RecordList:
- DepexStr = ReplaceMacro(Record[0], self._Macros, False)
- Arch = Record[3]
- ModuleType = Record[4]
- TokenList = DepexStr.split()
- if (Arch, ModuleType) not in TemporaryDictionary:
- TemporaryDictionary[Arch, ModuleType] = ''
- for Token in TokenList:
- TemporaryDictionary[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType] + Token.strip() + ' '
- for Arch, ModuleType in TemporaryDictionary:
- RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]
- return RetVal
- def LocalPkg(self):
- module_path = self.MetaFile.File
- subdir = os.path.split(module_path)[0]
- TopDir = ""
- while subdir:
- subdir,TopDir = os.path.split(subdir)
-
- for file_name in os.listdir(os.path.join(self.MetaFile.Root,TopDir)):
- if file_name.upper().endswith("DEC"):
- pkg = os.path.join(TopDir,file_name)
- return pkg
- @cached_class_function
- def GetGuidsUsedByPcd(self):
- self.Guid
- return self._GuidsUsedByPcd
-
- ## Retrieve PCD for given type
- def _GetPcd(self, Type):
- Pcds = OrderedDict()
- PcdDict = tdict(True, 4)
- PcdList = []
- RecordList = self._RawData[Type, self._Arch, self._Platform]
- for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:
- PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)
- PcdList.append((PcdCName, TokenSpaceGuid))
- CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]
- Comments = []
- for CmtRec in CommentRecords:
- Comments.append(CmtRec[0])
- self._PcdComments[TokenSpaceGuid, PcdCName] = Comments
-
- # resolve PCD type, value, datum info, etc. by getting its definition from package
- _GuidDict = self.Guids.copy()
- for PcdCName, TokenSpaceGuid in PcdList:
- PcdRealName = PcdCName
- Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]
- if Setting is None:
- continue
- ValueList = AnalyzePcdData(Setting)
- DefaultValue = ValueList[0]
- Pcd = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- '',
- '',
- DefaultValue,
- '',
- '',
- {},
- False,
- self.Guids[TokenSpaceGuid]
- )
- if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:
- # Patch PCD: TokenSpace.PcdCName|Value|Offset
- Pcd.Offset = ValueList[1]
-
- if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
- for Package in self.Packages:
- for key in Package.Pcds:
- if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):
- for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
- Pcd_Type = item[0].split('_')[-1]
- if Pcd_Type == Package.Pcds[key].Type:
- Value = Package.Pcds[key]
- Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type
- if len(key) == 2:
- newkey = (Value.TokenCName, key[1])
- elif len(key) == 3:
- newkey = (Value.TokenCName, key[1], key[2])
- del Package.Pcds[key]
- Package.Pcds[newkey] = Value
- break
- else:
- pass
- else:
- pass
-
- # get necessary info from package declaring this PCD
- for Package in self.Packages:
- #
- # 'dynamic' in INF means its type is determined by platform;
- # if platform doesn't give its type, use 'lowest' one in the
- # following order, if any
- #
- # TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX
- #
- _GuidDict.update(Package.Guids)
- PcdType = self._PCD_TYPE_STRING_[Type]
- if Type == MODEL_PCD_DYNAMIC:
- Pcd.Pending = True
- for T in PCD_TYPE_LIST:
- if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
- for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
- if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:
- PcdType = T
- PcdCName = item[0]
- break
- else:
- pass
- break
- else:
- if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:
- PcdType = T
- break
-
- else:
- Pcd.Pending = False
- if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
- for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
- Pcd_Type = item[0].split('_')[-1]
- if Pcd_Type == PcdType:
- PcdCName = item[0]
- break
- else:
- pass
- else:
- pass
-
- if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:
- PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]
- Pcd.Type = PcdType
- Pcd.TokenValue = PcdInPackage.TokenValue
-
- #
- # Check whether the token value exist or not.
- #
- if Pcd.TokenValue is None or Pcd.TokenValue == "":
- EdkLogger.error(
- 'build',
- FORMAT_INVALID,
- "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),
- File=self.MetaFile, Line=LineNo,
- ExtraData=None
- )
- #
- # Check hexadecimal token value length and format.
- #
- ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)
- if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):
- if ReIsValidPcdTokenValue.match(Pcd.TokenValue) is None:
- EdkLogger.error(
- 'build',
- FORMAT_INVALID,
- "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
- File=self.MetaFile, Line=LineNo,
- ExtraData=None
- )
-
- #
- # Check decimal token value length and format.
- #
- else:
- try:
- TokenValueInt = int (Pcd.TokenValue, 10)
- if (TokenValueInt < 0 or TokenValueInt > 4294967295):
- EdkLogger.error(
- 'build',
- FORMAT_INVALID,
- "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
- File=self.MetaFile, Line=LineNo,
- ExtraData=None
- )
- except:
- EdkLogger.error(
- 'build',
- FORMAT_INVALID,
- "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
- File=self.MetaFile, Line=LineNo,
- ExtraData=None
- )
-
- Pcd.DatumType = PcdInPackage.DatumType
- Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize
- Pcd.InfDefaultValue = Pcd.DefaultValue
- if not Pcd.DefaultValue:
- Pcd.DefaultValue = PcdInPackage.DefaultValue
- else:
- try:
- Pcd.DefaultValue = ValueExpressionEx(Pcd.DefaultValue, Pcd.DatumType, _GuidDict)(True)
- except BadExpression as Value:
- EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(TokenSpaceGuid, PcdRealName, Pcd.DefaultValue, Value),
- File=self.MetaFile, Line=LineNo)
- break
- else:
- EdkLogger.error(
- 'build',
- FORMAT_INVALID,
- "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),
- File=self.MetaFile, Line=LineNo,
- ExtraData="\t%s" % '\n\t'.join(str(P) for P in self.Packages)
- )
- Pcds[PcdCName, TokenSpaceGuid] = Pcd
-
- return Pcds
-
- ## check whether current module is binary module
- @property
- def IsBinaryModule(self):
- if (self.Binaries and not self.Sources) or GlobalData.gIgnoreSource:
- return True
- return False
- def CheckFeatureFlagPcd(self,Instance):
- Pcds = GlobalData.gPlatformFinalPcds.copy()
- if PcdPattern.search(Instance):
- PcdTuple = tuple(Instance.split('.')[::-1])
- if PcdTuple in self.Pcds:
- if not (self.Pcds[PcdTuple].Type == 'FeatureFlag' or self.Pcds[PcdTuple].Type == 'FixedAtBuild'):
- EdkLogger.error('build', FORMAT_INVALID,
- "\nFeatureFlagPcd must be defined in a [PcdsFeatureFlag] or [PcdsFixedAtBuild] section of Dsc or Dec file",
- File=str(self), ExtraData=Instance)
- if not Instance in Pcds:
- Pcds[Instance] = self.Pcds[PcdTuple].DefaultValue
- else: #if PcdTuple not in self.Pcds:
- EdkLogger.error('build', FORMAT_INVALID,
- "\nFeatureFlagPcd must be defined in [FeaturePcd] or [FixedPcd] of Inf file",
- File=str(self), ExtraData=Instance)
- if Instance in Pcds:
- if Pcds[Instance] == '0':
- return False
- elif Pcds[Instance] == '1':
- return True
- try:
- Value = ValueExpression(Instance, Pcds)()
- if Value == True:
- return True
- return False
- except:
- EdkLogger.warn('build', FORMAT_INVALID,"The FeatureFlagExpression cannot be evaluated", File=str(self), ExtraData=Instance)
- return False
- else:
- for Name, Guid in self.Pcds:
- if self.Pcds[(Name, Guid)].Type == 'FeatureFlag' or self.Pcds[(Name, Guid)].Type == 'FixedAtBuild':
- PcdFullName = '%s.%s' % (Guid, Name);
- if not PcdFullName in Pcds:
- Pcds[PcdFullName] = self.Pcds[(Name, Guid)].DefaultValue
- try:
- Value = ValueExpression(Instance, Pcds)()
- if Value == True:
- return True
- return False
- except:
- EdkLogger.warn('build', FORMAT_INVALID, "The FeatureFlagExpression cannot be evaluated", File=str(self), ExtraData=Instance)
- return False
-def ExtendCopyDictionaryLists(CopyToDict, CopyFromDict):
- for Key in CopyFromDict:
- CopyToDict[Key].extend(CopyFromDict[Key])
+## @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 __future__ import absolute_import
+from Common.DataType import *
+from Common.Misc import *
+from Common.caching import cached_property, cached_class_function
+from types import *
+from .MetaFileParser import *
+from collections import OrderedDict
+from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject
+from Common.Expression import ValueExpressionEx, PcdPattern
+
+## Get Protocol value from given packages
+#
+# @param CName The CName of the GUID
+# @param PackageList List of packages looking-up in
+# @param Inffile The driver file
+#
+# @retval GuidValue if the CName is found in any given package
+# @retval None if the CName is not found in all given packages
+#
+def _ProtocolValue(CName, PackageList, Inffile = None):
+ for P in PackageList:
+ ProtocolKeys = list(P.Protocols.keys())
+ if Inffile and P._PrivateProtocols:
+ if not Inffile.startswith(P.MetaFile.Dir):
+ ProtocolKeys = [x for x in P.Protocols if x not in P._PrivateProtocols]
+ if CName in ProtocolKeys:
+ return P.Protocols[CName]
+ return None
+
+## Get PPI value from given packages
+#
+# @param CName The CName of the GUID
+# @param PackageList List of packages looking-up in
+# @param Inffile The driver file
+#
+# @retval GuidValue if the CName is found in any given package
+# @retval None if the CName is not found in all given packages
+#
+def _PpiValue(CName, PackageList, Inffile = None):
+ for P in PackageList:
+ PpiKeys = list(P.Ppis.keys())
+ if Inffile and P._PrivatePpis:
+ if not Inffile.startswith(P.MetaFile.Dir):
+ PpiKeys = [x for x in P.Ppis if x not in P._PrivatePpis]
+ if CName in PpiKeys:
+ return P.Ppis[CName]
+ return None
+
+## Module build information from INF file
+#
+# This class is used to retrieve information stored in database and convert them
+# into ModuleBuildClassObject form for easier use for AutoGen.
+#
+class InfBuildData(ModuleBuildClassObject):
+
+ # dict used to convert part of [Defines] to members of InfBuildData directly
+ _PROPERTY_ = {
+ #
+ # Required Fields
+ #
+ TAB_INF_DEFINES_BASE_NAME : "_BaseName",
+ TAB_INF_DEFINES_FILE_GUID : "_Guid",
+ TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",
+ #
+ # Optional Fields
+ #
+ # TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
+ TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",
+ TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",
+ # TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
+ TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",
+ TAB_INF_DEFINES_VERSION_NUMBER : "_Version",
+ TAB_INF_DEFINES_VERSION_STRING : "_Version",
+ TAB_INF_DEFINES_VERSION : "_Version",
+ TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",
+ TAB_INF_DEFINES_SHADOW : "_Shadow"
+ }
+
+ # regular expression for converting XXX_FLAGS in [nmake] section to new type
+ _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)
+ # dict used to convert old tool name used in [nmake] section to new ones
+ _TOOL_CODE_ = {
+ "C" : "CC",
+ BINARY_FILE_TYPE_LIB : "SLINK",
+ "LINK" : "DLINK",
+ }
+
+
+ ## Constructor of InfBuildData
+ #
+ # Initialize object of InfBuildData
+ #
+ # @param FilePath The path of platform description file
+ # @param RawData The raw data of DSC file
+ # @param BuildDataBase Database used to retrieve module/package information
+ # @param Arch The target architecture
+ # @param Platform The name of platform employing this module
+ # @param Macros Macros used for replacement in DSC file
+ #
+ def __init__(self, FilePath, RawData, BuildDatabase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
+ self.MetaFile = FilePath
+ self._ModuleDir = FilePath.Dir
+ self._RawData = RawData
+ self._Bdb = BuildDatabase
+ self._Arch = Arch
+ self._Target = Target
+ self._Toolchain = Toolchain
+ self._Platform = TAB_COMMON
+ self._TailComments = None
+ self._BaseName = None
+ self._DxsFile = None
+ self._ModuleType = None
+ self._ComponentType = None
+ self._BuildType = None
+ self._Guid = None
+ self._Version = None
+ self._PcdIsDriver = None
+ self._BinaryModule = None
+ self._Shadow = None
+ self._MakefileName = None
+ self._CustomMakefile = None
+ self._Specification = None
+ self._LibraryClass = None
+ self._ModuleEntryPointList = None
+ self._ModuleUnloadImageList = None
+ self._ConstructorList = None
+ self._DestructorList = None
+ self._Defs = OrderedDict()
+ self._ProtocolComments = None
+ self._PpiComments = None
+ self._GuidsUsedByPcd = OrderedDict()
+ self._GuidComments = None
+ self._PcdComments = None
+ self._BuildOptions = None
+ self._DependencyFileList = None
+ self.UpdatePcdTypeDict()
+ self.LibInstances = []
+ self.ReferenceModules = set()
+
+ def SetReferenceModule(self,Module):
+ self.ReferenceModules.add(Module)
+ return self
+
+ ## 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_
+
+ ## Get current effective macros
+ @cached_property
+ def _Macros(self):
+ RetVal = {}
+ return RetVal
+
+ ## Get architecture
+ @cached_property
+ def Arch(self):
+ return self._Arch
+
+ ## Return the name of platform employing this module
+ @cached_property
+ def Platform(self):
+ return self._Platform
+
+ @cached_property
+ def HeaderComments(self):
+ return [a[0] for a in self._RawData[MODEL_META_DATA_HEADER_COMMENT]]
+
+ @cached_property
+ def TailComments(self):
+ return [a[0] for a in self._RawData[MODEL_META_DATA_TAIL_COMMENT]]
+
+ ## Retrieve all information in [Defines] section
+ #
+ # (Retrieving all [Defines] information in one-shot is just to save time.)
+ #
+ @cached_class_function
+ def _GetHeaderInfo(self):
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
+ for Record in RecordList:
+ Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)
+ # items defined _PROPERTY_ don't need additional processing
+ if Name in self:
+ self[Name] = Value
+ self._Defs[Name] = Value
+ self._Macros[Name] = Value
+ # some special items in [Defines] section need special treatment
+ elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
+ if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
+ Name = 'UEFI_SPECIFICATION_VERSION'
+ if self._Specification is None:
+ self._Specification = OrderedDict()
+ self._Specification[Name] = GetHexVerValue(Value)
+ if self._Specification[Name] is None:
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
+ "'%s' format is not supported for %s" % (Value, Name),
+ File=self.MetaFile, Line=Record[-1])
+ elif Name == 'LIBRARY_CLASS':
+ if self._LibraryClass is None:
+ self._LibraryClass = []
+ ValueList = GetSplitValueList(Value)
+ LibraryClass = ValueList[0]
+ if len(ValueList) > 1:
+ SupModuleList = GetSplitValueList(ValueList[1], ' ')
+ else:
+ SupModuleList = SUP_MODULE_LIST
+ self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))
+ elif Name == 'ENTRY_POINT':
+ if self._ModuleEntryPointList is None:
+ self._ModuleEntryPointList = []
+ self._ModuleEntryPointList.append(Value)
+ elif Name == 'UNLOAD_IMAGE':
+ if self._ModuleUnloadImageList is None:
+ self._ModuleUnloadImageList = []
+ if not Value:
+ continue
+ self._ModuleUnloadImageList.append(Value)
+ elif Name == 'CONSTRUCTOR':
+ if self._ConstructorList is None:
+ self._ConstructorList = []
+ if not Value:
+ continue
+ self._ConstructorList.append(Value)
+ elif Name == 'DESTRUCTOR':
+ if self._DestructorList is None:
+ self._DestructorList = []
+ if not Value:
+ continue
+ self._DestructorList.append(Value)
+ elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:
+ TokenList = GetSplitValueList(Value)
+ if self._CustomMakefile is None:
+ self._CustomMakefile = {}
+ if len(TokenList) < 2:
+ self._CustomMakefile[TAB_COMPILER_MSFT] = TokenList[0]
+ self._CustomMakefile['GCC'] = TokenList[0]
+ else:
+ if TokenList[0] not in [TAB_COMPILER_MSFT, 'GCC']:
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
+ "No supported family [%s]" % TokenList[0],
+ File=self.MetaFile, Line=Record[-1])
+ self._CustomMakefile[TokenList[0]] = TokenList[1]
+ else:
+ self._Defs[Name] = Value
+ self._Macros[Name] = Value
+
+ #
+ # Retrieve information in sections specific to Edk.x modules
+ #
+ if not self._ModuleType:
+ EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
+ "MODULE_TYPE is not given", File=self.MetaFile)
+ if self._ModuleType not in SUP_MODULE_LIST:
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
+ for Record in RecordList:
+ Name = Record[1]
+ if Name == "MODULE_TYPE":
+ LineNo = Record[6]
+ break
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
+ "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),
+ File=self.MetaFile, Line=LineNo)
+ if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
+ if self._ModuleType == SUP_MODULE_SMM_CORE:
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)
+ if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x00010032):
+ if self._ModuleType == SUP_MODULE_MM_CORE_STANDALONE:
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)
+ if self._ModuleType == SUP_MODULE_MM_STANDALONE:
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)
+ if 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \
+ and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:
+ self._BuildType = 'UEFI_OPTIONROM'
+ if 'PCI_COMPRESS' in self._Defs:
+ if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):
+ EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" % self.MetaFile)
+
+ elif 'UEFI_HII_RESOURCE_SECTION' in self._Defs \
+ and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
+ self._BuildType = 'UEFI_HII'
+ else:
+ self._BuildType = self._ModuleType.upper()
+
+ if self._DxsFile:
+ File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,
+ File=self.MetaFile, Line=LineNo)
+ if not self._DependencyFileList:
+ self._DependencyFileList = []
+ self._DependencyFileList.append(File)
+
+ ## Retrieve file version
+ @cached_property
+ def AutoGenVersion(self):
+ RetVal = 0x00010000
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
+ for Record in RecordList:
+ if Record[1] == TAB_INF_DEFINES_INF_VERSION:
+ if '.' in Record[2]:
+ ValueList = Record[2].split('.')
+ Major = '%04o' % int(ValueList[0], 0)
+ Minor = '%04o' % int(ValueList[1], 0)
+ RetVal = int('0x' + Major + Minor, 0)
+ else:
+ RetVal = int(Record[2], 0)
+ break
+ return RetVal
+
+ ## Retrieve BASE_NAME
+ @cached_property
+ def BaseName(self):
+ if self._BaseName is None:
+ self._GetHeaderInfo()
+ if self._BaseName is None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)
+ return self._BaseName
+
+ ## Retrieve DxsFile
+ @cached_property
+ def DxsFile(self):
+ if self._DxsFile is None:
+ self._GetHeaderInfo()
+ if self._DxsFile is None:
+ self._DxsFile = ''
+ return self._DxsFile
+
+ ## Retrieve MODULE_TYPE
+ @cached_property
+ def ModuleType(self):
+ if self._ModuleType is None:
+ self._GetHeaderInfo()
+ if self._ModuleType is None:
+ self._ModuleType = SUP_MODULE_BASE
+ if self._ModuleType not in SUP_MODULE_LIST:
+ self._ModuleType = SUP_MODULE_USER_DEFINED
+ return self._ModuleType
+
+ ## Retrieve COMPONENT_TYPE
+ @cached_property
+ def ComponentType(self):
+ if self._ComponentType is None:
+ self._GetHeaderInfo()
+ if self._ComponentType is None:
+ self._ComponentType = SUP_MODULE_USER_DEFINED
+ return self._ComponentType
+
+ ## Retrieve "BUILD_TYPE"
+ @cached_property
+ def BuildType(self):
+ if self._BuildType is None:
+ self._GetHeaderInfo()
+ if not self._BuildType:
+ self._BuildType = SUP_MODULE_BASE
+ return self._BuildType
+
+ ## Retrieve file guid
+ @cached_property
+ def Guid(self):
+ if self._Guid is None:
+ self._GetHeaderInfo()
+ if self._Guid is None:
+ self._Guid = '00000000-0000-0000-0000-000000000000'
+ return self._Guid
+
+ ## Retrieve module version
+ @cached_property
+ def Version(self):
+ if self._Version is None:
+ self._GetHeaderInfo()
+ if self._Version is None:
+ self._Version = '0.0'
+ return self._Version
+
+ ## Retrieve PCD_IS_DRIVER
+ @cached_property
+ def PcdIsDriver(self):
+ if self._PcdIsDriver is None:
+ self._GetHeaderInfo()
+ if self._PcdIsDriver is None:
+ self._PcdIsDriver = ''
+ return self._PcdIsDriver
+
+ ## Retrieve SHADOW
+ @cached_property
+ def Shadow(self):
+ if self._Shadow is None:
+ self._GetHeaderInfo()
+ if self._Shadow and self._Shadow.upper() == 'TRUE':
+ self._Shadow = True
+ else:
+ self._Shadow = False
+ return self._Shadow
+
+ ## Retrieve CUSTOM_MAKEFILE
+ @cached_property
+ def CustomMakefile(self):
+ if self._CustomMakefile is None:
+ self._GetHeaderInfo()
+ if self._CustomMakefile is None:
+ self._CustomMakefile = {}
+ return self._CustomMakefile
+
+ ## Retrieve EFI_SPECIFICATION_VERSION
+ @cached_property
+ def Specification(self):
+ if self._Specification is None:
+ self._GetHeaderInfo()
+ if self._Specification is None:
+ self._Specification = {}
+ return self._Specification
+
+ ## Retrieve LIBRARY_CLASS
+ @cached_property
+ def LibraryClass(self):
+ if self._LibraryClass is None:
+ self._GetHeaderInfo()
+ if self._LibraryClass is None:
+ self._LibraryClass = []
+ return self._LibraryClass
+
+ ## Retrieve ENTRY_POINT
+ @cached_property
+ def ModuleEntryPointList(self):
+ if self._ModuleEntryPointList is None:
+ self._GetHeaderInfo()
+ if self._ModuleEntryPointList is None:
+ self._ModuleEntryPointList = []
+ return self._ModuleEntryPointList
+
+ ## Retrieve UNLOAD_IMAGE
+ @cached_property
+ def ModuleUnloadImageList(self):
+ if self._ModuleUnloadImageList is None:
+ self._GetHeaderInfo()
+ if self._ModuleUnloadImageList is None:
+ self._ModuleUnloadImageList = []
+ return self._ModuleUnloadImageList
+
+ ## Retrieve CONSTRUCTOR
+ @cached_property
+ def ConstructorList(self):
+ if self._ConstructorList is None:
+ self._GetHeaderInfo()
+ if self._ConstructorList is None:
+ self._ConstructorList = []
+ return self._ConstructorList
+
+ ## Retrieve DESTRUCTOR
+ @cached_property
+ def DestructorList(self):
+ if self._DestructorList is None:
+ self._GetHeaderInfo()
+ if self._DestructorList is None:
+ self._DestructorList = []
+ return self._DestructorList
+
+ ## Retrieve definies other than above ones
+ @cached_property
+ def Defines(self):
+ self._GetHeaderInfo()
+ return self._Defs
+
+ ## Retrieve binary files
+ @cached_class_function
+ def _GetBinaries(self):
+ RetVal = []
+ RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]
+ Macros = self._Macros
+ Macros['PROCESSOR'] = self._Arch
+ for Record in RecordList:
+ FileType = Record[0]
+ LineNo = Record[-1]
+ Target = TAB_COMMON
+ FeatureFlag = []
+ if Record[2]:
+ TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
+ if TokenList:
+ Target = TokenList[0]
+ if len(TokenList) > 1:
+ FeatureFlag = Record[1:]
+
+ File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate()
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+ RetVal.append(File)
+ return RetVal
+
+ ## Retrieve binary files with error check.
+ @cached_property
+ def Binaries(self):
+ RetVal = self._GetBinaries()
+ if GlobalData.gIgnoreSource and not RetVal:
+ ErrorInfo = "The INF file does not contain any RetVal to use in creating the image\n"
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)
+
+ return RetVal
+
+ ## Retrieve source files
+ @cached_property
+ def Sources(self):
+ self._GetHeaderInfo()
+ # Ignore all source files in a binary build mode
+ if GlobalData.gIgnoreSource:
+ return []
+
+ RetVal = []
+ RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
+ Macros = self._Macros
+ for Record in RecordList:
+ LineNo = Record[-1]
+ ToolChainFamily = Record[1]
+ # OptionsList := [TagName, ToolCode, FeatureFlag]
+ OptionsList = ['', '', '']
+ TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
+ for Index in range(len(TokenList)):
+ OptionsList[Index] = TokenList[Index]
+ if OptionsList[2]:
+ FeaturePcdExpression = self.CheckFeatureFlagPcd(OptionsList[2])
+ if not FeaturePcdExpression:
+ continue
+ File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',
+ '', False, self._Arch, ToolChainFamily, '', OptionsList[0], OptionsList[1])
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate()
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+
+ RetVal.append(File)
+ # add any previously found dependency files to the source list
+ if self._DependencyFileList:
+ RetVal.extend(self._DependencyFileList)
+ return RetVal
+
+ ## Retrieve library classes employed by this module
+ @cached_property
+ def LibraryClasses(self):
+ RetVal = OrderedDict()
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]
+ for Record in RecordList:
+ Lib = Record[0]
+ Instance = Record[1]
+ if Instance:
+ Instance = NormPath(Instance, self._Macros)
+ RetVal[Lib] = Instance
+ else:
+ RetVal[Lib] = None
+ return RetVal
+
+ ## Retrieve library names (for Edk.x style of modules)
+ @cached_property
+ def Libraries(self):
+ RetVal = []
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]
+ for Record in RecordList:
+ LibraryName = ReplaceMacro(Record[0], self._Macros, False)
+ # in case of name with '.lib' extension, which is unusual in Edk.x inf
+ LibraryName = os.path.splitext(LibraryName)[0]
+ if LibraryName not in RetVal:
+ RetVal.append(LibraryName)
+ return RetVal
+
+ @cached_property
+ def ProtocolComments(self):
+ self.Protocols
+ return self._ProtocolComments
+
+ ## Retrieve protocols consumed/produced by this module
+ @cached_property
+ def Protocols(self):
+ RetVal = OrderedDict()
+ self._ProtocolComments = OrderedDict()
+ RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
+ for Record in RecordList:
+ CName = Record[0]
+ Value = _ProtocolValue(CName, self.Packages, self.MetaFile.Path)
+ if Value is None:
+ PackageList = "\n\t".join(str(P) for P in self.Packages)
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
+ "Value of Protocol [%s] is not found under [Protocols] section in" % CName,
+ ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
+ RetVal[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ self._ProtocolComments[CName] = [a[0] for a in CommentRecords]
+ return RetVal
+
+ @cached_property
+ def PpiComments(self):
+ self.Ppis
+ return self._PpiComments
+
+ ## Retrieve PPIs consumed/produced by this module
+ @cached_property
+ def Ppis(self):
+ RetVal = OrderedDict()
+ self._PpiComments = OrderedDict()
+ RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
+ for Record in RecordList:
+ CName = Record[0]
+ Value = _PpiValue(CName, self.Packages, self.MetaFile.Path)
+ if Value is None:
+ PackageList = "\n\t".join(str(P) for P in self.Packages)
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
+ "Value of PPI [%s] is not found under [Ppis] section in " % CName,
+ ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
+ RetVal[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ self._PpiComments[CName] = [a[0] for a in CommentRecords]
+ return RetVal
+
+ @cached_property
+ def GuidComments(self):
+ self.Guids
+ return self._GuidComments
+
+ ## Retrieve GUIDs consumed/produced by this module
+ @cached_property
+ def Guids(self):
+ RetVal = OrderedDict()
+ self._GuidComments = OrderedDict()
+ RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
+ for Record in RecordList:
+ CName = Record[0]
+ Value = GuidValue(CName, self.Packages, self.MetaFile.Path)
+ if Value is None:
+ PackageList = "\n\t".join(str(P) for P in self.Packages)
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
+ "Value of Guid [%s] is not found under [Guids] section in" % CName,
+ ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
+ RetVal[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ self._GuidComments[CName] = [a[0] for a in CommentRecords]
+
+ for Type in [MODEL_PCD_FIXED_AT_BUILD,MODEL_PCD_PATCHABLE_IN_MODULE,MODEL_PCD_FEATURE_FLAG,MODEL_PCD_DYNAMIC,MODEL_PCD_DYNAMIC_EX]:
+ RecordList = self._RawData[Type, self._Arch, self._Platform]
+ for TokenSpaceGuid, _, _, _, _, _, LineNo in RecordList:
+ # get the guid value
+ if TokenSpaceGuid not in RetVal:
+ Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)
+ if Value is None:
+ PackageList = "\n\t".join(str(P) for P in self.Packages)
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
+ "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,
+ ExtraData=PackageList, File=self.MetaFile, Line=LineNo)
+ RetVal[TokenSpaceGuid] = Value
+ self._GuidsUsedByPcd[TokenSpaceGuid] = Value
+ return RetVal
+
+ ## Retrieve include paths necessary for this module (for Edk.x style of modules)
+ @cached_property
+ def Includes(self):
+ RetVal = []
+ Macros = self._Macros
+ Macros['PROCESSOR'] = GlobalData.gEdkGlobal.get('PROCESSOR', self._Arch)
+ RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]
+ for Record in RecordList:
+ File = NormPath(Record[0], Macros)
+ if File[0] == '.':
+ File = os.path.join(self._ModuleDir, File)
+ else:
+ File = mws.join(GlobalData.gWorkspace, File)
+ File = RealPath(os.path.normpath(File))
+ if File:
+ RetVal.append(File)
+ return RetVal
+
+ ## Retrieve packages this module depends on
+ @cached_property
+ def Packages(self):
+ RetVal = []
+ RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]
+ Macros = self._Macros
+ for Record in RecordList:
+ File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate('.dec')
+ if ErrorCode != 0:
+ LineNo = Record[-1]
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+ # parse this package now. we need it to get protocol/ppi/guid value
+ RetVal.append(self._Bdb[File, self._Arch, self._Target, self._Toolchain])
+ return RetVal
+
+ ## Retrieve PCD comments
+ @cached_property
+ def PcdComments(self):
+ self.Pcds
+ return self._PcdComments
+
+ ## Retrieve PCDs used in this module
+ @cached_property
+ def Pcds(self):
+ self._PcdComments = OrderedDict()
+ RetVal = OrderedDict()
+ RetVal.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
+ RetVal.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
+ RetVal.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
+ RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC))
+ RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
+ return RetVal
+
+ @cached_property
+ def ModulePcdList(self):
+ RetVal = self.Pcds
+ return RetVal
+ @cached_property
+ def LibraryPcdList(self):
+ if bool(self.LibraryClass):
+ return []
+ RetVal = {}
+ Pcds = set()
+ for Library in self.LibInstances:
+ PcdsInLibrary = OrderedDict()
+ for Key in Library.Pcds:
+ if Key in self.Pcds or Key in Pcds:
+ continue
+ Pcds.add(Key)
+ PcdsInLibrary[Key] = copy.copy(Library.Pcds[Key])
+ RetVal[Library] = PcdsInLibrary
+ return RetVal
+ @cached_property
+ def PcdsName(self):
+ PcdsName = set()
+ for Type in (MODEL_PCD_FIXED_AT_BUILD,MODEL_PCD_PATCHABLE_IN_MODULE,MODEL_PCD_FEATURE_FLAG,MODEL_PCD_DYNAMIC,MODEL_PCD_DYNAMIC_EX):
+ RecordList = self._RawData[Type, self._Arch, self._Platform]
+ for TokenSpaceGuid, PcdCName, _, _, _, _, _ in RecordList:
+ PcdsName.add((PcdCName, TokenSpaceGuid))
+ return PcdsName
+
+ ## Retrieve build options specific to this module
+ @cached_property
+ def BuildOptions(self):
+ if self._BuildOptions is None:
+ self._BuildOptions = OrderedDict()
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]
+ for Record in RecordList:
+ ToolChainFamily = Record[0]
+ ToolChain = Record[1]
+ Option = Record[2]
+ if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):
+ self._BuildOptions[ToolChainFamily, ToolChain] = Option
+ else:
+ # concatenate the option string if they're for the same tool
+ OptionString = self._BuildOptions[ToolChainFamily, ToolChain]
+ self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
+ return self._BuildOptions
+
+ ## Retrieve dependency expression
+ @cached_property
+ def Depex(self):
+ RetVal = tdict(False, 2)
+
+ # If the module has only Binaries and no Sources, then ignore [Depex]
+ if not self.Sources and self.Binaries:
+ return RetVal
+
+ RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
+ # PEIM and DXE drivers must have a valid [Depex] section
+ if len(self.LibraryClass) == 0 and len(RecordList) == 0:
+ if self.ModuleType == SUP_MODULE_DXE_DRIVER or self.ModuleType == SUP_MODULE_PEIM or self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER or \
+ self.ModuleType == SUP_MODULE_DXE_SAL_DRIVER or self.ModuleType == SUP_MODULE_DXE_RUNTIME_DRIVER:
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
+ % self.ModuleType, File=self.MetaFile)
+
+ if len(RecordList) != 0 and (self.ModuleType == SUP_MODULE_USER_DEFINED or self.ModuleType == SUP_MODULE_HOST_APPLICATION):
+ for Record in RecordList:
+ if Record[4] not in [SUP_MODULE_PEIM, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER]:
+ EdkLogger.error('build', FORMAT_INVALID,
+ "'%s' module must specify the type of [Depex] section" % self.ModuleType,
+ File=self.MetaFile)
+
+ TemporaryDictionary = OrderedDict()
+ for Record in RecordList:
+ DepexStr = ReplaceMacro(Record[0], self._Macros, False)
+ Arch = Record[3]
+ ModuleType = Record[4]
+ TokenList = DepexStr.split()
+ if (Arch, ModuleType) not in TemporaryDictionary:
+ TemporaryDictionary[Arch, ModuleType] = []
+ DepexList = TemporaryDictionary[Arch, ModuleType]
+ for Token in TokenList:
+ if Token in DEPEX_SUPPORTED_OPCODE_SET:
+ DepexList.append(Token)
+ elif Token.endswith(".inf"): # module file name
+ ModuleFile = os.path.normpath(Token)
+ Module = self.BuildDatabase[ModuleFile]
+ if Module is None:
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",
+ ExtraData=Token, File=self.MetaFile, Line=Record[-1])
+ DepexList.append(Module.Guid)
+ else:
+ # it use the Fixed PCD format
+ if '.' in Token:
+ if tuple(Token.split('.')[::-1]) not in self.Pcds:
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "PCD [{}] used in [Depex] section should be listed in module PCD section".format(Token), File=self.MetaFile, Line=Record[-1])
+ else:
+ if self.Pcds[tuple(Token.split('.')[::-1])].DatumType != TAB_VOID:
+ EdkLogger.error('build', FORMAT_INVALID, "PCD [{}] used in [Depex] section should be VOID* datum type".format(Token), File=self.MetaFile, Line=Record[-1])
+ Value = Token
+ else:
+ # get the GUID value now
+ Value = _ProtocolValue(Token, self.Packages, self.MetaFile.Path)
+ if Value is None:
+ Value = _PpiValue(Token, self.Packages, self.MetaFile.Path)
+ if Value is None:
+ Value = GuidValue(Token, self.Packages, self.MetaFile.Path)
+
+ if Value is None:
+ PackageList = "\n\t".join(str(P) for P in self.Packages)
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
+ "Value of [%s] is not found in" % Token,
+ ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
+ DepexList.append(Value)
+ for Arch, ModuleType in TemporaryDictionary:
+ RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]
+ return RetVal
+
+ ## Retrieve dependency expression
+ @cached_property
+ def DepexExpression(self):
+ RetVal = tdict(False, 2)
+ RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
+ TemporaryDictionary = OrderedDict()
+ for Record in RecordList:
+ DepexStr = ReplaceMacro(Record[0], self._Macros, False)
+ Arch = Record[3]
+ ModuleType = Record[4]
+ TokenList = DepexStr.split()
+ if (Arch, ModuleType) not in TemporaryDictionary:
+ TemporaryDictionary[Arch, ModuleType] = ''
+ for Token in TokenList:
+ TemporaryDictionary[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType] + Token.strip() + ' '
+ for Arch, ModuleType in TemporaryDictionary:
+ RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]
+ return RetVal
+ def LocalPkg(self):
+ module_path = self.MetaFile.File
+ subdir = os.path.split(module_path)[0]
+ TopDir = ""
+ while subdir:
+ subdir,TopDir = os.path.split(subdir)
+
+ for file_name in os.listdir(os.path.join(self.MetaFile.Root,TopDir)):
+ if file_name.upper().endswith("DEC"):
+ pkg = os.path.join(TopDir,file_name)
+ return pkg
+ @cached_class_function
+ def GetGuidsUsedByPcd(self):
+ self.Guid
+ return self._GuidsUsedByPcd
+
+ ## Retrieve PCD for given type
+ def _GetPcd(self, Type):
+ Pcds = OrderedDict()
+ PcdDict = tdict(True, 4)
+ PcdList = []
+ RecordList = self._RawData[Type, self._Arch, self._Platform]
+ for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:
+ PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)
+ PcdList.append((PcdCName, TokenSpaceGuid))
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._PcdComments[TokenSpaceGuid, PcdCName] = Comments
+
+ # resolve PCD type, value, datum info, etc. by getting its definition from package
+ _GuidDict = self.Guids.copy()
+ for PcdCName, TokenSpaceGuid in PcdList:
+ PcdRealName = PcdCName
+ Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]
+ if Setting is None:
+ continue
+ ValueList = AnalyzePcdData(Setting)
+ DefaultValue = ValueList[0]
+ Pcd = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ '',
+ '',
+ DefaultValue,
+ '',
+ '',
+ {},
+ False,
+ self.Guids[TokenSpaceGuid]
+ )
+ if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:
+ # Patch PCD: TokenSpace.PcdCName|Value|Offset
+ Pcd.Offset = ValueList[1]
+
+ if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
+ for Package in self.Packages:
+ for key in Package.Pcds:
+ if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):
+ for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
+ Pcd_Type = item[0].split('_')[-1]
+ if Pcd_Type == Package.Pcds[key].Type:
+ Value = Package.Pcds[key]
+ Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type
+ if len(key) == 2:
+ newkey = (Value.TokenCName, key[1])
+ elif len(key) == 3:
+ newkey = (Value.TokenCName, key[1], key[2])
+ del Package.Pcds[key]
+ Package.Pcds[newkey] = Value
+ break
+ else:
+ pass
+ else:
+ pass
+
+ # get necessary info from package declaring this PCD
+ for Package in self.Packages:
+ #
+ # 'dynamic' in INF means its type is determined by platform;
+ # if platform doesn't give its type, use 'lowest' one in the
+ # following order, if any
+ #
+ # TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX
+ #
+ _GuidDict.update(Package.Guids)
+ PcdType = self._PCD_TYPE_STRING_[Type]
+ if Type == MODEL_PCD_DYNAMIC:
+ Pcd.Pending = True
+ for T in PCD_TYPE_LIST:
+ if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
+ for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
+ if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:
+ PcdType = T
+ PcdCName = item[0]
+ break
+ else:
+ pass
+ break
+ else:
+ if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:
+ PcdType = T
+ break
+
+ else:
+ Pcd.Pending = False
+ if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
+ for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
+ Pcd_Type = item[0].split('_')[-1]
+ if Pcd_Type == PcdType:
+ PcdCName = item[0]
+ break
+ else:
+ pass
+ else:
+ pass
+
+ if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:
+ PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]
+ Pcd.Type = PcdType
+ Pcd.TokenValue = PcdInPackage.TokenValue
+
+ #
+ # Check whether the token value exist or not.
+ #
+ if Pcd.TokenValue is None or Pcd.TokenValue == "":
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData=None
+ )
+ #
+ # Check hexadecimal token value length and format.
+ #
+ ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)
+ if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):
+ if ReIsValidPcdTokenValue.match(Pcd.TokenValue) is None:
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData=None
+ )
+
+ #
+ # Check decimal token value length and format.
+ #
+ else:
+ try:
+ TokenValueInt = int (Pcd.TokenValue, 10)
+ if (TokenValueInt < 0 or TokenValueInt > 4294967295):
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData=None
+ )
+ except:
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData=None
+ )
+
+ Pcd.DatumType = PcdInPackage.DatumType
+ Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize
+ Pcd.InfDefaultValue = Pcd.DefaultValue
+ if not Pcd.DefaultValue:
+ Pcd.DefaultValue = PcdInPackage.DefaultValue
+ else:
+ try:
+ Pcd.DefaultValue = ValueExpressionEx(Pcd.DefaultValue, Pcd.DatumType, _GuidDict)(True)
+ except BadExpression as Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(TokenSpaceGuid, PcdRealName, Pcd.DefaultValue, Value),
+ File=self.MetaFile, Line=LineNo)
+ break
+ else:
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData="\t%s" % '\n\t'.join(str(P) for P in self.Packages)
+ )
+ Pcds[PcdCName, TokenSpaceGuid] = Pcd
+
+ return Pcds
+
+ ## check whether current module is binary module
+ @property
+ def IsBinaryModule(self):
+ if (self.Binaries and not self.Sources) or GlobalData.gIgnoreSource:
+ return True
+ return False
+ def CheckFeatureFlagPcd(self,Instance):
+ Pcds = GlobalData.gPlatformFinalPcds.copy()
+ if PcdPattern.search(Instance):
+ PcdTuple = tuple(Instance.split('.')[::-1])
+ if PcdTuple in self.Pcds:
+ if not (self.Pcds[PcdTuple].Type == 'FeatureFlag' or self.Pcds[PcdTuple].Type == 'FixedAtBuild'):
+ EdkLogger.error('build', FORMAT_INVALID,
+ "\nFeatureFlagPcd must be defined in a [PcdsFeatureFlag] or [PcdsFixedAtBuild] section of Dsc or Dec file",
+ File=str(self), ExtraData=Instance)
+ if not Instance in Pcds:
+ Pcds[Instance] = self.Pcds[PcdTuple].DefaultValue
+ else: #if PcdTuple not in self.Pcds:
+ EdkLogger.error('build', FORMAT_INVALID,
+ "\nFeatureFlagPcd must be defined in [FeaturePcd] or [FixedPcd] of Inf file",
+ File=str(self), ExtraData=Instance)
+ if Instance in Pcds:
+ if Pcds[Instance] == '0':
+ return False
+ elif Pcds[Instance] == '1':
+ return True
+ try:
+ Value = ValueExpression(Instance, Pcds)()
+ if Value == True:
+ return True
+ return False
+ except:
+ EdkLogger.warn('build', FORMAT_INVALID,"The FeatureFlagExpression cannot be evaluated", File=str(self), ExtraData=Instance)
+ return False
+ else:
+ for Name, Guid in self.Pcds:
+ if self.Pcds[(Name, Guid)].Type == 'FeatureFlag' or self.Pcds[(Name, Guid)].Type == 'FixedAtBuild':
+ PcdFullName = '%s.%s' % (Guid, Name);
+ if not PcdFullName in Pcds:
+ Pcds[PcdFullName] = self.Pcds[(Name, Guid)].DefaultValue
+ try:
+ Value = ValueExpression(Instance, Pcds)()
+ if Value == True:
+ return True
+ return False
+ except:
+ EdkLogger.warn('build', FORMAT_INVALID, "The FeatureFlagExpression cannot be evaluated", File=str(self), ExtraData=Instance)
+ return False
+def ExtendCopyDictionaryLists(CopyToDict, CopyFromDict):
+ for Key in CopyFromDict:
+ CopyToDict[Key].extend(CopyFromDict[Key])
diff --git a/BaseTools/Source/Python/Workspace/MetaDataTable.py b/BaseTools/Source/Python/Workspace/MetaDataTable.py
index a20bd14784..22f8c7fe22 100644
--- a/BaseTools/Source/Python/Workspace/MetaDataTable.py
+++ b/BaseTools/Source/Python/Workspace/MetaDataTable.py
@@ -1,306 +1,306 @@
-## @file
-# This file is used to create/update/query/erase table for files
-#
-# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-import Common.LongFilePathOs as os
-
-import Common.EdkLogger as EdkLogger
-from CommonDataClass import DataClass
-from CommonDataClass.DataClass import FileClass
-
-## Convert to SQL required string format
-def ConvertToSqlString(StringList):
- return list(map(lambda s: "'" + s.replace("'", "''") + "'", StringList))
-
-## TableFile
-#
-# This class defined a common table
-#
-# @param object: Inherited from object class
-#
-# @param Cursor: Cursor of the database
-# @param TableName: Name of the table
-#
-class Table(object):
- _COLUMN_ = ''
- _ID_STEP_ = 1
- _ID_MAX_ = 0x80000000
- _DUMMY_ = 0
-
- def __init__(self, Db, Name='', IdBase=0, Temporary=False):
- self.Db = Db
- self.Table = Name
- self.IdBase = int(IdBase)
- self.ID = int(IdBase)
- self.Temporary = Temporary
- self.Contents = []
-
- def __str__(self):
- return self.Table
-
- ## Create table
- #
- # Create a table
- #
- def Create(self, NewTable=True):
- self.Db.CreateEmptyTable(self.Table)
- self.ID = self.GetId()
-
- ## Insert table
- #
- # Insert a record into a table
- #
- def Insert(self, *Args):
- self.ID = self.ID + self._ID_STEP_
- if self.ID >= (self.IdBase + self._ID_MAX_):
- self.ID = self.IdBase + self._ID_STEP_
- row = [self.ID]
- row.extend(Args)
- self.Contents.append(row)
-
- return self.ID
-
-
- ## Get count
- #
- # Get a count of all records of the table
- #
- # @retval Count: Total count of all records
- #
- def GetCount(self):
- tab = self.Db.GetTable(self.Table)
- return len(tab)
-
-
- def GetId(self):
- tab = self.Db.GetTable(self.Table)
- Id = max([int(item[0]) for item in tab])
- if Id is None:
- Id = self.IdBase
- return Id
-
- ## Init the ID of the table
- #
- # Init the ID of the table
- #
- def InitID(self):
- self.ID = self.GetId()
-
- ## Exec
- #
- # Exec Sql Command, return result
- #
- # @param SqlCommand: The SqlCommand to be executed
- #
- # @retval RecordSet: The result after executed
- #
- def Exec(self, SqlCommand):
- EdkLogger.debug(EdkLogger.DEBUG_5, SqlCommand)
- self.Db.execute(SqlCommand)
- RecordSet = self.Db.fetchall()
- return RecordSet
-
- def SetEndFlag(self):
- Tab = self.Db.GetTable(self.Table)
- Tab.append(self._DUMMY_)
-
-
- def IsIntegral(self):
- tab = self.Db.GetTable(self.Table)
- Id = min([int(item[0]) for item in tab])
- if Id != -1:
- return False
- return True
-
- def GetAll(self):
- tab = self.Db.GetTable(self.Table)
- return tab
-
-
-## TableFile
-#
-# This class defined a table used for file
-#
-# @param object: Inherited from object class
-#
-class TableFile(Table):
- _COLUMN_ = '''
- ID INTEGER PRIMARY KEY,
- Name VARCHAR NOT NULL,
- ExtName VARCHAR,
- Path VARCHAR,
- FullPath VARCHAR NOT NULL,
- Model INTEGER DEFAULT 0,
- TimeStamp SINGLE NOT NULL,
- FromItem REAL NOT NULL
- '''
- def __init__(self, Cursor):
- Table.__init__(self, Cursor, 'File')
-
- ## Insert table
- #
- # Insert a record into table File
- #
- # @param Name: Name of a File
- # @param ExtName: ExtName of a File
- # @param Path: Path of a File
- # @param FullPath: FullPath of a File
- # @param Model: Model of a File
- # @param TimeStamp: TimeStamp of a File
- #
- def Insert(self, Name, ExtName, Path, FullPath, Model, TimeStamp, FromItem=0):
- (Name, ExtName, Path, FullPath) = ConvertToSqlString((Name, ExtName, Path, FullPath))
- return Table.Insert(
- self,
- Name,
- ExtName,
- Path,
- FullPath,
- Model,
- TimeStamp,
- FromItem
- )
-
- ## InsertFile
- #
- # Insert one file to table
- #
- # @param FileFullPath: The full path of the file
- # @param Model: The model of the file
- #
- # @retval FileID: The ID after record is inserted
- #
- def InsertFile(self, File, Model, FromItem=''):
- if FromItem:
- return self.Insert(
- File.Name,
- File.Ext,
- File.Dir,
- File.Path,
- Model,
- File.TimeStamp,
- FromItem
- )
- return self.Insert(
- File.Name,
- File.Ext,
- File.Dir,
- File.Path,
- Model,
- File.TimeStamp
- )
-
- ## Get type of a given file
- #
- # @param FileId ID of a file
- #
- # @retval file_type Model value of given file in the table
- #
- def GetFileType(self, FileId):
- QueryScript = "select Model from %s where ID = '%s'" % (self.Table, FileId)
- RecordList = self.Exec(QueryScript)
- if len(RecordList) == 0:
- return None
- return RecordList[0][0]
-
- ## Get file timestamp of a given file
- #
- # @param FileId ID of file
- #
- # @retval timestamp TimeStamp value of given file in the table
- #
- def GetFileTimeStamp(self, FileId):
- QueryScript = "select TimeStamp from %s where ID = '%s'" % (self.Table, FileId)
- RecordList = self.Exec(QueryScript)
- if len(RecordList) == 0:
- return None
- return RecordList[0][0]
-
- ## Update the timestamp of a given file
- #
- # @param FileId ID of file
- # @param TimeStamp Time stamp of file
- #
- def SetFileTimeStamp(self, FileId, TimeStamp):
- self.Exec("update %s set TimeStamp=%s where ID='%s'" % (self.Table, TimeStamp, FileId))
-
- ## Get list of file with given type
- #
- # @param FileType Type value of file
- #
- # @retval file_list List of files with the given type
- #
- def GetFileList(self, FileType):
- RecordList = self.Exec("select FullPath from %s where Model=%s" % (self.Table, FileType))
- if len(RecordList) == 0:
- return []
- return [R[0] for R in RecordList]
-
-## TableDataModel
-#
-# This class defined a table used for data model
-#
-# @param object: Inherited from object class
-#
-#
-class TableDataModel(Table):
- _COLUMN_ = """
- ID INTEGER PRIMARY KEY,
- CrossIndex INTEGER NOT NULL,
- Name VARCHAR NOT NULL,
- Description VARCHAR
- """
- def __init__(self, Cursor):
- Table.__init__(self, Cursor, 'DataModel')
-
- ## Insert table
- #
- # Insert a record into table DataModel
- #
- # @param ID: ID of a ModelType
- # @param CrossIndex: CrossIndex of a ModelType
- # @param Name: Name of a ModelType
- # @param Description: Description of a ModelType
- #
- def Insert(self, CrossIndex, Name, Description):
- (Name, Description) = ConvertToSqlString((Name, Description))
- return Table.Insert(self, CrossIndex, Name, Description)
-
- ## Init table
- #
- # Create all default records of table DataModel
- #
- def InitTable(self):
- EdkLogger.verbose("\nInitialize table DataModel started ...")
- Count = self.GetCount()
- if Count is not None and Count != 0:
- return
- for Item in DataClass.MODEL_LIST:
- CrossIndex = Item[1]
- Name = Item[0]
- Description = Item[0]
- self.Insert(CrossIndex, Name, Description)
- EdkLogger.verbose("Initialize table DataModel ... DONE!")
-
- ## Get CrossIndex
- #
- # Get a model's cross index from its name
- #
- # @param ModelName: Name of the model
- # @retval CrossIndex: CrossIndex of the model
- #
- def GetCrossIndex(self, ModelName):
- CrossIndex = -1
- SqlCommand = """select CrossIndex from DataModel where name = '""" + ModelName + """'"""
- self.Db.execute(SqlCommand)
- for Item in self.Db:
- CrossIndex = Item[0]
-
- return CrossIndex
-
+## @file
+# This file is used to create/update/query/erase table for files
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+##
+# Import Modules
+#
+import Common.LongFilePathOs as os
+
+import Common.EdkLogger as EdkLogger
+from CommonDataClass import DataClass
+from CommonDataClass.DataClass import FileClass
+
+## Convert to SQL required string format
+def ConvertToSqlString(StringList):
+ return list(map(lambda s: "'" + s.replace("'", "''") + "'", StringList))
+
+## TableFile
+#
+# This class defined a common table
+#
+# @param object: Inherited from object class
+#
+# @param Cursor: Cursor of the database
+# @param TableName: Name of the table
+#
+class Table(object):
+ _COLUMN_ = ''
+ _ID_STEP_ = 1
+ _ID_MAX_ = 0x80000000
+ _DUMMY_ = 0
+
+ def __init__(self, Db, Name='', IdBase=0, Temporary=False):
+ self.Db = Db
+ self.Table = Name
+ self.IdBase = int(IdBase)
+ self.ID = int(IdBase)
+ self.Temporary = Temporary
+ self.Contents = []
+
+ def __str__(self):
+ return self.Table
+
+ ## Create table
+ #
+ # Create a table
+ #
+ def Create(self, NewTable=True):
+ self.Db.CreateEmptyTable(self.Table)
+ self.ID = self.GetId()
+
+ ## Insert table
+ #
+ # Insert a record into a table
+ #
+ def Insert(self, *Args):
+ self.ID = self.ID + self._ID_STEP_
+ if self.ID >= (self.IdBase + self._ID_MAX_):
+ self.ID = self.IdBase + self._ID_STEP_
+ row = [self.ID]
+ row.extend(Args)
+ self.Contents.append(row)
+
+ return self.ID
+
+
+ ## Get count
+ #
+ # Get a count of all records of the table
+ #
+ # @retval Count: Total count of all records
+ #
+ def GetCount(self):
+ tab = self.Db.GetTable(self.Table)
+ return len(tab)
+
+
+ def GetId(self):
+ tab = self.Db.GetTable(self.Table)
+ Id = max([int(item[0]) for item in tab])
+ if Id is None:
+ Id = self.IdBase
+ return Id
+
+ ## Init the ID of the table
+ #
+ # Init the ID of the table
+ #
+ def InitID(self):
+ self.ID = self.GetId()
+
+ ## Exec
+ #
+ # Exec Sql Command, return result
+ #
+ # @param SqlCommand: The SqlCommand to be executed
+ #
+ # @retval RecordSet: The result after executed
+ #
+ def Exec(self, SqlCommand):
+ EdkLogger.debug(EdkLogger.DEBUG_5, SqlCommand)
+ self.Db.execute(SqlCommand)
+ RecordSet = self.Db.fetchall()
+ return RecordSet
+
+ def SetEndFlag(self):
+ Tab = self.Db.GetTable(self.Table)
+ Tab.append(self._DUMMY_)
+
+
+ def IsIntegral(self):
+ tab = self.Db.GetTable(self.Table)
+ Id = min([int(item[0]) for item in tab])
+ if Id != -1:
+ return False
+ return True
+
+ def GetAll(self):
+ tab = self.Db.GetTable(self.Table)
+ return tab
+
+
+## TableFile
+#
+# This class defined a table used for file
+#
+# @param object: Inherited from object class
+#
+class TableFile(Table):
+ _COLUMN_ = '''
+ ID INTEGER PRIMARY KEY,
+ Name VARCHAR NOT NULL,
+ ExtName VARCHAR,
+ Path VARCHAR,
+ FullPath VARCHAR NOT NULL,
+ Model INTEGER DEFAULT 0,
+ TimeStamp SINGLE NOT NULL,
+ FromItem REAL NOT NULL
+ '''
+ def __init__(self, Cursor):
+ Table.__init__(self, Cursor, 'File')
+
+ ## Insert table
+ #
+ # Insert a record into table File
+ #
+ # @param Name: Name of a File
+ # @param ExtName: ExtName of a File
+ # @param Path: Path of a File
+ # @param FullPath: FullPath of a File
+ # @param Model: Model of a File
+ # @param TimeStamp: TimeStamp of a File
+ #
+ def Insert(self, Name, ExtName, Path, FullPath, Model, TimeStamp, FromItem=0):
+ (Name, ExtName, Path, FullPath) = ConvertToSqlString((Name, ExtName, Path, FullPath))
+ return Table.Insert(
+ self,
+ Name,
+ ExtName,
+ Path,
+ FullPath,
+ Model,
+ TimeStamp,
+ FromItem
+ )
+
+ ## InsertFile
+ #
+ # Insert one file to table
+ #
+ # @param FileFullPath: The full path of the file
+ # @param Model: The model of the file
+ #
+ # @retval FileID: The ID after record is inserted
+ #
+ def InsertFile(self, File, Model, FromItem=''):
+ if FromItem:
+ return self.Insert(
+ File.Name,
+ File.Ext,
+ File.Dir,
+ File.Path,
+ Model,
+ File.TimeStamp,
+ FromItem
+ )
+ return self.Insert(
+ File.Name,
+ File.Ext,
+ File.Dir,
+ File.Path,
+ Model,
+ File.TimeStamp
+ )
+
+ ## Get type of a given file
+ #
+ # @param FileId ID of a file
+ #
+ # @retval file_type Model value of given file in the table
+ #
+ def GetFileType(self, FileId):
+ QueryScript = "select Model from %s where ID = '%s'" % (self.Table, FileId)
+ RecordList = self.Exec(QueryScript)
+ if len(RecordList) == 0:
+ return None
+ return RecordList[0][0]
+
+ ## Get file timestamp of a given file
+ #
+ # @param FileId ID of file
+ #
+ # @retval timestamp TimeStamp value of given file in the table
+ #
+ def GetFileTimeStamp(self, FileId):
+ QueryScript = "select TimeStamp from %s where ID = '%s'" % (self.Table, FileId)
+ RecordList = self.Exec(QueryScript)
+ if len(RecordList) == 0:
+ return None
+ return RecordList[0][0]
+
+ ## Update the timestamp of a given file
+ #
+ # @param FileId ID of file
+ # @param TimeStamp Time stamp of file
+ #
+ def SetFileTimeStamp(self, FileId, TimeStamp):
+ self.Exec("update %s set TimeStamp=%s where ID='%s'" % (self.Table, TimeStamp, FileId))
+
+ ## Get list of file with given type
+ #
+ # @param FileType Type value of file
+ #
+ # @retval file_list List of files with the given type
+ #
+ def GetFileList(self, FileType):
+ RecordList = self.Exec("select FullPath from %s where Model=%s" % (self.Table, FileType))
+ if len(RecordList) == 0:
+ return []
+ return [R[0] for R in RecordList]
+
+## TableDataModel
+#
+# This class defined a table used for data model
+#
+# @param object: Inherited from object class
+#
+#
+class TableDataModel(Table):
+ _COLUMN_ = """
+ ID INTEGER PRIMARY KEY,
+ CrossIndex INTEGER NOT NULL,
+ Name VARCHAR NOT NULL,
+ Description VARCHAR
+ """
+ def __init__(self, Cursor):
+ Table.__init__(self, Cursor, 'DataModel')
+
+ ## Insert table
+ #
+ # Insert a record into table DataModel
+ #
+ # @param ID: ID of a ModelType
+ # @param CrossIndex: CrossIndex of a ModelType
+ # @param Name: Name of a ModelType
+ # @param Description: Description of a ModelType
+ #
+ def Insert(self, CrossIndex, Name, Description):
+ (Name, Description) = ConvertToSqlString((Name, Description))
+ return Table.Insert(self, CrossIndex, Name, Description)
+
+ ## Init table
+ #
+ # Create all default records of table DataModel
+ #
+ def InitTable(self):
+ EdkLogger.verbose("\nInitialize table DataModel started ...")
+ Count = self.GetCount()
+ if Count is not None and Count != 0:
+ return
+ for Item in DataClass.MODEL_LIST:
+ CrossIndex = Item[1]
+ Name = Item[0]
+ Description = Item[0]
+ self.Insert(CrossIndex, Name, Description)
+ EdkLogger.verbose("Initialize table DataModel ... DONE!")
+
+ ## Get CrossIndex
+ #
+ # Get a model's cross index from its name
+ #
+ # @param ModelName: Name of the model
+ # @retval CrossIndex: CrossIndex of the model
+ #
+ def GetCrossIndex(self, ModelName):
+ CrossIndex = -1
+ SqlCommand = """select CrossIndex from DataModel where name = '""" + ModelName + """'"""
+ self.Db.execute(SqlCommand)
+ for Item in self.Db:
+ CrossIndex = Item[0]
+
+ return CrossIndex
+
diff --git a/BaseTools/Source/Python/Workspace/MetaFileCommentParser.py b/BaseTools/Source/Python/Workspace/MetaFileCommentParser.py
index 3737ae3511..333d56f3d7 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileCommentParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileCommentParser.py
@@ -1,45 +1,45 @@
-## @file
-# This file is used to check format of comments
-#
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from CommonDataClass.DataClass import (
- MODEL_PCD_PATCHABLE_IN_MODULE,
- MODEL_PCD_DYNAMIC_EX,
- MODEL_PCD_DYNAMIC,
- MODEL_EFI_GUID,
- MODEL_EFI_PPI,
- MODEL_EFI_PROTOCOL
-)
-from Common.BuildToolError import FORMAT_INVALID
-import Common.EdkLogger as EdkLogger
-
-UsageList = ("PRODUCES", "PRODUCED", "ALWAYS_PRODUCES", "ALWAYS_PRODUCED", "SOMETIMES_PRODUCES",
- "SOMETIMES_PRODUCED", "CONSUMES", "CONSUMED", "ALWAYS_CONSUMES", "ALWAYS_CONSUMED",
- "SOMETIMES_CONSUMES", "SOMETIMES_CONSUMED", "SOMETIME_CONSUMES")
-ErrorMsgMap = {
- MODEL_EFI_GUID : "The usage for this GUID is not listed in this INF: %s[%d]:%s",
- MODEL_EFI_PPI : "The usage for this PPI is not listed in this INF: %s[%d]:%s.",
- MODEL_EFI_PROTOCOL : "The usage for this Protocol is not listed in this INF: %s[%d]:%s.",
- MODEL_PCD_DYNAMIC : "The usage for this PCD is not listed in this INF: %s[%d]:%s."
-}
-
-def CheckInfComment(SectionType, Comments, InfFile, LineNo, ValueList):
- if SectionType in [MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_EX, MODEL_PCD_DYNAMIC]:
- CheckUsage(Comments, UsageList, InfFile, LineNo, ValueList[0]+'.'+ValueList[1], ErrorMsgMap[MODEL_PCD_DYNAMIC])
- elif SectionType in [MODEL_EFI_GUID, MODEL_EFI_PPI]:
- CheckUsage(Comments, UsageList, InfFile, LineNo, ValueList[0], ErrorMsgMap[SectionType])
- elif SectionType == MODEL_EFI_PROTOCOL:
- CheckUsage(Comments, UsageList + ("TO_START", "BY_START"), InfFile, LineNo, ValueList[0], ErrorMsgMap[SectionType])
-
-def CheckUsage(Comments, Usages, InfFile, LineNo, Value, ErrorMsg):
- for Comment in Comments:
- for Word in Comment[0].replace('#', ' ').split():
- if Word in Usages:
- return
- EdkLogger.error(
- "Parser", FORMAT_INVALID,
- ErrorMsg % (InfFile, LineNo, Value)
- )
+## @file
+# This file is used to check format of comments
+#
+# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+from CommonDataClass.DataClass import (
+ MODEL_PCD_PATCHABLE_IN_MODULE,
+ MODEL_PCD_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC,
+ MODEL_EFI_GUID,
+ MODEL_EFI_PPI,
+ MODEL_EFI_PROTOCOL
+)
+from Common.BuildToolError import FORMAT_INVALID
+import Common.EdkLogger as EdkLogger
+
+UsageList = ("PRODUCES", "PRODUCED", "ALWAYS_PRODUCES", "ALWAYS_PRODUCED", "SOMETIMES_PRODUCES",
+ "SOMETIMES_PRODUCED", "CONSUMES", "CONSUMED", "ALWAYS_CONSUMES", "ALWAYS_CONSUMED",
+ "SOMETIMES_CONSUMES", "SOMETIMES_CONSUMED", "SOMETIME_CONSUMES")
+ErrorMsgMap = {
+ MODEL_EFI_GUID : "The usage for this GUID is not listed in this INF: %s[%d]:%s",
+ MODEL_EFI_PPI : "The usage for this PPI is not listed in this INF: %s[%d]:%s.",
+ MODEL_EFI_PROTOCOL : "The usage for this Protocol is not listed in this INF: %s[%d]:%s.",
+ MODEL_PCD_DYNAMIC : "The usage for this PCD is not listed in this INF: %s[%d]:%s."
+}
+
+def CheckInfComment(SectionType, Comments, InfFile, LineNo, ValueList):
+ if SectionType in [MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_EX, MODEL_PCD_DYNAMIC]:
+ CheckUsage(Comments, UsageList, InfFile, LineNo, ValueList[0]+'.'+ValueList[1], ErrorMsgMap[MODEL_PCD_DYNAMIC])
+ elif SectionType in [MODEL_EFI_GUID, MODEL_EFI_PPI]:
+ CheckUsage(Comments, UsageList, InfFile, LineNo, ValueList[0], ErrorMsgMap[SectionType])
+ elif SectionType == MODEL_EFI_PROTOCOL:
+ CheckUsage(Comments, UsageList + ("TO_START", "BY_START"), InfFile, LineNo, ValueList[0], ErrorMsgMap[SectionType])
+
+def CheckUsage(Comments, Usages, InfFile, LineNo, Value, ErrorMsg):
+ for Comment in Comments:
+ for Word in Comment[0].replace('#', ' ').split():
+ if Word in Usages:
+ return
+ EdkLogger.error(
+ "Parser", FORMAT_INVALID,
+ ErrorMsg % (InfFile, LineNo, Value)
+ )
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 73a1654edb..5da5749bce 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -1,2197 +1,2197 @@
-## @file
-# This file is used to parse meta files
-#
-# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
-# (C) Copyright 2015-2018 Hewlett Packard Enterprise Development LP<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import print_function
-from __future__ import absolute_import
-import Common.LongFilePathOs as os
-import re
-import time
-import copy
-from hashlib import md5
-
-import Common.EdkLogger as EdkLogger
-import Common.GlobalData as GlobalData
-
-from CommonDataClass.DataClass import *
-from Common.DataType import *
-from Common.StringUtils import *
-from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression, ParseFieldValue, StructPattern
-from Common.Expression import *
-from CommonDataClass.Exceptions import *
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from collections import defaultdict
-from .MetaFileTable import MetaFileStorage
-from .MetaFileCommentParser import CheckInfComment
-from Common.DataType import TAB_COMMENT_EDK_START, TAB_COMMENT_EDK_END
-
-## RegEx for finding file versions
-hexVersionPattern = re.compile(r'0[xX][\da-f-A-F]{5,8}')
-decVersionPattern = re.compile(r'\d+\.\d+')
-CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")
-
-## A decorator used to parse macro definition
-def ParseMacro(Parser):
- def MacroParser(self):
- Match = GlobalData.gMacroDefPattern.match(self._CurrentLine)
- if not Match:
- # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
- Parser(self)
- return
-
- TokenList = GetSplitValueList(self._CurrentLine[Match.end(1):], TAB_EQUAL_SPLIT, 1)
- # Syntax check
- if not TokenList[0]:
- EdkLogger.error('Parser', FORMAT_INVALID, "No macro name given",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- if len(TokenList) < 2:
- TokenList.append('')
-
- Type = Match.group(1)
- Name, Value = TokenList
- # Global macros can be only defined via environment variable
- if Name in GlobalData.gGlobalDefines:
- EdkLogger.error('Parser', FORMAT_INVALID, "%s can only be defined via environment variable" % Name,
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- # Only upper case letters, digit and '_' are allowed
- if not GlobalData.gMacroNamePattern.match(Name):
- EdkLogger.error('Parser', FORMAT_INVALID, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
-
- Value = ReplaceMacro(Value, self._Macros)
- if Type in self.DataType:
- self._ItemType = self.DataType[Type]
- else:
- self._ItemType = MODEL_META_DATA_DEFINE
- # DEFINE defined macros
- if Type == TAB_DSC_DEFINES_DEFINE:
- #
- # First judge whether this DEFINE is in conditional directive statements or not.
- #
- if isinstance(self, DscParser) and self._InDirective > -1:
- pass
- else:
- if isinstance(self, DecParser):
- if MODEL_META_DATA_HEADER in self._SectionType:
- self._FileLocalMacros[Name] = Value
- else:
- self._ConstructSectionMacroDict(Name, Value)
- elif self._SectionType == MODEL_META_DATA_HEADER:
- self._FileLocalMacros[Name] = Value
- else:
- self._ConstructSectionMacroDict(Name, Value)
-
- # EDK_GLOBAL defined macros
- elif not isinstance(self, DscParser):
- EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used in .dsc file",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- elif self._SectionType != MODEL_META_DATA_HEADER:
- EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used under [Defines] section",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- elif (Name in self._FileLocalMacros) and (self._FileLocalMacros[Name] != Value):
- EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
-
- self._ValueList = [Type, Name, Value]
-
- return MacroParser
-
-## Base class of parser
-#
-# This class is used for derivation purpose. The specific parser for one kind
-# type file must derive this class and implement some public interfaces.
-#
-# @param FilePath The path of platform description file
-# @param FileType The raw data of DSC file
-# @param Table Database used to retrieve module/package information
-# @param Macros Macros used for replacement in file
-# @param Owner Owner ID (for sub-section parsing)
-# @param From ID from which the data comes (for !INCLUDE directive)
-#
-class MetaFileParser(object):
- # data type (file content) for specific file type
- DataType = {}
-
- # Parser objects used to implement singleton
- MetaFiles = {}
-
- ## Factory method
- #
- # One file, one parser object. This factory method makes sure that there's
- # only one object constructed for one meta file.
- #
- # @param Class class object of real AutoGen class
- # (InfParser, DecParser or DscParser)
- # @param FilePath The path of meta file
- # @param *args The specific class related parameters
- # @param **kwargs The specific class related dict parameters
- #
- def __new__(Class, FilePath, *args, **kwargs):
- if FilePath in Class.MetaFiles:
- return Class.MetaFiles[FilePath]
- else:
- ParserObject = super(MetaFileParser, Class).__new__(Class)
- Class.MetaFiles[FilePath] = ParserObject
- return ParserObject
-
- ## Constructor of MetaFileParser
- #
- # Initialize object of MetaFileParser
- #
- # @param FilePath The path of platform description file
- # @param FileType The raw data of DSC file
- # @param Arch Default Arch value for filtering sections
- # @param Table Database used to retrieve module/package information
- # @param Owner Owner ID (for sub-section parsing)
- # @param From ID from which the data comes (for !INCLUDE directive)
- #
- def __init__(self, FilePath, FileType, Arch, Table, Owner= -1, From= -1):
- self._Table = Table
- self._RawTable = Table
- self._Arch = Arch
- self._FileType = FileType
- self.MetaFile = FilePath
- self._FileDir = self.MetaFile.Dir
- self._Defines = {}
- self._Packages = []
- self._FileLocalMacros = {}
- self._SectionsMacroDict = defaultdict(dict)
-
- # for recursive parsing
- self._Owner = [Owner]
- self._From = From
-
- # parsr status for parsing
- self._ValueList = ['', '', '', '', '']
- self._Scope = []
- self._LineIndex = 0
- self._CurrentLine = ''
- self._SectionType = MODEL_UNKNOWN
- self._SectionName = ''
- self._InSubsection = False
- self._SubsectionType = MODEL_UNKNOWN
- self._SubsectionName = ''
- self._ItemType = MODEL_UNKNOWN
- self._LastItem = -1
- self._Enabled = 0
- self._Finished = False
- self._PostProcessed = False
- # Different version of meta-file has different way to parse.
- self._Version = 0
- self._GuidDict = {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
-
- self._PcdCodeValue = ""
- self._PcdDataTypeCODE = False
- self._CurrentPcdName = ""
-
- ## Store the parsed data in table
- def _Store(self, *Args):
- return self._Table.Insert(*Args)
-
- ## Virtual method for starting parse
- def Start(self):
- raise NotImplementedError
-
- ## Notify a post-process is needed
- def DoPostProcess(self):
- self._PostProcessed = False
-
- ## Set parsing complete flag in both class and table
- def _Done(self):
- self._Finished = True
- self._Table.SetEndFlag()
-
- def _PostProcess(self):
- self._PostProcessed = True
-
- ## Get the parse complete flag
- @property
- def Finished(self):
- return self._Finished
-
- ## Set the complete flag
- @Finished.setter
- def Finished(self, Value):
- self._Finished = Value
-
- ## Remove records that do not match given Filter Arch
- def _FilterRecordList(self, RecordList, FilterArch):
- NewRecordList = []
- for Record in RecordList:
- Arch = Record[3]
- if Arch == TAB_ARCH_COMMON or Arch == FilterArch:
- NewRecordList.append(Record)
- return NewRecordList
-
- ## Use [] style to query data in table, just for readability
- #
- # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
- #
- def __getitem__(self, DataInfo):
- if not isinstance(DataInfo, type(())):
- DataInfo = (DataInfo,)
-
- # Parse the file first, if necessary
- self.StartParse()
-
- # No specific ARCH or Platform given, use raw data
- if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] is None):
- return self._FilterRecordList(self._RawTable.Query(*DataInfo), self._Arch)
-
- # Do post-process if necessary
- if not self._PostProcessed:
- self._PostProcess()
-
- return self._FilterRecordList(self._Table.Query(*DataInfo), DataInfo[1])
-
- def StartParse(self):
- if not self._Finished:
- if self._RawTable.IsIntegrity():
- self._Finished = True
- else:
- self._Table = self._RawTable
- self._PostProcessed = False
- self.Start()
- ## Data parser for the common format in different type of file
- #
- # The common format in the meatfile is like
- #
- # xxx1 | xxx2 | xxx3
- #
- @ParseMacro
- def _CommonParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
- self._ValueList[0:len(TokenList)] = TokenList
-
- ## Data parser for the format in which there's path
- #
- # Only path can have macro used. So we need to replace them before use.
- #
- @ParseMacro
- def _PathParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
- self._ValueList[0:len(TokenList)] = TokenList
- # Don't do macro replacement for dsc file at this point
- if not isinstance(self, DscParser):
- Macros = self._Macros
- self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]
-
- ## Skip unsupported data
- def _Skip(self):
- EdkLogger.warn("Parser", "Unrecognized content", File=self.MetaFile,
- Line=self._LineIndex + 1, ExtraData=self._CurrentLine);
- self._ValueList[0:1] = [self._CurrentLine]
-
- ## Skip unsupported data for UserExtension Section
- def _SkipUserExtension(self):
- self._ValueList[0:1] = [self._CurrentLine]
-
- ## Section header parser
- #
- # The section header is always in following format:
- #
- # [section_name.arch<.platform|module_type>]
- #
- def _SectionHeaderParser(self):
- self._Scope = []
- self._SectionName = ''
- ArchList = set()
- for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT):
- if Item == '':
- continue
- ItemList = GetSplitValueList(Item, TAB_SPLIT, 3)
- # different section should not mix in one section
- if self._SectionName != '' and self._SectionName != ItemList[0].upper():
- EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section",
- File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
- self._SectionName = ItemList[0].upper()
- if self._SectionName in self.DataType:
- self._SectionType = self.DataType[self._SectionName]
- # Check if the section name is valid
- if self._SectionName not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET and len(ItemList) > 3:
- EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
- self.MetaFile, self._LineIndex + 1, self._CurrentLine)
- elif self._Version >= 0x00010005:
- EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
- self.MetaFile, self._LineIndex + 1, self._CurrentLine)
- else:
- self._SectionType = MODEL_UNKNOWN
-
- # S1 is always Arch
- if len(ItemList) > 1:
- S1 = ItemList[1].upper()
- else:
- S1 = TAB_ARCH_COMMON
- S1 = ReplaceMacro(S1, self._Macros)
- ArchList.add(S1)
-
- # S2 may be Platform or ModuleType
- if len(ItemList) > 2:
- if self._SectionName.upper() in SECTIONS_HAVE_ITEM_PCD_SET:
- S2 = ItemList[2]
- else:
- S2 = ItemList[2].upper()
- else:
- S2 = TAB_COMMON
- if len(ItemList) > 3:
- S3 = ItemList[3]
- else:
- S3 = TAB_COMMON
- self._Scope.append([S1, S2, S3])
-
- # 'COMMON' must not be used with specific ARCHs at the same section
- if TAB_ARCH_COMMON in ArchList and len(ArchList) > 1:
- EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
- File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
- # If the section information is needed later, it should be stored in database
- self._ValueList[0] = self._SectionName
-
- ## [packages] section parser
- @ParseMacro
- def _PackageParser(self):
- self._CurrentLine = CleanString(self._CurrentLine)
- self._Packages.append(self._CurrentLine)
- self._ValueList[0] = self._CurrentLine
-
- ## [defines] section parser
- @ParseMacro
- def _DefineParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- self._ValueList[1:len(TokenList)] = TokenList
- if not self._ValueList[1]:
- EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- if not self._ValueList[2]:
- EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
-
- self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]
- Name, Value = self._ValueList[1], self._ValueList[2]
- MacroUsed = GlobalData.gMacroRefPattern.findall(Value)
- if len(MacroUsed) != 0:
- for Macro in MacroUsed:
- if Macro in GlobalData.gGlobalDefines:
- EdkLogger.error("Parser", FORMAT_INVALID, "Global macro %s is not permitted." % (Macro), ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- else:
- EdkLogger.error("Parser", FORMAT_INVALID, "%s not defined" % (Macro), ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- # Sometimes, we need to make differences between EDK and EDK2 modules
- if Name == 'INF_VERSION':
- if hexVersionPattern.match(Value):
- self._Version = int(Value, 0)
- elif decVersionPattern.match(Value):
- ValueList = Value.split('.')
- Major = int(ValueList[0], 0)
- Minor = int(ValueList[1], 0)
- if Major > 0xffff or Minor > 0xffff:
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- self._Version = int('0x{0:04x}{1:04x}'.format(Major, Minor), 0)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
-
- if isinstance(self, InfParser) and self._Version < 0x00010005:
- # EDK module allows using defines as macros
- self._FileLocalMacros[Name] = Value
- self._Defines[Name] = Value
-
- ## [BuildOptions] section parser
- @ParseMacro
- def _BuildOptionParser(self):
- self._CurrentLine = CleanString(self._CurrentLine, BuildOption=True)
- TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
- if len(TokenList2) == 2:
- self._ValueList[0] = TokenList2[0] # toolchain family
- self._ValueList[1] = TokenList2[1] # keys
- else:
- self._ValueList[1] = TokenList[0]
- if len(TokenList) == 2 and not isinstance(self, DscParser): # value
- self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)
-
- if self._ValueList[1].count('_') != 4:
- EdkLogger.error(
- 'Parser',
- FORMAT_INVALID,
- "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],
- ExtraData=self._CurrentLine,
- File=self.MetaFile,
- Line=self._LineIndex + 1
- )
- def GetValidExpression(self, TokenSpaceGuid, PcdCName):
- return self._Table.GetValidExpression(TokenSpaceGuid, PcdCName)
-
- @property
- def _Macros(self):
- Macros = {}
- Macros.update(self._FileLocalMacros)
- Macros.update(self._GetApplicableSectionMacro())
- return Macros
-
- ## Construct section Macro dict
- def _ConstructSectionMacroDict(self, Name, Value):
- ScopeKey = [(Scope[0], Scope[1], Scope[2]) for Scope in self._Scope]
- ScopeKey = tuple(ScopeKey)
- #
- # DecParser SectionType is a list, will contain more than one item only in Pcd Section
- # As Pcd section macro usage is not allowed, so here it is safe
- #
- if isinstance(self, DecParser):
- SectionDictKey = self._SectionType[0], ScopeKey
- else:
- SectionDictKey = self._SectionType, ScopeKey
-
- self._SectionsMacroDict[SectionDictKey][Name] = Value
-
- ## Get section Macros that are applicable to current line, which may come from other sections
- ## that share the same name while scope is wider
- def _GetApplicableSectionMacro(self):
- Macros = {}
-
- ComComMacroDict = {}
- ComSpeMacroDict = {}
- SpeSpeMacroDict = {}
-
- ActiveSectionType = self._SectionType
- if isinstance(self, DecParser):
- ActiveSectionType = self._SectionType[0]
-
- for (SectionType, Scope) in self._SectionsMacroDict:
- if SectionType != ActiveSectionType:
- continue
-
- for ActiveScope in self._Scope:
- Scope0, Scope1, Scope2= ActiveScope[0], ActiveScope[1], ActiveScope[2]
- if(Scope0, Scope1, Scope2) not in Scope:
- break
- else:
- SpeSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
-
- for ActiveScope in self._Scope:
- Scope0, Scope1, Scope2 = ActiveScope[0], ActiveScope[1], ActiveScope[2]
- if(Scope0, Scope1, Scope2) not in Scope and (Scope0, TAB_COMMON, TAB_COMMON) not in Scope and (TAB_COMMON, Scope1, TAB_COMMON) not in Scope:
- break
- else:
- ComSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
-
- if (TAB_COMMON, TAB_COMMON, TAB_COMMON) in Scope:
- ComComMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
-
- Macros.update(ComComMacroDict)
- Macros.update(ComSpeMacroDict)
- Macros.update(SpeSpeMacroDict)
-
- return Macros
-
- def ProcessMultipleLineCODEValue(self,Content):
- CODEBegin = False
- CODELine = ""
- continuelinecount = 0
- newContent = []
- for Index in range(0, len(Content)):
- Line = Content[Index]
- if CODEBegin:
- CODELine = CODELine + Line
- continuelinecount +=1
- if ")}" in Line:
- newContent.append(CODELine)
- for _ in range(continuelinecount):
- newContent.append("")
- CODEBegin = False
- CODELine = ""
- continuelinecount = 0
- else:
- if not Line:
- newContent.append(Line)
- continue
- if "{CODE(" not in Line:
- newContent.append(Line)
- continue
- elif CODEPattern.findall(Line):
- newContent.append(Line)
- continue
- else:
- CODEBegin = True
- CODELine = Line
-
- return newContent
-
- _SectionParser = {}
-
-## INF file parser class
-#
-# @param FilePath The path of platform description file
-# @param FileType The raw data of DSC file
-# @param Table Database used to retrieve module/package information
-# @param Macros Macros used for replacement in file
-#
-class InfParser(MetaFileParser):
- # INF file supported data types (one type per section)
- DataType = {
- TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
- TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,
- TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
- TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
- TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
- TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
- TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
- TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,
- TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,
- TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,
- TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
- TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,
- TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,
- TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,
- TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,
- TAB_GUIDS.upper() : MODEL_EFI_GUID,
- TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
- TAB_PPIS.upper() : MODEL_EFI_PPI,
- TAB_DEPEX.upper() : MODEL_EFI_DEPEX,
- TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,
- TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION
- }
-
- ## Constructor of InfParser
- #
- # Initialize object of InfParser
- #
- # @param FilePath The path of module description file
- # @param FileType The raw data of DSC file
- # @param Arch Default Arch value for filtering sections
- # @param Table Database used to retrieve module/package information
- #
- def __init__(self, FilePath, FileType, Arch, Table):
- # prevent re-initialization
- if hasattr(self, "_Table"):
- return
- MetaFileParser.__init__(self, FilePath, FileType, Arch, Table)
- self.PcdsDict = {}
-
- ## Parser starter
- def Start(self):
- NmakeLine = ''
- Content = ''
- try:
- with open(str(self.MetaFile), 'r') as File:
- Content = File.readlines()
- except:
- EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
-
- # parse the file line by line
- IsFindBlockComment = False
- GetHeaderComment = False
- TailComments = []
- SectionComments = []
- Comments = []
-
- for Index in range(0, len(Content)):
- # skip empty, commented, block commented lines
- Line, Comment = CleanString2(Content[Index], AllowCppStyleComment=True)
- NextLine = ''
- if Index + 1 < len(Content):
- NextLine, NextComment = CleanString2(Content[Index + 1])
- if Line == '':
- if Comment:
- Comments.append((Comment, Index + 1))
- elif GetHeaderComment:
- SectionComments.extend(Comments)
- Comments = []
- continue
- if Line.find(TAB_COMMENT_EDK_START) > -1:
- IsFindBlockComment = True
- continue
- if Line.find(TAB_COMMENT_EDK_END) > -1:
- IsFindBlockComment = False
- continue
- if IsFindBlockComment:
- continue
-
- self._LineIndex = Index
- self._CurrentLine = Line
-
- # section header
- if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
- if not GetHeaderComment:
- for Cmt, LNo in Comments:
- self._Store(MODEL_META_DATA_HEADER_COMMENT, Cmt, '', '', TAB_COMMON,
- TAB_COMMON, self._Owner[-1], LNo, -1, LNo, -1, 0)
- GetHeaderComment = True
- else:
- TailComments.extend(SectionComments + Comments)
- Comments = []
- self._SectionHeaderParser()
- # Check invalid sections
- if self._Version < 0x00010005:
- if self._SectionType in [MODEL_META_DATA_BUILD_OPTION,
- MODEL_EFI_LIBRARY_CLASS,
- MODEL_META_DATA_PACKAGE,
- MODEL_PCD_FIXED_AT_BUILD,
- MODEL_PCD_PATCHABLE_IN_MODULE,
- MODEL_PCD_FEATURE_FLAG,
- MODEL_PCD_DYNAMIC_EX,
- MODEL_PCD_DYNAMIC,
- MODEL_EFI_GUID,
- MODEL_EFI_PROTOCOL,
- MODEL_EFI_PPI,
- MODEL_META_DATA_USER_EXTENSION]:
- EdkLogger.error('Parser', FORMAT_INVALID,
- "Section [%s] is not allowed in inf file without version" % (self._SectionName),
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- elif self._SectionType in [MODEL_EFI_INCLUDE,
- MODEL_EFI_LIBRARY_INSTANCE,
- MODEL_META_DATA_NMAKE]:
- EdkLogger.error('Parser', FORMAT_INVALID,
- "Section [%s] is not allowed in inf file with version 0x%08x" % (self._SectionName, self._Version),
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- continue
- # merge two lines specified by '\' in section NMAKE
- elif self._SectionType == MODEL_META_DATA_NMAKE:
- if Line[-1] == '\\':
- if NextLine == '':
- self._CurrentLine = NmakeLine + Line[0:-1]
- NmakeLine = ''
- else:
- if NextLine[0] == TAB_SECTION_START and NextLine[-1] == TAB_SECTION_END:
- self._CurrentLine = NmakeLine + Line[0:-1]
- NmakeLine = ''
- else:
- NmakeLine = NmakeLine + ' ' + Line[0:-1]
- continue
- else:
- self._CurrentLine = NmakeLine + Line
- NmakeLine = ''
-
- # section content
- self._ValueList = ['', '', '']
- # parse current line, result will be put in self._ValueList
- self._SectionParser[self._SectionType](self)
- if self._ValueList is None or self._ItemType == MODEL_META_DATA_DEFINE:
- self._ItemType = -1
- Comments = []
- continue
- if Comment:
- Comments.append((Comment, Index + 1))
- if GlobalData.gOptions and GlobalData.gOptions.CheckUsage:
- CheckInfComment(self._SectionType, Comments, str(self.MetaFile), Index + 1, self._ValueList)
- #
- # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
- # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
- #
- for Arch, Platform, _ in self._Scope:
- LastItem = self._Store(self._SectionType,
- self._ValueList[0],
- self._ValueList[1],
- self._ValueList[2],
- Arch,
- Platform,
- self._Owner[-1],
- self._LineIndex + 1,
- - 1,
- self._LineIndex + 1,
- - 1,
- 0
- )
- for Comment, LineNo in Comments:
- self._Store(MODEL_META_DATA_COMMENT, Comment, '', '', Arch, Platform,
- LastItem, LineNo, -1, LineNo, -1, 0)
- Comments = []
- SectionComments = []
- TailComments.extend(SectionComments + Comments)
- if IsFindBlockComment:
- EdkLogger.error("Parser", FORMAT_INVALID, "Open block comments (starting with /*) are expected to end with */",
- File=self.MetaFile)
-
- # If there are tail comments in INF file, save to database whatever the comments are
- for Comment in TailComments:
- self._Store(MODEL_META_DATA_TAIL_COMMENT, Comment[0], '', '', TAB_COMMON,
- TAB_COMMON, self._Owner[-1], -1, -1, -1, -1, 0)
- self._Done()
-
- ## Data parser for the format in which there's path
- #
- # Only path can have macro used. So we need to replace them before use.
- #
- def _IncludeParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
- self._ValueList[0:len(TokenList)] = TokenList
- Macros = self._Macros
- if Macros:
- for Index in range(0, len(self._ValueList)):
- Value = self._ValueList[Index]
- if not Value:
- continue
- self._ValueList[Index] = ReplaceMacro(Value, Macros)
-
- ## Parse [Sources] section
- #
- # Only path can have macro used. So we need to replace them before use.
- #
- @ParseMacro
- def _SourceFileParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
- # Let TokenList[2] be TagName|ToolCode|FeatureFlag
- if len(TokenList) > 3:
- for extraToken in range(3, len(TokenList)):
- TokenList[2] = TokenList[2] + '|' + TokenList[extraToken]
- self._ValueList[0:len(TokenList)] = TokenList
- Macros = self._Macros
- # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
- if 'COMPONENT_TYPE' in Macros:
- if self._Defines['COMPONENT_TYPE'].upper() == 'ACPITABLE':
- self._ValueList[0] = GetSplitValueList(self._ValueList[0], ' ', 1)[0]
- if self._Defines['BASE_NAME'] == 'Microcode':
- pass
- self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]
-
- ## Parse [Binaries] section
- #
- # Only path can have macro used. So we need to replace them before use.
- #
- @ParseMacro
- def _BinaryFileParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 2)
- if len(TokenList) < 2:
- EdkLogger.error('Parser', FORMAT_INVALID, "No file type or path specified",
- ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
- File=self.MetaFile, Line=self._LineIndex + 1)
- if not TokenList[0]:
- EdkLogger.error('Parser', FORMAT_INVALID, "No file type specified",
- ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
- File=self.MetaFile, Line=self._LineIndex + 1)
- if not TokenList[1]:
- EdkLogger.error('Parser', FORMAT_INVALID, "No file path specified",
- ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
- File=self.MetaFile, Line=self._LineIndex + 1)
- self._ValueList[0:len(TokenList)] = TokenList
- self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)
-
- ## [nmake] section parser (Edk.x style only)
- def _NmakeParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- self._ValueList[0:len(TokenList)] = TokenList
- # remove macros
- self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)
- # remove self-reference in macro setting
- #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
-
- ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
- @ParseMacro
- def _PcdParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
- ValueList = GetSplitValueList(TokenList[0], TAB_SPLIT)
- if len(ValueList) != 2:
- EdkLogger.error('Parser', FORMAT_INVALID, "Illegal token space GUID and PCD name format",
- ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- self._ValueList[0:1] = ValueList
- if len(TokenList) > 1:
- self._ValueList[2] = TokenList[1]
- if self._ValueList[0] == '' or self._ValueList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
- ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
-
- # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
- if self._ValueList[2] != '':
- InfPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
- if InfPcdValueList[0] in ['True', 'true', 'TRUE']:
- self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '1', 1)
- elif InfPcdValueList[0] in ['False', 'false', 'FALSE']:
- self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '0', 1)
- elif isinstance(InfPcdValueList[0], str) and InfPcdValueList[0].find('$(') >= 0:
- Value = ReplaceExprMacro(InfPcdValueList[0],self._Macros)
- if Value != '0':
- self._ValueList[2] = Value
- if (self._ValueList[0], self._ValueList[1]) not in self.PcdsDict:
- self.PcdsDict[self._ValueList[0], self._ValueList[1]] = self._SectionType
- elif self.PcdsDict[self._ValueList[0], self._ValueList[1]] != self._SectionType:
- EdkLogger.error('Parser', FORMAT_INVALID, "It is not permissible to list a specified PCD in different PCD type sections.",
- ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
-
- ## [depex] section parser
- @ParseMacro
- def _DepexParser(self):
- self._ValueList[0:1] = [self._CurrentLine]
-
- _SectionParser = {
- MODEL_UNKNOWN : MetaFileParser._Skip,
- MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,
- MODEL_META_DATA_BUILD_OPTION : MetaFileParser._BuildOptionParser,
- MODEL_EFI_INCLUDE : _IncludeParser, # for Edk.x modules
- MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._CommonParser, # for Edk.x modules
- MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,
- MODEL_META_DATA_PACKAGE : MetaFileParser._PathParser,
- MODEL_META_DATA_NMAKE : _NmakeParser, # for Edk.x modules
- MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
- MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
- MODEL_PCD_FEATURE_FLAG : _PcdParser,
- MODEL_PCD_DYNAMIC_EX : _PcdParser,
- MODEL_PCD_DYNAMIC : _PcdParser,
- MODEL_EFI_SOURCE_FILE : _SourceFileParser,
- MODEL_EFI_GUID : MetaFileParser._CommonParser,
- MODEL_EFI_PROTOCOL : MetaFileParser._CommonParser,
- MODEL_EFI_PPI : MetaFileParser._CommonParser,
- MODEL_EFI_DEPEX : _DepexParser,
- MODEL_EFI_BINARY_FILE : _BinaryFileParser,
- MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
- }
-
-## DSC file parser class
-#
-# @param FilePath The path of platform description file
-# @param FileType The raw data of DSC file
-# @param Table Database used to retrieve module/package information
-# @param Macros Macros used for replacement in file
-# @param Owner Owner ID (for sub-section parsing)
-# @param From ID from which the data comes (for !INCLUDE directive)
-#
-class DscParser(MetaFileParser):
- # DSC file supported data types (one type per section)
- DataType = {
- TAB_SKUIDS.upper() : MODEL_EFI_SKU_ID,
- TAB_DEFAULT_STORES.upper() : MODEL_EFI_DEFAULT_STORES,
- TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
- TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
- TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
- TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,
- TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
- TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
- TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
- TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_DEFAULT,
- TAB_PCDS_DYNAMIC_HII_NULL.upper() : MODEL_PCD_DYNAMIC_HII,
- TAB_PCDS_DYNAMIC_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_VPD,
- TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT,
- TAB_PCDS_DYNAMIC_EX_HII_NULL.upper() : MODEL_PCD_DYNAMIC_EX_HII,
- TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_EX_VPD,
- TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,
- TAB_DSC_DEFINES.upper() : MODEL_META_DATA_HEADER,
- TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
- TAB_DSC_DEFINES_EDKGLOBAL : MODEL_META_DATA_GLOBAL_DEFINE,
- TAB_INCLUDE.upper() : MODEL_META_DATA_INCLUDE,
- TAB_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
- TAB_IF_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
- TAB_IF_N_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,
- TAB_ELSE_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,
- TAB_ELSE.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,
- TAB_END_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,
- TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION,
- TAB_ERROR.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR,
- }
-
- # Valid names in define section
- DefineKeywords = [
- "DSC_SPECIFICATION",
- "PLATFORM_NAME",
- "PLATFORM_GUID",
- "PLATFORM_VERSION",
- "SKUID_IDENTIFIER",
- "PCD_INFO_GENERATION",
- "PCD_VAR_CHECK_GENERATION",
- "SUPPORTED_ARCHITECTURES",
- "BUILD_TARGETS",
- "OUTPUT_DIRECTORY",
- "FLASH_DEFINITION",
- "BUILD_NUMBER",
- "RFC_LANGUAGES",
- "ISO_LANGUAGES",
- "TIME_STAMP_FILE",
- "VPD_TOOL_GUID",
- "FIX_LOAD_TOP_MEMORY_ADDRESS",
- "PREBUILD",
- "POSTBUILD"
- ]
-
- SubSectionDefineKeywords = [
- "FILE_GUID"
- ]
-
- SymbolPattern = ValueExpression.SymbolPattern
-
- IncludedFiles = set()
-
- ## Constructor of DscParser
- #
- # Initialize object of DscParser
- #
- # @param FilePath The path of platform description file
- # @param FileType The raw data of DSC file
- # @param Arch Default Arch value for filtering sections
- # @param Table Database used to retrieve module/package information
- # @param Owner Owner ID (for sub-section parsing)
- # @param From ID from which the data comes (for !INCLUDE directive)
- #
- def __init__(self, FilePath, FileType, Arch, Table, Owner= -1, From= -1):
- # prevent re-initialization
- if hasattr(self, "_Table") and self._Table is Table:
- return
- MetaFileParser.__init__(self, FilePath, FileType, Arch, Table, Owner, From)
- self._Version = 0x00010005 # Only EDK2 dsc file is supported
- # to store conditional directive evaluation result
- self._DirectiveStack = []
- self._DirectiveEvalStack = []
- self._Enabled = 1
-
- #
- # Specify whether current line is in uncertain condition
- #
- self._InDirective = -1
-
- # Final valid replacable symbols
- self._Symbols = {}
- #
- # Map the ID between the original table and new table to track
- # the owner item
- #
- self._IdMapping = {-1:-1}
-
- self._Content = None
-
- ## Parser starter
- def Start(self):
- Content = ''
- try:
- with open(str(self.MetaFile), 'r') as File:
- Content = File.readlines()
- except:
- EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
-
- OwnerId = {}
-
- Content = self.ProcessMultipleLineCODEValue(Content)
-
- for Index in range(0, len(Content)):
- Line = CleanString(Content[Index])
- # skip empty line
- if Line == '':
- continue
-
- self._CurrentLine = Line
- self._LineIndex = Index
- if self._InSubsection and self._Owner[-1] == -1:
- self._Owner.append(self._LastItem)
-
- # section header
- if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
- self._SectionType = MODEL_META_DATA_SECTION_HEADER
- # subsection ending
- elif Line[0] == '}' and self._InSubsection:
- self._InSubsection = False
- self._SubsectionType = MODEL_UNKNOWN
- self._SubsectionName = ''
- self._Owner[-1] = -1
- OwnerId.clear()
- continue
- # subsection header
- elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:
- self._SubsectionType = MODEL_META_DATA_SUBSECTION_HEADER
- # directive line
- elif Line[0] == '!':
- TokenList = GetSplitValueList(Line, ' ', 1)
- if TokenList[0] == TAB_INCLUDE:
- for Arch, ModuleType, DefaultStore in self._Scope:
- if self._SubsectionType != MODEL_UNKNOWN and Arch in OwnerId:
- self._Owner[-1] = OwnerId[Arch]
- self._DirectiveParser()
- else:
- self._DirectiveParser()
- continue
- if Line[0] == TAB_OPTION_START and not self._InSubsection:
- EdkLogger.error("Parser", FILE_READ_FAILURE, "Missing the '{' before %s in Line %s" % (Line, Index+1), ExtraData=self.MetaFile)
-
- if self._InSubsection:
- SectionType = self._SubsectionType
- else:
- SectionType = self._SectionType
- self._ItemType = SectionType
-
- self._ValueList = ['', '', '']
- # "SET pcd = pcd_expression" syntax is not supported in Dsc file.
- if self._CurrentLine.upper().strip().startswith("SET "):
- EdkLogger.error('Parser', FORMAT_INVALID, '''"SET pcd = pcd_expression" syntax is not support in Dsc file''',
- ExtraData=self._CurrentLine,
- File=self.MetaFile, Line=self._LineIndex + 1)
- self._SectionParser[SectionType](self)
- if self._ValueList is None:
- continue
- #
- # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
- # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
- #
- for Arch, ModuleType, DefaultStore in self._Scope:
- Owner = self._Owner[-1]
- if self._SubsectionType != MODEL_UNKNOWN and Arch in OwnerId:
- Owner = OwnerId[Arch]
- self._LastItem = self._Store(
- self._ItemType,
- self._ValueList[0],
- self._ValueList[1],
- self._ValueList[2],
- Arch,
- ModuleType,
- DefaultStore,
- Owner,
- self._From,
- self._LineIndex + 1,
- - 1,
- self._LineIndex + 1,
- - 1,
- self._Enabled
- )
- if self._SubsectionType == MODEL_UNKNOWN and self._InSubsection:
- OwnerId[Arch] = self._LastItem
-
- if self._DirectiveStack:
- Type, Line, Text = self._DirectiveStack[-1]
- EdkLogger.error('Parser', FORMAT_INVALID, "No matching '!endif' found",
- ExtraData=Text, File=self.MetaFile, Line=Line)
- self._Done()
-
- ## <subsection_header> parser
- def _SubsectionHeaderParser(self):
- self._SubsectionName = self._CurrentLine[1:-1].upper()
- if self._SubsectionName in self.DataType:
- self._SubsectionType = self.DataType[self._SubsectionName]
- else:
- self._SubsectionType = MODEL_UNKNOWN
- EdkLogger.warn("Parser", "Unrecognized sub-section", File=self.MetaFile,
- Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
- self._ValueList[0] = self._SubsectionName
-
- ## Directive statement parser
- def _DirectiveParser(self):
- self._ValueList = ['', '', '']
- TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)
- self._ValueList[0:len(TokenList)] = TokenList
-
- # Syntax check
- DirectiveName = self._ValueList[0].upper()
- if DirectiveName not in self.DataType:
- EdkLogger.error("Parser", FORMAT_INVALID, "Unknown directive [%s]" % DirectiveName,
- File=self.MetaFile, Line=self._LineIndex + 1)
-
- if DirectiveName in ['!IF', '!IFDEF', '!IFNDEF']:
- self._InDirective += 1
-
- if DirectiveName in ['!ENDIF']:
- self._InDirective -= 1
-
- if DirectiveName in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self._ValueList[1] == '':
- EdkLogger.error("Parser", FORMAT_INVALID, "Missing expression",
- File=self.MetaFile, Line=self._LineIndex + 1,
- ExtraData=self._CurrentLine)
-
- ItemType = self.DataType[DirectiveName]
- Scope = [[TAB_COMMON, TAB_COMMON, TAB_COMMON]]
- if ItemType == MODEL_META_DATA_INCLUDE:
- Scope = self._Scope
- elif ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR:
- Scope = self._Scope
- if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
- # Remove all directives between !if and !endif, including themselves
- while self._DirectiveStack:
- # Remove any !else or !elseif
- DirectiveInfo = self._DirectiveStack.pop()
- if DirectiveInfo[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
- break
- else:
- EdkLogger.error("Parser", FORMAT_INVALID, "Redundant '!endif'",
- File=self.MetaFile, Line=self._LineIndex + 1,
- ExtraData=self._CurrentLine)
- elif ItemType not in {MODEL_META_DATA_INCLUDE, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR}:
- # Break if there's a !else is followed by a !elseif
- if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF and \
- self._DirectiveStack and \
- self._DirectiveStack[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
- EdkLogger.error("Parser", FORMAT_INVALID, "'!elseif' after '!else'",
- File=self.MetaFile, Line=self._LineIndex + 1,
- ExtraData=self._CurrentLine)
- self._DirectiveStack.append((ItemType, self._LineIndex + 1, self._CurrentLine))
-
- #
- # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
- # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
- #
- for Arch, ModuleType, DefaultStore in Scope:
- self._LastItem = self._Store(
- ItemType,
- self._ValueList[0],
- self._ValueList[1],
- self._ValueList[2],
- Arch,
- ModuleType,
- DefaultStore,
- self._Owner[-1],
- self._From,
- self._LineIndex + 1,
- - 1,
- self._LineIndex + 1,
- - 1,
- 0
- )
-
- ## [defines] section parser
- @ParseMacro
- def _DefineParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- self._ValueList[1:len(TokenList)] = TokenList
-
- # Syntax check
- if not self._ValueList[1]:
- EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- if not self._ValueList[2]:
- EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- if (not self._ValueList[1] in self.DefineKeywords and
- (self._InSubsection and self._ValueList[1] not in self.SubSectionDefineKeywords)):
- EdkLogger.error('Parser', FORMAT_INVALID,
- "Unknown keyword found: %s. "
- "If this is a macro you must "
- "add it as a DEFINE in the DSC" % self._ValueList[1],
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- if not self._InSubsection:
- self._Defines[self._ValueList[1]] = self._ValueList[2]
- self._ItemType = self.DataType[TAB_DSC_DEFINES.upper()]
-
- @ParseMacro
- def _SkuIdParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
- if len(TokenList) not in (2, 3):
- EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Number>|<UiName>[|<UiName>]'",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- self._ValueList[0:len(TokenList)] = TokenList
- @ParseMacro
- def _DefaultStoresParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
- if len(TokenList) != 2:
- EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Number>|<UiName>'",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- self._ValueList[0:len(TokenList)] = TokenList
-
- ## Parse Edk style of library modules
- @ParseMacro
- def _LibraryInstanceParser(self):
- self._ValueList[0] = self._CurrentLine
-
-
- def _DecodeCODEData(self):
- pass
- ## PCD sections parser
- #
- # [PcdsFixedAtBuild]
- # [PcdsPatchableInModule]
- # [PcdsFeatureFlag]
- # [PcdsDynamicEx
- # [PcdsDynamicExDefault]
- # [PcdsDynamicExVpd]
- # [PcdsDynamicExHii]
- # [PcdsDynamic]
- # [PcdsDynamicDefault]
- # [PcdsDynamicVpd]
- # [PcdsDynamicHii]
- #
- @ParseMacro
- def _PcdParser(self):
- if self._PcdDataTypeCODE:
- self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine
- if self._CurrentLine.endswith(")}"):
- self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue))
- self._PcdDataTypeCODE = False
- self._PcdCodeValue = ""
- else:
- self._ValueList = None
- return
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
- self._CurrentPcdName = TokenList[0]
- if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"):
- self._PcdDataTypeCODE = True
- self._PcdCodeValue = TokenList[1].strip()
-
- if self._PcdDataTypeCODE:
- if self._CurrentLine.endswith(")}"):
- self._PcdDataTypeCODE = False
- self._PcdCodeValue = ""
- else:
- self._ValueList = None
- return
- self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
- PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)
- if len(PcdNameTockens) == 2:
- self._ValueList[0], self._ValueList[1] = PcdNameTockens[0], PcdNameTockens[1]
- elif len(PcdNameTockens) == 3:
- self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), PcdNameTockens[2]
- elif len(PcdNameTockens) > 3:
- self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), ".".join(PcdNameTockens[2:])
- if len(TokenList) == 2:
- self._ValueList[2] = TokenList[1]
- if self._ValueList[0] == '' or self._ValueList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
- ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- if self._ValueList[2] == '':
- #
- # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
- #
- if self._SectionType in (MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):
- return
- EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given",
- ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
-
- # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
- ValueList = GetSplitValueList(self._ValueList[2])
- if len(ValueList) > 1 and ValueList[1] in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64] \
- and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]:
- EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1],
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
-
- # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
- if self._ItemType in [MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII]:
- DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
- if len(DscPcdValueList[0].replace('L', '').replace('"', '').strip()) == 0:
- EdkLogger.error('Parser', FORMAT_INVALID, "The VariableName field in the HII format PCD entry must not be an empty string",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
-
- # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
- DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
- if DscPcdValueList[0] in ['True', 'true', 'TRUE']:
- self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1);
- elif DscPcdValueList[0] in ['False', 'false', 'FALSE']:
- self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1);
-
-
- ## [components] section parser
- @ParseMacro
- def _ComponentParser(self):
- if self._CurrentLine[-1] == '{':
- self._ValueList[0] = self._CurrentLine[0:-1].strip()
- self._InSubsection = True
- self._SubsectionType = MODEL_UNKNOWN
- else:
- self._ValueList[0] = self._CurrentLine
-
- ## [LibraryClasses] section
- @ParseMacro
- def _LibraryClassParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
- if len(TokenList) < 2:
- EdkLogger.error('Parser', FORMAT_INVALID, "No library class or instance specified",
- ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- if TokenList[0] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No library class specified",
- ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- if TokenList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No library instance specified",
- ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
-
- self._ValueList[0:len(TokenList)] = TokenList
-
-
- ## [BuildOptions] section parser
- @ParseMacro
- def _BuildOptionParser(self):
- self._CurrentLine = CleanString(self._CurrentLine, BuildOption=True)
- TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
- if len(TokenList2) == 2:
- self._ValueList[0] = TokenList2[0] # toolchain family
- self._ValueList[1] = TokenList2[1] # keys
- else:
- self._ValueList[1] = TokenList[0]
- if len(TokenList) == 2: # value
- self._ValueList[2] = TokenList[1]
-
- if self._ValueList[1].count('_') != 4:
- EdkLogger.error(
- 'Parser',
- FORMAT_INVALID,
- "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],
- ExtraData=self._CurrentLine,
- File=self.MetaFile,
- Line=self._LineIndex + 1
- )
-
- ## Override parent's method since we'll do all macro replacements in parser
- @property
- def _Macros(self):
- Macros = {}
- Macros.update(self._FileLocalMacros)
- Macros.update(self._GetApplicableSectionMacro())
- Macros.update(GlobalData.gEdkGlobal)
- Macros.update(GlobalData.gPlatformDefines)
- Macros.update(GlobalData.gCommandLineDefines)
- # PCD cannot be referenced in macro definition
- if self._ItemType not in [MODEL_META_DATA_DEFINE, MODEL_META_DATA_GLOBAL_DEFINE]:
- Macros.update(self._Symbols)
- if GlobalData.BuildOptionPcd:
- for Item in GlobalData.BuildOptionPcd:
- if isinstance(Item, tuple):
- continue
- PcdName, TmpValue = Item.split("=")
- TmpValue = BuildOptionValue(TmpValue, self._GuidDict)
- Macros[PcdName.strip()] = TmpValue
- return Macros
-
- def _PostProcess(self):
- Processer = {
- MODEL_META_DATA_SECTION_HEADER : self.__ProcessSectionHeader,
- MODEL_META_DATA_SUBSECTION_HEADER : self.__ProcessSubsectionHeader,
- MODEL_META_DATA_HEADER : self.__ProcessDefine,
- MODEL_META_DATA_DEFINE : self.__ProcessDefine,
- MODEL_META_DATA_GLOBAL_DEFINE : self.__ProcessDefine,
- MODEL_META_DATA_INCLUDE : self.__ProcessDirective,
- MODEL_META_DATA_PACKAGE : self.__ProcessPackages,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IF : self.__ProcessDirective,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE : self.__ProcessDirective,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF : self.__ProcessDirective,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF : self.__ProcessDirective,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF : self.__ProcessDirective,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF : self.__ProcessDirective,
- MODEL_EFI_SKU_ID : self.__ProcessSkuId,
- MODEL_EFI_DEFAULT_STORES : self.__ProcessDefaultStores,
- MODEL_EFI_LIBRARY_INSTANCE : self.__ProcessLibraryInstance,
- MODEL_EFI_LIBRARY_CLASS : self.__ProcessLibraryClass,
- MODEL_PCD_FIXED_AT_BUILD : self.__ProcessPcd,
- MODEL_PCD_PATCHABLE_IN_MODULE : self.__ProcessPcd,
- MODEL_PCD_FEATURE_FLAG : self.__ProcessPcd,
- MODEL_PCD_DYNAMIC_DEFAULT : self.__ProcessPcd,
- MODEL_PCD_DYNAMIC_HII : self.__ProcessPcd,
- MODEL_PCD_DYNAMIC_VPD : self.__ProcessPcd,
- MODEL_PCD_DYNAMIC_EX_DEFAULT : self.__ProcessPcd,
- MODEL_PCD_DYNAMIC_EX_HII : self.__ProcessPcd,
- MODEL_PCD_DYNAMIC_EX_VPD : self.__ProcessPcd,
- MODEL_META_DATA_COMPONENT : self.__ProcessComponent,
- MODEL_META_DATA_BUILD_OPTION : self.__ProcessBuildOption,
- MODEL_UNKNOWN : self._Skip,
- MODEL_META_DATA_USER_EXTENSION : self._SkipUserExtension,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR : self._ProcessError,
- }
-
- self._Table = MetaFileStorage(self._RawTable.DB, self.MetaFile, MODEL_FILE_DSC, True)
- self._DirectiveStack = []
- self._DirectiveEvalStack = []
- self._FileWithError = self.MetaFile
- self._FileLocalMacros = {}
- self._SectionsMacroDict.clear()
- GlobalData.gPlatformDefines = {}
-
- # Get all macro and PCD which has straitforward value
- self.__RetrievePcdValue()
- self._Content = self._RawTable.GetAll()
- self._ContentIndex = 0
- self._InSubsection = False
- while self._ContentIndex < len(self._Content) :
- Id, self._ItemType, V1, V2, V3, S1, S2, S3, Owner, self._From, \
- LineStart, ColStart, LineEnd, ColEnd, Enabled = self._Content[self._ContentIndex]
-
- if self._From < 0:
- self._FileWithError = self.MetaFile
-
- self._ContentIndex += 1
-
- self._Scope = [[S1, S2, S3]]
- #
- # For !include directive, handle it specially,
- # merge arch and module type in case of duplicate items
- #
- while self._ItemType == MODEL_META_DATA_INCLUDE:
- if self._ContentIndex >= len(self._Content):
- break
- Record = self._Content[self._ContentIndex]
- if LineStart == Record[10] and LineEnd == Record[12]:
- if [Record[5], Record[6], Record[7]] not in self._Scope:
- self._Scope.append([Record[5], Record[6], Record[7]])
- self._ContentIndex += 1
- else:
- break
-
- self._LineIndex = LineStart - 1
- self._ValueList = [V1, V2, V3]
-
- if Owner > 0 and Owner in self._IdMapping:
- self._InSubsection = True
- else:
- self._InSubsection = False
- try:
- Processer[self._ItemType]()
- except EvaluationException as Excpt:
- #
- # Only catch expression evaluation error here. We need to report
- # the precise number of line on which the error occurred
- #
- if hasattr(Excpt, 'Pcd'):
- if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
- Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]
- EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
- " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
- " of the DSC file, and it is currently defined in this section:"
- " %s, line #: %d." % (Excpt.Pcd, Info[0], Info[1]),
- File=self._FileWithError, ExtraData=' '.join(self._ValueList),
- Line=self._LineIndex + 1)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
- File=self._FileWithError, ExtraData=' '.join(self._ValueList),
- Line=self._LineIndex + 1)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
- File=self._FileWithError, ExtraData=' '.join(self._ValueList),
- Line=self._LineIndex + 1)
- except MacroException as Excpt:
- EdkLogger.error('Parser', FORMAT_INVALID, str(Excpt),
- File=self._FileWithError, ExtraData=' '.join(self._ValueList),
- Line=self._LineIndex + 1)
-
- if self._ValueList is None:
- continue
-
- NewOwner = self._IdMapping.get(Owner, -1)
- self._Enabled = int((not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack))
- self._LastItem = self._Store(
- self._ItemType,
- self._ValueList[0],
- self._ValueList[1],
- self._ValueList[2],
- S1,
- S2,
- S3,
- NewOwner,
- self._From,
- self._LineIndex + 1,
- - 1,
- self._LineIndex + 1,
- - 1,
- self._Enabled
- )
- self._IdMapping[Id] = self._LastItem
-
- GlobalData.gPlatformDefines.update(self._FileLocalMacros)
- self._PostProcessed = True
- self._Content = None
- def _ProcessError(self):
- if not self._Enabled:
- return
- EdkLogger.error('Parser', ERROR_STATEMENT, self._ValueList[1], File=self.MetaFile, Line=self._LineIndex + 1)
-
- def __ProcessSectionHeader(self):
- self._SectionName = self._ValueList[0]
- if self._SectionName in self.DataType:
- self._SectionType = self.DataType[self._SectionName]
- else:
- self._SectionType = MODEL_UNKNOWN
-
- def __ProcessSubsectionHeader(self):
- self._SubsectionName = self._ValueList[0]
- if self._SubsectionName in self.DataType:
- self._SubsectionType = self.DataType[self._SubsectionName]
- else:
- self._SubsectionType = MODEL_UNKNOWN
-
- def __RetrievePcdValue(self):
- try:
- with open(str(self.MetaFile), 'r') as File:
- Content = File.readlines()
- except:
- EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
-
- GlobalData.gPlatformOtherPcds['DSCFILE'] = str(self.MetaFile)
- for PcdType in (MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_HII,
- MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_DYNAMIC_EX_HII,
- MODEL_PCD_DYNAMIC_EX_VPD):
- Records = self._RawTable.Query(PcdType, BelongsToItem= -1.0)
- for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, Dummy4, ID, Line in Records:
- Name = TokenSpaceGuid + '.' + PcdName
- if Name not in GlobalData.gPlatformOtherPcds:
- PcdLine = Line
- while not Content[Line - 1].lstrip().startswith(TAB_SECTION_START):
- Line -= 1
- GlobalData.gPlatformOtherPcds[Name] = (CleanString(Content[Line - 1]), PcdLine, PcdType)
-
- def __ProcessDefine(self):
- if not self._Enabled:
- return
-
- Type, Name, Value = self._ValueList
- Value = ReplaceMacro(Value, self._Macros, False)
- #
- # If it is <Defines>, return
- #
- if self._InSubsection:
- self._ValueList = [Type, Name, Value]
- return
-
- if self._ItemType == MODEL_META_DATA_DEFINE:
- if self._SectionType == MODEL_META_DATA_HEADER:
- self._FileLocalMacros[Name] = Value
- else:
- self._ConstructSectionMacroDict(Name, Value)
- elif self._ItemType == MODEL_META_DATA_GLOBAL_DEFINE:
- GlobalData.gEdkGlobal[Name] = Value
-
- #
- # Keyword in [Defines] section can be used as Macros
- #
- if (self._ItemType == MODEL_META_DATA_HEADER) and (self._SectionType == MODEL_META_DATA_HEADER):
- self._FileLocalMacros[Name] = Value
-
- self._ValueList = [Type, Name, Value]
-
- def __ProcessDirective(self):
- Result = None
- if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF]:
- Macros = self._Macros
- Macros.update(GlobalData.gGlobalDefines)
- try:
- Result = ValueExpression(self._ValueList[1], Macros)()
- except SymbolNotFound as Exc:
- EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc), self._ValueList[1])
- Result = False
- except WrnExpression as Excpt:
- #
- # Catch expression evaluation warning here. We need to report
- # the precise number of line and return the evaluation result
- #
- EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
- File=self._FileWithError, ExtraData=' '.join(self._ValueList),
- Line=self._LineIndex + 1)
- Result = Excpt.result
-
- if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
- self._DirectiveStack.append(self._ItemType)
- if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IF:
- Result = bool(Result)
- else:
- Macro = self._ValueList[1]
- Macro = Macro[2:-1] if (Macro.startswith("$(") and Macro.endswith(")")) else Macro
- Result = Macro in self._Macros
- if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF:
- Result = not Result
- self._DirectiveEvalStack.append(Result)
- elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF:
- self._DirectiveStack.append(self._ItemType)
- self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]
- self._DirectiveEvalStack.append(bool(Result))
- elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
- self._DirectiveStack.append(self._ItemType)
- self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]
- self._DirectiveEvalStack.append(True)
- elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
- # Back to the nearest !if/!ifdef/!ifndef
- while self._DirectiveStack:
- self._DirectiveEvalStack.pop()
- Directive = self._DirectiveStack.pop()
- if Directive in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
- MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
- break
- elif self._ItemType == MODEL_META_DATA_INCLUDE:
- # The included file must be relative to workspace or same directory as DSC file
- __IncludeMacros = {}
- #
- # Allow using system environment variables in path after !include
- #
- __IncludeMacros['WORKSPACE'] = GlobalData.gGlobalDefines['WORKSPACE']
- #
- # Allow using MACROs comes from [Defines] section to keep compatible.
- #
- __IncludeMacros.update(self._Macros)
-
- IncludedFile = NormPath(ReplaceMacro(self._ValueList[1], __IncludeMacros, RaiseError=True))
- #
- # First search the include file under the same directory as DSC file
- #
- IncludedFile1 = PathClass(IncludedFile, self.MetaFile.Dir)
- if self._Enabled:
- ErrorCode, ErrorInfo1 = IncludedFile1.Validate()
- if ErrorCode != 0:
- #
- # Also search file under the WORKSPACE directory
- #
- IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)
- ErrorCode, ErrorInfo2 = IncludedFile1.Validate()
- if ErrorCode != 0:
- EdkLogger.error('parser', ErrorCode, File=self._FileWithError,
- Line=self._LineIndex + 1, ExtraData=ErrorInfo1 + "\n" + ErrorInfo2)
-
- self._FileWithError = IncludedFile1
-
- FromItem = self._Content[self._ContentIndex - 1][0]
- if self._InSubsection:
- Owner = self._Content[self._ContentIndex - 1][8]
- else:
- Owner = self._Content[self._ContentIndex - 1][0]
- IncludedFileTable = MetaFileStorage(self._RawTable.DB, IncludedFile1, MODEL_FILE_DSC, False, FromItem=FromItem)
- Parser = DscParser(IncludedFile1, self._FileType, self._Arch, IncludedFileTable,
- Owner=Owner, From=FromItem)
-
- self.IncludedFiles.add (IncludedFile1)
-
- # set the parser status with current status
- Parser._SectionName = self._SectionName
- Parser._SubsectionType = self._SubsectionType
- Parser._InSubsection = self._InSubsection
- Parser._SectionType = self._SectionType
- Parser._Scope = self._Scope
- Parser._Enabled = self._Enabled
- # Parse the included file
- Parser.StartParse()
- # Insert all records in the table for the included file into dsc file table
- Records = IncludedFileTable.GetAll()
- if Records:
- self._Content[self._ContentIndex:self._ContentIndex] = Records
- self._Content.pop(self._ContentIndex - 1)
- self._ValueList = None
- self._ContentIndex -= 1
-
- def __ProcessPackages(self):
- self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
-
- def __ProcessSkuId(self):
- self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)
- for Value in self._ValueList]
- def __ProcessDefaultStores(self):
- self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)
- for Value in self._ValueList]
-
- def __ProcessLibraryInstance(self):
- self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]
-
- def __ProcessLibraryClass(self):
- self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros, RaiseError=True)
-
- def __ProcessPcd(self):
- if self._ItemType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
- self._ValueList[2] = ReplaceMacro(self._ValueList[2], self._Macros, RaiseError=True)
- return
-
- ValList, Valid, Index = AnalyzeDscPcd(self._ValueList[2], self._ItemType)
- if not Valid:
- if self._ItemType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):
- if ValList[1] != TAB_VOID and StructPattern.match(ValList[1]) is None and ValList[2]:
- EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect. The datum type info should be VOID* or a valid struct name.", File=self._FileWithError,
- Line=self._LineIndex + 1, ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))
- EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex + 1,
- ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))
- PcdValue = ValList[Index]
- if PcdValue and "." not in self._ValueList[0]:
- try:
- ValList[Index] = ValueExpression(PcdValue, self._Macros)(True)
- except WrnExpression as Value:
- ValList[Index] = Value.result
- except:
- pass
-
- if ValList[Index] == 'True':
- ValList[Index] = '1'
- if ValList[Index] == 'False':
- ValList[Index] = '0'
-
- if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):
- GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue
- self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue
- try:
- self._ValueList[2] = '|'.join(ValList)
- except Exception:
- print(ValList)
-
- def __ProcessComponent(self):
- self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
-
- def __ProcessBuildOption(self):
- self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=False)
- for Value in self._ValueList]
-
- def DisableOverrideComponent(self,module_id):
- for ori_id in self._IdMapping:
- if self._IdMapping[ori_id] == module_id:
- self._RawTable.DisableComponent(ori_id)
-
- _SectionParser = {
- MODEL_META_DATA_HEADER : _DefineParser,
- MODEL_EFI_SKU_ID : _SkuIdParser,
- MODEL_EFI_DEFAULT_STORES : _DefaultStoresParser,
- MODEL_EFI_LIBRARY_INSTANCE : _LibraryInstanceParser,
- MODEL_EFI_LIBRARY_CLASS : _LibraryClassParser,
- MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
- MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
- MODEL_PCD_FEATURE_FLAG : _PcdParser,
- MODEL_PCD_DYNAMIC_DEFAULT : _PcdParser,
- MODEL_PCD_DYNAMIC_HII : _PcdParser,
- MODEL_PCD_DYNAMIC_VPD : _PcdParser,
- MODEL_PCD_DYNAMIC_EX_DEFAULT : _PcdParser,
- MODEL_PCD_DYNAMIC_EX_HII : _PcdParser,
- MODEL_PCD_DYNAMIC_EX_VPD : _PcdParser,
- MODEL_META_DATA_COMPONENT : _ComponentParser,
- MODEL_META_DATA_BUILD_OPTION : _BuildOptionParser,
- MODEL_UNKNOWN : MetaFileParser._Skip,
- MODEL_META_DATA_PACKAGE : MetaFileParser._PackageParser,
- MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
- MODEL_META_DATA_SECTION_HEADER : MetaFileParser._SectionHeaderParser,
- MODEL_META_DATA_SUBSECTION_HEADER : _SubsectionHeaderParser,
- }
-
-## DEC file parser class
-#
-# @param FilePath The path of platform description file
-# @param FileType The raw data of DSC file
-# @param Table Database used to retrieve module/package information
-# @param Macros Macros used for replacement in file
-#
-class DecParser(MetaFileParser):
- # DEC file supported data types (one type per section)
- DataType = {
- TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER,
- TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
- TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
- TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
- TAB_GUIDS.upper() : MODEL_EFI_GUID,
- TAB_PPIS.upper() : MODEL_EFI_PPI,
- TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
- TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
- TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
- TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
- TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC,
- TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX,
- TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION,
- }
-
- ## Constructor of DecParser
- #
- # Initialize object of DecParser
- #
- # @param FilePath The path of platform description file
- # @param FileType The raw data of DSC file
- # @param Arch Default Arch value for filtering sections
- # @param Table Database used to retrieve module/package information
- #
- def __init__(self, FilePath, FileType, Arch, Table):
- # prevent re-initialization
- if hasattr(self, "_Table"):
- return
- MetaFileParser.__init__(self, FilePath, FileType, Arch, Table, -1)
- self._Comments = []
- self._Version = 0x00010005 # Only EDK2 dec file is supported
- self._AllPCDs = [] # Only for check duplicate PCD
- self._AllPcdDict = {}
-
- self._CurrentStructurePcdName = ""
- self._include_flag = False
- self._package_flag = False
-
- self._RestofValue = ""
-
- ## Parser starter
- def Start(self):
- Content = ''
- try:
- with open(str(self.MetaFile), 'r') as File:
- Content = File.readlines()
- except:
- EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
-
- Content = self.ProcessMultipleLineCODEValue(Content)
-
- self._DefinesCount = 0
- for Index in range(0, len(Content)):
- Line, Comment = CleanString2(Content[Index])
- self._CurrentLine = Line
- self._LineIndex = Index
-
- # save comment for later use
- if Comment:
- self._Comments.append((Comment, self._LineIndex + 1))
- # skip empty line
- if Line == '':
- continue
-
- # section header
- if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
- self._SectionHeaderParser()
- if self._SectionName == TAB_DEC_DEFINES.upper():
- self._DefinesCount += 1
- self._Comments = []
- continue
- if self._SectionType == MODEL_UNKNOWN:
- EdkLogger.error("Parser", FORMAT_INVALID,
- ""
- "Not able to determine \"%s\" in which section."%self._CurrentLine,
- self.MetaFile, self._LineIndex + 1)
- elif len(self._SectionType) == 0:
- self._Comments = []
- continue
-
- # section content
- self._ValueList = ['', '', '']
- self._SectionParser[self._SectionType[0]](self)
- if self._ValueList is None or self._ItemType == MODEL_META_DATA_DEFINE:
- self._ItemType = -1
- self._Comments = []
- continue
-
- #
- # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
- # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
- #
- for Arch, ModuleType, Type in self._Scope:
- self._LastItem = self._Store(
- Type,
- self._ValueList[0],
- self._ValueList[1],
- self._ValueList[2],
- Arch,
- ModuleType,
- self._Owner[-1],
- self._LineIndex + 1,
- - 1,
- self._LineIndex + 1,
- - 1,
- 0
- )
- for Comment, LineNo in self._Comments:
- self._Store(
- MODEL_META_DATA_COMMENT,
- Comment,
- self._ValueList[0],
- self._ValueList[1],
- Arch,
- ModuleType,
- self._LastItem,
- LineNo,
- - 1,
- LineNo,
- - 1,
- 0
- )
- self._Comments = []
- if self._DefinesCount > 1:
- EdkLogger.error('Parser', FORMAT_INVALID, 'Multiple [Defines] section is exist.', self.MetaFile )
- if self._DefinesCount == 0:
- EdkLogger.error('Parser', FORMAT_INVALID, 'No [Defines] section exist.', self.MetaFile)
- self._Done()
-
-
- ## Section header parser
- #
- # The section header is always in following format:
- #
- # [section_name.arch<.platform|module_type>]
- #
- def _SectionHeaderParser(self):
- self._Scope = []
- self._SectionName = ''
- self._SectionType = []
- ArchList = set()
- PrivateList = set()
- Line = re.sub(r',[\s]*', TAB_COMMA_SPLIT, self._CurrentLine)
- for Item in Line[1:-1].split(TAB_COMMA_SPLIT):
- if Item == '':
- EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR,
- "section name can NOT be empty or incorrectly use separator comma",
- self.MetaFile, self._LineIndex + 1, self._CurrentLine)
- ItemList = Item.split(TAB_SPLIT)
-
- # different types of PCD are permissible in one section
- self._SectionName = ItemList[0].upper()
- if self._SectionName == TAB_DEC_DEFINES.upper() and (len(ItemList) > 1 or len(Line.split(TAB_COMMA_SPLIT)) > 1):
- EdkLogger.error("Parser", FORMAT_INVALID, "Defines section format is invalid",
- self.MetaFile, self._LineIndex + 1, self._CurrentLine)
- if self._SectionName in self.DataType:
- if self.DataType[self._SectionName] not in self._SectionType:
- self._SectionType.append(self.DataType[self._SectionName])
- else:
- EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
- self.MetaFile, self._LineIndex + 1, self._CurrentLine)
-
- if MODEL_PCD_FEATURE_FLAG in self._SectionType and len(self._SectionType) > 1:
- EdkLogger.error(
- 'Parser',
- FORMAT_INVALID,
- "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL,
- File=self.MetaFile,
- Line=self._LineIndex + 1,
- ExtraData=self._CurrentLine
- )
- # S1 is always Arch
- if len(ItemList) > 1:
- S1 = ItemList[1].upper()
- else:
- S1 = TAB_ARCH_COMMON
- ArchList.add(S1)
- # S2 may be Platform or ModuleType
- if len(ItemList) > 2:
- S2 = ItemList[2].upper()
- # only Includes, GUIDs, PPIs, Protocols section have Private tag
- if self._SectionName in [TAB_INCLUDES.upper(), TAB_GUIDS.upper(), TAB_PROTOCOLS.upper(), TAB_PPIS.upper()]:
- if S2 != 'PRIVATE':
- EdkLogger.error("Parser", FORMAT_INVALID, 'Please use keyword "Private" as section tag modifier.',
- File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
- else:
- S2 = TAB_COMMON
- PrivateList.add(S2)
- if [S1, S2, self.DataType[self._SectionName]] not in self._Scope:
- self._Scope.append([S1, S2, self.DataType[self._SectionName]])
-
- # 'COMMON' must not be used with specific ARCHs at the same section
- if TAB_ARCH_COMMON in ArchList and len(ArchList) > 1:
- EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
- File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
-
- # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
- if TAB_COMMON in PrivateList and len(PrivateList) > 1:
- EdkLogger.error('Parser', FORMAT_INVALID, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
- File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
-
- ## [guids], [ppis] and [protocols] section parser
- @ParseMacro
- def _GuidParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- if len(TokenList) < 2:
- EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name or value specified",
- ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- if TokenList[0] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name specified",
- ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- if TokenList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No GUID value specified",
- ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidStructureStringToGuidString(TokenList[1]) == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid GUID value format",
- ExtraData=self._CurrentLine + \
- " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- self._ValueList[0] = TokenList[0]
- self._ValueList[1] = TokenList[1]
- if self._ValueList[0] not in self._GuidDict:
- self._GuidDict[self._ValueList[0]] = self._ValueList[1]
-
- def ParsePcdName(self,namelist):
- if "[" in namelist[1]:
- pcdname = namelist[1][:namelist[1].index("[")]
- arrayindex = namelist[1][namelist[1].index("["):]
- namelist[1] = pcdname
- if len(namelist) == 2:
- namelist.append(arrayindex)
- else:
- namelist[2] = ".".join((arrayindex,namelist[2]))
- return namelist
-
- ## PCD sections parser
- #
- # [PcdsFixedAtBuild]
- # [PcdsPatchableInModule]
- # [PcdsFeatureFlag]
- # [PcdsDynamicEx
- # [PcdsDynamic]
- #
- @ParseMacro
- def _PcdParser(self):
-
- if self._CurrentStructurePcdName:
- self._ValueList[0] = self._CurrentStructurePcdName
-
- if "|" not in self._CurrentLine:
- if "<HeaderFiles>" == self._CurrentLine:
- self._include_flag = True
- self._package_flag = False
- self._ValueList = None
- return
- if "<Packages>" == self._CurrentLine:
- self._package_flag = True
- self._ValueList = None
- self._include_flag = False
- return
-
- if self._include_flag:
- self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
- self._ValueList[2] = self._CurrentLine
- if self._package_flag and "}" != self._CurrentLine:
- self._ValueList[1] = "<Packages>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
- self._ValueList[2] = self._CurrentLine
- if self._CurrentLine == "}":
- self._package_flag = False
- self._include_flag = False
- self._ValueList = None
- return
- else:
- PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)
- PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT))
- if len(PcdNames) == 2:
- if PcdNames[1].strip().endswith("]"):
- PcdName = PcdNames[1][:PcdNames[1].index('[')]
- Index = PcdNames[1][PcdNames[1].index('['):]
- self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName))
- self._ValueList[1] = Index
- self._ValueList[2] = PcdTockens[1]
- else:
- self._CurrentStructurePcdName = ""
- else:
- if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]):
- EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])),
- File=self.MetaFile, Line=self._LineIndex + 1)
- self._ValueList[1] = TAB_SPLIT.join(PcdNames[2:])
- self._ValueList[2] = PcdTockens[1]
- if not self._CurrentStructurePcdName:
- if self._PcdDataTypeCODE:
- if ")}" in self._CurrentLine:
- ValuePart,RestofValue = self._CurrentLine.split(")}")
- self._PcdCodeValue = self._PcdCodeValue + "\n " + ValuePart
- self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue,RestofValue))
- self._PcdDataTypeCODE = False
- self._PcdCodeValue = ""
- else:
- self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine
- self._ValueList = None
- return
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
- self._CurrentPcdName = TokenList[0]
- if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"):
- if ")}" in self._CurrentLine:
- self._PcdDataTypeCODE = False
- self._PcdCodeValue = ""
- else:
- self._PcdDataTypeCODE = True
- self._PcdCodeValue = TokenList[1].strip()
- self._ValueList = None
- return
-
- self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
- ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')
- # check PCD information
- if self._ValueList[0] == '' or self._ValueList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
- ExtraData=self._CurrentLine + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check format of token space GUID CName
- if not ValueRe.match(self._ValueList[0]):
- EdkLogger.error('Parser', FORMAT_INVALID, "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
- ExtraData=self._CurrentLine + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check format of PCD CName
- if not ValueRe.match(self._ValueList[1]):
- EdkLogger.error('Parser', FORMAT_INVALID, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
- ExtraData=self._CurrentLine + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check PCD datum information
- if len(TokenList) < 2 or TokenList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",
- ExtraData=self._CurrentLine + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
-
-
- ValueRe = re.compile(r'^\s*L?\".*\|.*\"')
- PtrValue = ValueRe.findall(TokenList[1])
-
- # Has VOID* type string, may contain "|" character in the string.
- if len(PtrValue) != 0:
- ptrValueList = re.sub(ValueRe, '', TokenList[1])
- ValueList = AnalyzePcdExpression(ptrValueList)
- ValueList[0] = PtrValue[0]
- else:
- ValueList = AnalyzePcdExpression(TokenList[1])
-
-
- # check if there's enough datum information given
- if len(ValueList) != 3:
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",
- ExtraData=self._CurrentLine + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check default value
- if ValueList[0] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",
- ExtraData=self._CurrentLine + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check datum type
- if ValueList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",
- ExtraData=self._CurrentLine + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check token of the PCD
- if ValueList[2] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",
- ExtraData=self._CurrentLine + \
- " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
- File=self.MetaFile, Line=self._LineIndex + 1)
-
- PcdValue = ValueList[0]
- if PcdValue:
- try:
- self._GuidDict.update(self._AllPcdDict)
- ValueList[0] = ValueExpressionEx(ValueList[0], ValueList[1], self._GuidDict)(True)
- except BadExpression as Value:
- EdkLogger.error('Parser', FORMAT_INVALID, Value, ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- # check format of default value against the datum type
- IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])
- if not IsValid:
- EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,
- File=self.MetaFile, Line=self._LineIndex + 1)
-
- if Cause == "StructurePcd":
- self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2])
- self._ValueList[0] = self._CurrentStructurePcdName
- self._ValueList[1] = ValueList[1].strip()
-
- if ValueList[0] in ['True', 'true', 'TRUE']:
- ValueList[0] = '1'
- elif ValueList[0] in ['False', 'false', 'FALSE']:
- ValueList[0] = '0'
-
- # check for duplicate PCD definition
- if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:
- EdkLogger.error('Parser', FORMAT_INVALID,
- "The same PCD name and GUID have been already defined",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- else:
- self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))
- self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]
-
- self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()
-
- _SectionParser = {
- MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,
- MODEL_EFI_INCLUDE : MetaFileParser._PathParser,
- MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,
- MODEL_EFI_GUID : _GuidParser,
- MODEL_EFI_PPI : _GuidParser,
- MODEL_EFI_PROTOCOL : _GuidParser,
- MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
- MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
- MODEL_PCD_FEATURE_FLAG : _PcdParser,
- MODEL_PCD_DYNAMIC : _PcdParser,
- MODEL_PCD_DYNAMIC_EX : _PcdParser,
- MODEL_UNKNOWN : MetaFileParser._Skip,
- MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
- }
-
-##
-#
-# This acts like the main() function for the script, unless it is 'import'ed into another
-# script.
-#
-if __name__ == '__main__':
- pass
-
+## @file
+# This file is used to parse meta files
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2015-2018 Hewlett Packard Enterprise Development LP<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+##
+# Import Modules
+#
+from __future__ import print_function
+from __future__ import absolute_import
+import Common.LongFilePathOs as os
+import re
+import time
+import copy
+from hashlib import md5
+
+import Common.EdkLogger as EdkLogger
+import Common.GlobalData as GlobalData
+
+from CommonDataClass.DataClass import *
+from Common.DataType import *
+from Common.StringUtils import *
+from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression, ParseFieldValue, StructPattern
+from Common.Expression import *
+from CommonDataClass.Exceptions import *
+from Common.LongFilePathSupport import OpenLongFilePath as open
+from collections import defaultdict
+from .MetaFileTable import MetaFileStorage
+from .MetaFileCommentParser import CheckInfComment
+from Common.DataType import TAB_COMMENT_EDK_START, TAB_COMMENT_EDK_END
+
+## RegEx for finding file versions
+hexVersionPattern = re.compile(r'0[xX][\da-f-A-F]{5,8}')
+decVersionPattern = re.compile(r'\d+\.\d+')
+CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")
+
+## A decorator used to parse macro definition
+def ParseMacro(Parser):
+ def MacroParser(self):
+ Match = GlobalData.gMacroDefPattern.match(self._CurrentLine)
+ if not Match:
+ # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
+ Parser(self)
+ return
+
+ TokenList = GetSplitValueList(self._CurrentLine[Match.end(1):], TAB_EQUAL_SPLIT, 1)
+ # Syntax check
+ if not TokenList[0]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No macro name given",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ if len(TokenList) < 2:
+ TokenList.append('')
+
+ Type = Match.group(1)
+ Name, Value = TokenList
+ # Global macros can be only defined via environment variable
+ if Name in GlobalData.gGlobalDefines:
+ EdkLogger.error('Parser', FORMAT_INVALID, "%s can only be defined via environment variable" % Name,
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ # Only upper case letters, digit and '_' are allowed
+ if not GlobalData.gMacroNamePattern.match(Name):
+ EdkLogger.error('Parser', FORMAT_INVALID, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+
+ Value = ReplaceMacro(Value, self._Macros)
+ if Type in self.DataType:
+ self._ItemType = self.DataType[Type]
+ else:
+ self._ItemType = MODEL_META_DATA_DEFINE
+ # DEFINE defined macros
+ if Type == TAB_DSC_DEFINES_DEFINE:
+ #
+ # First judge whether this DEFINE is in conditional directive statements or not.
+ #
+ if isinstance(self, DscParser) and self._InDirective > -1:
+ pass
+ else:
+ if isinstance(self, DecParser):
+ if MODEL_META_DATA_HEADER in self._SectionType:
+ self._FileLocalMacros[Name] = Value
+ else:
+ self._ConstructSectionMacroDict(Name, Value)
+ elif self._SectionType == MODEL_META_DATA_HEADER:
+ self._FileLocalMacros[Name] = Value
+ else:
+ self._ConstructSectionMacroDict(Name, Value)
+
+ # EDK_GLOBAL defined macros
+ elif not isinstance(self, DscParser):
+ EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used in .dsc file",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ elif self._SectionType != MODEL_META_DATA_HEADER:
+ EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used under [Defines] section",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ elif (Name in self._FileLocalMacros) and (self._FileLocalMacros[Name] != Value):
+ EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+
+ self._ValueList = [Type, Name, Value]
+
+ return MacroParser
+
+## Base class of parser
+#
+# This class is used for derivation purpose. The specific parser for one kind
+# type file must derive this class and implement some public interfaces.
+#
+# @param FilePath The path of platform description file
+# @param FileType The raw data of DSC file
+# @param Table Database used to retrieve module/package information
+# @param Macros Macros used for replacement in file
+# @param Owner Owner ID (for sub-section parsing)
+# @param From ID from which the data comes (for !INCLUDE directive)
+#
+class MetaFileParser(object):
+ # data type (file content) for specific file type
+ DataType = {}
+
+ # Parser objects used to implement singleton
+ MetaFiles = {}
+
+ ## Factory method
+ #
+ # One file, one parser object. This factory method makes sure that there's
+ # only one object constructed for one meta file.
+ #
+ # @param Class class object of real AutoGen class
+ # (InfParser, DecParser or DscParser)
+ # @param FilePath The path of meta file
+ # @param *args The specific class related parameters
+ # @param **kwargs The specific class related dict parameters
+ #
+ def __new__(Class, FilePath, *args, **kwargs):
+ if FilePath in Class.MetaFiles:
+ return Class.MetaFiles[FilePath]
+ else:
+ ParserObject = super(MetaFileParser, Class).__new__(Class)
+ Class.MetaFiles[FilePath] = ParserObject
+ return ParserObject
+
+ ## Constructor of MetaFileParser
+ #
+ # Initialize object of MetaFileParser
+ #
+ # @param FilePath The path of platform description file
+ # @param FileType The raw data of DSC file
+ # @param Arch Default Arch value for filtering sections
+ # @param Table Database used to retrieve module/package information
+ # @param Owner Owner ID (for sub-section parsing)
+ # @param From ID from which the data comes (for !INCLUDE directive)
+ #
+ def __init__(self, FilePath, FileType, Arch, Table, Owner= -1, From= -1):
+ self._Table = Table
+ self._RawTable = Table
+ self._Arch = Arch
+ self._FileType = FileType
+ self.MetaFile = FilePath
+ self._FileDir = self.MetaFile.Dir
+ self._Defines = {}
+ self._Packages = []
+ self._FileLocalMacros = {}
+ self._SectionsMacroDict = defaultdict(dict)
+
+ # for recursive parsing
+ self._Owner = [Owner]
+ self._From = From
+
+ # parsr status for parsing
+ self._ValueList = ['', '', '', '', '']
+ self._Scope = []
+ self._LineIndex = 0
+ self._CurrentLine = ''
+ self._SectionType = MODEL_UNKNOWN
+ self._SectionName = ''
+ self._InSubsection = False
+ self._SubsectionType = MODEL_UNKNOWN
+ self._SubsectionName = ''
+ self._ItemType = MODEL_UNKNOWN
+ self._LastItem = -1
+ self._Enabled = 0
+ self._Finished = False
+ self._PostProcessed = False
+ # Different version of meta-file has different way to parse.
+ self._Version = 0
+ self._GuidDict = {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
+
+ self._PcdCodeValue = ""
+ self._PcdDataTypeCODE = False
+ self._CurrentPcdName = ""
+
+ ## Store the parsed data in table
+ def _Store(self, *Args):
+ return self._Table.Insert(*Args)
+
+ ## Virtual method for starting parse
+ def Start(self):
+ raise NotImplementedError
+
+ ## Notify a post-process is needed
+ def DoPostProcess(self):
+ self._PostProcessed = False
+
+ ## Set parsing complete flag in both class and table
+ def _Done(self):
+ self._Finished = True
+ self._Table.SetEndFlag()
+
+ def _PostProcess(self):
+ self._PostProcessed = True
+
+ ## Get the parse complete flag
+ @property
+ def Finished(self):
+ return self._Finished
+
+ ## Set the complete flag
+ @Finished.setter
+ def Finished(self, Value):
+ self._Finished = Value
+
+ ## Remove records that do not match given Filter Arch
+ def _FilterRecordList(self, RecordList, FilterArch):
+ NewRecordList = []
+ for Record in RecordList:
+ Arch = Record[3]
+ if Arch == TAB_ARCH_COMMON or Arch == FilterArch:
+ NewRecordList.append(Record)
+ return NewRecordList
+
+ ## Use [] style to query data in table, just for readability
+ #
+ # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
+ #
+ def __getitem__(self, DataInfo):
+ if not isinstance(DataInfo, type(())):
+ DataInfo = (DataInfo,)
+
+ # Parse the file first, if necessary
+ self.StartParse()
+
+ # No specific ARCH or Platform given, use raw data
+ if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] is None):
+ return self._FilterRecordList(self._RawTable.Query(*DataInfo), self._Arch)
+
+ # Do post-process if necessary
+ if not self._PostProcessed:
+ self._PostProcess()
+
+ return self._FilterRecordList(self._Table.Query(*DataInfo), DataInfo[1])
+
+ def StartParse(self):
+ if not self._Finished:
+ if self._RawTable.IsIntegrity():
+ self._Finished = True
+ else:
+ self._Table = self._RawTable
+ self._PostProcessed = False
+ self.Start()
+ ## Data parser for the common format in different type of file
+ #
+ # The common format in the meatfile is like
+ #
+ # xxx1 | xxx2 | xxx3
+ #
+ @ParseMacro
+ def _CommonParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+ self._ValueList[0:len(TokenList)] = TokenList
+
+ ## Data parser for the format in which there's path
+ #
+ # Only path can have macro used. So we need to replace them before use.
+ #
+ @ParseMacro
+ def _PathParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+ self._ValueList[0:len(TokenList)] = TokenList
+ # Don't do macro replacement for dsc file at this point
+ if not isinstance(self, DscParser):
+ Macros = self._Macros
+ self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]
+
+ ## Skip unsupported data
+ def _Skip(self):
+ EdkLogger.warn("Parser", "Unrecognized content", File=self.MetaFile,
+ Line=self._LineIndex + 1, ExtraData=self._CurrentLine);
+ self._ValueList[0:1] = [self._CurrentLine]
+
+ ## Skip unsupported data for UserExtension Section
+ def _SkipUserExtension(self):
+ self._ValueList[0:1] = [self._CurrentLine]
+
+ ## Section header parser
+ #
+ # The section header is always in following format:
+ #
+ # [section_name.arch<.platform|module_type>]
+ #
+ def _SectionHeaderParser(self):
+ self._Scope = []
+ self._SectionName = ''
+ ArchList = set()
+ for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT):
+ if Item == '':
+ continue
+ ItemList = GetSplitValueList(Item, TAB_SPLIT, 3)
+ # different section should not mix in one section
+ if self._SectionName != '' and self._SectionName != ItemList[0].upper():
+ EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section",
+ File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
+ self._SectionName = ItemList[0].upper()
+ if self._SectionName in self.DataType:
+ self._SectionType = self.DataType[self._SectionName]
+ # Check if the section name is valid
+ if self._SectionName not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET and len(ItemList) > 3:
+ EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
+ self.MetaFile, self._LineIndex + 1, self._CurrentLine)
+ elif self._Version >= 0x00010005:
+ EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
+ self.MetaFile, self._LineIndex + 1, self._CurrentLine)
+ else:
+ self._SectionType = MODEL_UNKNOWN
+
+ # S1 is always Arch
+ if len(ItemList) > 1:
+ S1 = ItemList[1].upper()
+ else:
+ S1 = TAB_ARCH_COMMON
+ S1 = ReplaceMacro(S1, self._Macros)
+ ArchList.add(S1)
+
+ # S2 may be Platform or ModuleType
+ if len(ItemList) > 2:
+ if self._SectionName.upper() in SECTIONS_HAVE_ITEM_PCD_SET:
+ S2 = ItemList[2]
+ else:
+ S2 = ItemList[2].upper()
+ else:
+ S2 = TAB_COMMON
+ if len(ItemList) > 3:
+ S3 = ItemList[3]
+ else:
+ S3 = TAB_COMMON
+ self._Scope.append([S1, S2, S3])
+
+ # 'COMMON' must not be used with specific ARCHs at the same section
+ if TAB_ARCH_COMMON in ArchList and len(ArchList) > 1:
+ EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
+ File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
+ # If the section information is needed later, it should be stored in database
+ self._ValueList[0] = self._SectionName
+
+ ## [packages] section parser
+ @ParseMacro
+ def _PackageParser(self):
+ self._CurrentLine = CleanString(self._CurrentLine)
+ self._Packages.append(self._CurrentLine)
+ self._ValueList[0] = self._CurrentLine
+
+ ## [defines] section parser
+ @ParseMacro
+ def _DefineParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+ self._ValueList[1:len(TokenList)] = TokenList
+ if not self._ValueList[1]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ if not self._ValueList[2]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+
+ self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]
+ Name, Value = self._ValueList[1], self._ValueList[2]
+ MacroUsed = GlobalData.gMacroRefPattern.findall(Value)
+ if len(MacroUsed) != 0:
+ for Macro in MacroUsed:
+ if Macro in GlobalData.gGlobalDefines:
+ EdkLogger.error("Parser", FORMAT_INVALID, "Global macro %s is not permitted." % (Macro), ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ else:
+ EdkLogger.error("Parser", FORMAT_INVALID, "%s not defined" % (Macro), ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ # Sometimes, we need to make differences between EDK and EDK2 modules
+ if Name == 'INF_VERSION':
+ if hexVersionPattern.match(Value):
+ self._Version = int(Value, 0)
+ elif decVersionPattern.match(Value):
+ ValueList = Value.split('.')
+ Major = int(ValueList[0], 0)
+ Minor = int(ValueList[1], 0)
+ if Major > 0xffff or Minor > 0xffff:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ self._Version = int('0x{0:04x}{1:04x}'.format(Major, Minor), 0)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+
+ if isinstance(self, InfParser) and self._Version < 0x00010005:
+ # EDK module allows using defines as macros
+ self._FileLocalMacros[Name] = Value
+ self._Defines[Name] = Value
+
+ ## [BuildOptions] section parser
+ @ParseMacro
+ def _BuildOptionParser(self):
+ self._CurrentLine = CleanString(self._CurrentLine, BuildOption=True)
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+ TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
+ if len(TokenList2) == 2:
+ self._ValueList[0] = TokenList2[0] # toolchain family
+ self._ValueList[1] = TokenList2[1] # keys
+ else:
+ self._ValueList[1] = TokenList[0]
+ if len(TokenList) == 2 and not isinstance(self, DscParser): # value
+ self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)
+
+ if self._ValueList[1].count('_') != 4:
+ EdkLogger.error(
+ 'Parser',
+ FORMAT_INVALID,
+ "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],
+ ExtraData=self._CurrentLine,
+ File=self.MetaFile,
+ Line=self._LineIndex + 1
+ )
+ def GetValidExpression(self, TokenSpaceGuid, PcdCName):
+ return self._Table.GetValidExpression(TokenSpaceGuid, PcdCName)
+
+ @property
+ def _Macros(self):
+ Macros = {}
+ Macros.update(self._FileLocalMacros)
+ Macros.update(self._GetApplicableSectionMacro())
+ return Macros
+
+ ## Construct section Macro dict
+ def _ConstructSectionMacroDict(self, Name, Value):
+ ScopeKey = [(Scope[0], Scope[1], Scope[2]) for Scope in self._Scope]
+ ScopeKey = tuple(ScopeKey)
+ #
+ # DecParser SectionType is a list, will contain more than one item only in Pcd Section
+ # As Pcd section macro usage is not allowed, so here it is safe
+ #
+ if isinstance(self, DecParser):
+ SectionDictKey = self._SectionType[0], ScopeKey
+ else:
+ SectionDictKey = self._SectionType, ScopeKey
+
+ self._SectionsMacroDict[SectionDictKey][Name] = Value
+
+ ## Get section Macros that are applicable to current line, which may come from other sections
+ ## that share the same name while scope is wider
+ def _GetApplicableSectionMacro(self):
+ Macros = {}
+
+ ComComMacroDict = {}
+ ComSpeMacroDict = {}
+ SpeSpeMacroDict = {}
+
+ ActiveSectionType = self._SectionType
+ if isinstance(self, DecParser):
+ ActiveSectionType = self._SectionType[0]
+
+ for (SectionType, Scope) in self._SectionsMacroDict:
+ if SectionType != ActiveSectionType:
+ continue
+
+ for ActiveScope in self._Scope:
+ Scope0, Scope1, Scope2= ActiveScope[0], ActiveScope[1], ActiveScope[2]
+ if(Scope0, Scope1, Scope2) not in Scope:
+ break
+ else:
+ SpeSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
+
+ for ActiveScope in self._Scope:
+ Scope0, Scope1, Scope2 = ActiveScope[0], ActiveScope[1], ActiveScope[2]
+ if(Scope0, Scope1, Scope2) not in Scope and (Scope0, TAB_COMMON, TAB_COMMON) not in Scope and (TAB_COMMON, Scope1, TAB_COMMON) not in Scope:
+ break
+ else:
+ ComSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
+
+ if (TAB_COMMON, TAB_COMMON, TAB_COMMON) in Scope:
+ ComComMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
+
+ Macros.update(ComComMacroDict)
+ Macros.update(ComSpeMacroDict)
+ Macros.update(SpeSpeMacroDict)
+
+ return Macros
+
+ def ProcessMultipleLineCODEValue(self,Content):
+ CODEBegin = False
+ CODELine = ""
+ continuelinecount = 0
+ newContent = []
+ for Index in range(0, len(Content)):
+ Line = Content[Index]
+ if CODEBegin:
+ CODELine = CODELine + Line
+ continuelinecount +=1
+ if ")}" in Line:
+ newContent.append(CODELine)
+ for _ in range(continuelinecount):
+ newContent.append("")
+ CODEBegin = False
+ CODELine = ""
+ continuelinecount = 0
+ else:
+ if not Line:
+ newContent.append(Line)
+ continue
+ if "{CODE(" not in Line:
+ newContent.append(Line)
+ continue
+ elif CODEPattern.findall(Line):
+ newContent.append(Line)
+ continue
+ else:
+ CODEBegin = True
+ CODELine = Line
+
+ return newContent
+
+ _SectionParser = {}
+
+## INF file parser class
+#
+# @param FilePath The path of platform description file
+# @param FileType The raw data of DSC file
+# @param Table Database used to retrieve module/package information
+# @param Macros Macros used for replacement in file
+#
+class InfParser(MetaFileParser):
+ # INF file supported data types (one type per section)
+ DataType = {
+ TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
+ TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,
+ TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
+ TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
+ TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
+ TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
+ TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
+ TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,
+ TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,
+ TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,
+ TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
+ TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,
+ TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,
+ TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,
+ TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,
+ TAB_GUIDS.upper() : MODEL_EFI_GUID,
+ TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
+ TAB_PPIS.upper() : MODEL_EFI_PPI,
+ TAB_DEPEX.upper() : MODEL_EFI_DEPEX,
+ TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,
+ TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION
+ }
+
+ ## Constructor of InfParser
+ #
+ # Initialize object of InfParser
+ #
+ # @param FilePath The path of module description file
+ # @param FileType The raw data of DSC file
+ # @param Arch Default Arch value for filtering sections
+ # @param Table Database used to retrieve module/package information
+ #
+ def __init__(self, FilePath, FileType, Arch, Table):
+ # prevent re-initialization
+ if hasattr(self, "_Table"):
+ return
+ MetaFileParser.__init__(self, FilePath, FileType, Arch, Table)
+ self.PcdsDict = {}
+
+ ## Parser starter
+ def Start(self):
+ NmakeLine = ''
+ Content = ''
+ try:
+ with open(str(self.MetaFile), 'r') as File:
+ Content = File.readlines()
+ except:
+ EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
+
+ # parse the file line by line
+ IsFindBlockComment = False
+ GetHeaderComment = False
+ TailComments = []
+ SectionComments = []
+ Comments = []
+
+ for Index in range(0, len(Content)):
+ # skip empty, commented, block commented lines
+ Line, Comment = CleanString2(Content[Index], AllowCppStyleComment=True)
+ NextLine = ''
+ if Index + 1 < len(Content):
+ NextLine, NextComment = CleanString2(Content[Index + 1])
+ if Line == '':
+ if Comment:
+ Comments.append((Comment, Index + 1))
+ elif GetHeaderComment:
+ SectionComments.extend(Comments)
+ Comments = []
+ continue
+ if Line.find(TAB_COMMENT_EDK_START) > -1:
+ IsFindBlockComment = True
+ continue
+ if Line.find(TAB_COMMENT_EDK_END) > -1:
+ IsFindBlockComment = False
+ continue
+ if IsFindBlockComment:
+ continue
+
+ self._LineIndex = Index
+ self._CurrentLine = Line
+
+ # section header
+ if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
+ if not GetHeaderComment:
+ for Cmt, LNo in Comments:
+ self._Store(MODEL_META_DATA_HEADER_COMMENT, Cmt, '', '', TAB_COMMON,
+ TAB_COMMON, self._Owner[-1], LNo, -1, LNo, -1, 0)
+ GetHeaderComment = True
+ else:
+ TailComments.extend(SectionComments + Comments)
+ Comments = []
+ self._SectionHeaderParser()
+ # Check invalid sections
+ if self._Version < 0x00010005:
+ if self._SectionType in [MODEL_META_DATA_BUILD_OPTION,
+ MODEL_EFI_LIBRARY_CLASS,
+ MODEL_META_DATA_PACKAGE,
+ MODEL_PCD_FIXED_AT_BUILD,
+ MODEL_PCD_PATCHABLE_IN_MODULE,
+ MODEL_PCD_FEATURE_FLAG,
+ MODEL_PCD_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC,
+ MODEL_EFI_GUID,
+ MODEL_EFI_PROTOCOL,
+ MODEL_EFI_PPI,
+ MODEL_META_DATA_USER_EXTENSION]:
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "Section [%s] is not allowed in inf file without version" % (self._SectionName),
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ elif self._SectionType in [MODEL_EFI_INCLUDE,
+ MODEL_EFI_LIBRARY_INSTANCE,
+ MODEL_META_DATA_NMAKE]:
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "Section [%s] is not allowed in inf file with version 0x%08x" % (self._SectionName, self._Version),
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ continue
+ # merge two lines specified by '\' in section NMAKE
+ elif self._SectionType == MODEL_META_DATA_NMAKE:
+ if Line[-1] == '\\':
+ if NextLine == '':
+ self._CurrentLine = NmakeLine + Line[0:-1]
+ NmakeLine = ''
+ else:
+ if NextLine[0] == TAB_SECTION_START and NextLine[-1] == TAB_SECTION_END:
+ self._CurrentLine = NmakeLine + Line[0:-1]
+ NmakeLine = ''
+ else:
+ NmakeLine = NmakeLine + ' ' + Line[0:-1]
+ continue
+ else:
+ self._CurrentLine = NmakeLine + Line
+ NmakeLine = ''
+
+ # section content
+ self._ValueList = ['', '', '']
+ # parse current line, result will be put in self._ValueList
+ self._SectionParser[self._SectionType](self)
+ if self._ValueList is None or self._ItemType == MODEL_META_DATA_DEFINE:
+ self._ItemType = -1
+ Comments = []
+ continue
+ if Comment:
+ Comments.append((Comment, Index + 1))
+ if GlobalData.gOptions and GlobalData.gOptions.CheckUsage:
+ CheckInfComment(self._SectionType, Comments, str(self.MetaFile), Index + 1, self._ValueList)
+ #
+ # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
+ # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
+ #
+ for Arch, Platform, _ in self._Scope:
+ LastItem = self._Store(self._SectionType,
+ self._ValueList[0],
+ self._ValueList[1],
+ self._ValueList[2],
+ Arch,
+ Platform,
+ self._Owner[-1],
+ self._LineIndex + 1,
+ - 1,
+ self._LineIndex + 1,
+ - 1,
+ 0
+ )
+ for Comment, LineNo in Comments:
+ self._Store(MODEL_META_DATA_COMMENT, Comment, '', '', Arch, Platform,
+ LastItem, LineNo, -1, LineNo, -1, 0)
+ Comments = []
+ SectionComments = []
+ TailComments.extend(SectionComments + Comments)
+ if IsFindBlockComment:
+ EdkLogger.error("Parser", FORMAT_INVALID, "Open block comments (starting with /*) are expected to end with */",
+ File=self.MetaFile)
+
+ # If there are tail comments in INF file, save to database whatever the comments are
+ for Comment in TailComments:
+ self._Store(MODEL_META_DATA_TAIL_COMMENT, Comment[0], '', '', TAB_COMMON,
+ TAB_COMMON, self._Owner[-1], -1, -1, -1, -1, 0)
+ self._Done()
+
+ ## Data parser for the format in which there's path
+ #
+ # Only path can have macro used. So we need to replace them before use.
+ #
+ def _IncludeParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+ self._ValueList[0:len(TokenList)] = TokenList
+ Macros = self._Macros
+ if Macros:
+ for Index in range(0, len(self._ValueList)):
+ Value = self._ValueList[Index]
+ if not Value:
+ continue
+ self._ValueList[Index] = ReplaceMacro(Value, Macros)
+
+ ## Parse [Sources] section
+ #
+ # Only path can have macro used. So we need to replace them before use.
+ #
+ @ParseMacro
+ def _SourceFileParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+ # Let TokenList[2] be TagName|ToolCode|FeatureFlag
+ if len(TokenList) > 3:
+ for extraToken in range(3, len(TokenList)):
+ TokenList[2] = TokenList[2] + '|' + TokenList[extraToken]
+ self._ValueList[0:len(TokenList)] = TokenList
+ Macros = self._Macros
+ # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
+ if 'COMPONENT_TYPE' in Macros:
+ if self._Defines['COMPONENT_TYPE'].upper() == 'ACPITABLE':
+ self._ValueList[0] = GetSplitValueList(self._ValueList[0], ' ', 1)[0]
+ if self._Defines['BASE_NAME'] == 'Microcode':
+ pass
+ self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]
+
+ ## Parse [Binaries] section
+ #
+ # Only path can have macro used. So we need to replace them before use.
+ #
+ @ParseMacro
+ def _BinaryFileParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 2)
+ if len(TokenList) < 2:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No file type or path specified",
+ ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ if not TokenList[0]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No file type specified",
+ ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ if not TokenList[1]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No file path specified",
+ ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ self._ValueList[0:len(TokenList)] = TokenList
+ self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)
+
+ ## [nmake] section parser (Edk.x style only)
+ def _NmakeParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+ self._ValueList[0:len(TokenList)] = TokenList
+ # remove macros
+ self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)
+ # remove self-reference in macro setting
+ #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
+
+ ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
+ @ParseMacro
+ def _PcdParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
+ ValueList = GetSplitValueList(TokenList[0], TAB_SPLIT)
+ if len(ValueList) != 2:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Illegal token space GUID and PCD name format",
+ ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ self._ValueList[0:1] = ValueList
+ if len(TokenList) > 1:
+ self._ValueList[2] = TokenList[1]
+ if self._ValueList[0] == '' or self._ValueList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
+ ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+
+ # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
+ if self._ValueList[2] != '':
+ InfPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
+ if InfPcdValueList[0] in ['True', 'true', 'TRUE']:
+ self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '1', 1)
+ elif InfPcdValueList[0] in ['False', 'false', 'FALSE']:
+ self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '0', 1)
+ elif isinstance(InfPcdValueList[0], str) and InfPcdValueList[0].find('$(') >= 0:
+ Value = ReplaceExprMacro(InfPcdValueList[0],self._Macros)
+ if Value != '0':
+ self._ValueList[2] = Value
+ if (self._ValueList[0], self._ValueList[1]) not in self.PcdsDict:
+ self.PcdsDict[self._ValueList[0], self._ValueList[1]] = self._SectionType
+ elif self.PcdsDict[self._ValueList[0], self._ValueList[1]] != self._SectionType:
+ EdkLogger.error('Parser', FORMAT_INVALID, "It is not permissible to list a specified PCD in different PCD type sections.",
+ ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+
+ ## [depex] section parser
+ @ParseMacro
+ def _DepexParser(self):
+ self._ValueList[0:1] = [self._CurrentLine]
+
+ _SectionParser = {
+ MODEL_UNKNOWN : MetaFileParser._Skip,
+ MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,
+ MODEL_META_DATA_BUILD_OPTION : MetaFileParser._BuildOptionParser,
+ MODEL_EFI_INCLUDE : _IncludeParser, # for Edk.x modules
+ MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._CommonParser, # for Edk.x modules
+ MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,
+ MODEL_META_DATA_PACKAGE : MetaFileParser._PathParser,
+ MODEL_META_DATA_NMAKE : _NmakeParser, # for Edk.x modules
+ MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
+ MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
+ MODEL_PCD_FEATURE_FLAG : _PcdParser,
+ MODEL_PCD_DYNAMIC_EX : _PcdParser,
+ MODEL_PCD_DYNAMIC : _PcdParser,
+ MODEL_EFI_SOURCE_FILE : _SourceFileParser,
+ MODEL_EFI_GUID : MetaFileParser._CommonParser,
+ MODEL_EFI_PROTOCOL : MetaFileParser._CommonParser,
+ MODEL_EFI_PPI : MetaFileParser._CommonParser,
+ MODEL_EFI_DEPEX : _DepexParser,
+ MODEL_EFI_BINARY_FILE : _BinaryFileParser,
+ MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
+ }
+
+## DSC file parser class
+#
+# @param FilePath The path of platform description file
+# @param FileType The raw data of DSC file
+# @param Table Database used to retrieve module/package information
+# @param Macros Macros used for replacement in file
+# @param Owner Owner ID (for sub-section parsing)
+# @param From ID from which the data comes (for !INCLUDE directive)
+#
+class DscParser(MetaFileParser):
+ # DSC file supported data types (one type per section)
+ DataType = {
+ TAB_SKUIDS.upper() : MODEL_EFI_SKU_ID,
+ TAB_DEFAULT_STORES.upper() : MODEL_EFI_DEFAULT_STORES,
+ TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
+ TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
+ TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
+ TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,
+ TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
+ TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
+ TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
+ TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_DEFAULT,
+ TAB_PCDS_DYNAMIC_HII_NULL.upper() : MODEL_PCD_DYNAMIC_HII,
+ TAB_PCDS_DYNAMIC_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_VPD,
+ TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT,
+ TAB_PCDS_DYNAMIC_EX_HII_NULL.upper() : MODEL_PCD_DYNAMIC_EX_HII,
+ TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_EX_VPD,
+ TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,
+ TAB_DSC_DEFINES.upper() : MODEL_META_DATA_HEADER,
+ TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
+ TAB_DSC_DEFINES_EDKGLOBAL : MODEL_META_DATA_GLOBAL_DEFINE,
+ TAB_INCLUDE.upper() : MODEL_META_DATA_INCLUDE,
+ TAB_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ TAB_IF_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
+ TAB_IF_N_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,
+ TAB_ELSE_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,
+ TAB_ELSE.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,
+ TAB_END_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,
+ TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION,
+ TAB_ERROR.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR,
+ }
+
+ # Valid names in define section
+ DefineKeywords = [
+ "DSC_SPECIFICATION",
+ "PLATFORM_NAME",
+ "PLATFORM_GUID",
+ "PLATFORM_VERSION",
+ "SKUID_IDENTIFIER",
+ "PCD_INFO_GENERATION",
+ "PCD_VAR_CHECK_GENERATION",
+ "SUPPORTED_ARCHITECTURES",
+ "BUILD_TARGETS",
+ "OUTPUT_DIRECTORY",
+ "FLASH_DEFINITION",
+ "BUILD_NUMBER",
+ "RFC_LANGUAGES",
+ "ISO_LANGUAGES",
+ "TIME_STAMP_FILE",
+ "VPD_TOOL_GUID",
+ "FIX_LOAD_TOP_MEMORY_ADDRESS",
+ "PREBUILD",
+ "POSTBUILD"
+ ]
+
+ SubSectionDefineKeywords = [
+ "FILE_GUID"
+ ]
+
+ SymbolPattern = ValueExpression.SymbolPattern
+
+ IncludedFiles = set()
+
+ ## Constructor of DscParser
+ #
+ # Initialize object of DscParser
+ #
+ # @param FilePath The path of platform description file
+ # @param FileType The raw data of DSC file
+ # @param Arch Default Arch value for filtering sections
+ # @param Table Database used to retrieve module/package information
+ # @param Owner Owner ID (for sub-section parsing)
+ # @param From ID from which the data comes (for !INCLUDE directive)
+ #
+ def __init__(self, FilePath, FileType, Arch, Table, Owner= -1, From= -1):
+ # prevent re-initialization
+ if hasattr(self, "_Table") and self._Table is Table:
+ return
+ MetaFileParser.__init__(self, FilePath, FileType, Arch, Table, Owner, From)
+ self._Version = 0x00010005 # Only EDK2 dsc file is supported
+ # to store conditional directive evaluation result
+ self._DirectiveStack = []
+ self._DirectiveEvalStack = []
+ self._Enabled = 1
+
+ #
+ # Specify whether current line is in uncertain condition
+ #
+ self._InDirective = -1
+
+ # Final valid replacable symbols
+ self._Symbols = {}
+ #
+ # Map the ID between the original table and new table to track
+ # the owner item
+ #
+ self._IdMapping = {-1:-1}
+
+ self._Content = None
+
+ ## Parser starter
+ def Start(self):
+ Content = ''
+ try:
+ with open(str(self.MetaFile), 'r') as File:
+ Content = File.readlines()
+ except:
+ EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
+
+ OwnerId = {}
+
+ Content = self.ProcessMultipleLineCODEValue(Content)
+
+ for Index in range(0, len(Content)):
+ Line = CleanString(Content[Index])
+ # skip empty line
+ if Line == '':
+ continue
+
+ self._CurrentLine = Line
+ self._LineIndex = Index
+ if self._InSubsection and self._Owner[-1] == -1:
+ self._Owner.append(self._LastItem)
+
+ # section header
+ if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
+ self._SectionType = MODEL_META_DATA_SECTION_HEADER
+ # subsection ending
+ elif Line[0] == '}' and self._InSubsection:
+ self._InSubsection = False
+ self._SubsectionType = MODEL_UNKNOWN
+ self._SubsectionName = ''
+ self._Owner[-1] = -1
+ OwnerId.clear()
+ continue
+ # subsection header
+ elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:
+ self._SubsectionType = MODEL_META_DATA_SUBSECTION_HEADER
+ # directive line
+ elif Line[0] == '!':
+ TokenList = GetSplitValueList(Line, ' ', 1)
+ if TokenList[0] == TAB_INCLUDE:
+ for Arch, ModuleType, DefaultStore in self._Scope:
+ if self._SubsectionType != MODEL_UNKNOWN and Arch in OwnerId:
+ self._Owner[-1] = OwnerId[Arch]
+ self._DirectiveParser()
+ else:
+ self._DirectiveParser()
+ continue
+ if Line[0] == TAB_OPTION_START and not self._InSubsection:
+ EdkLogger.error("Parser", FILE_READ_FAILURE, "Missing the '{' before %s in Line %s" % (Line, Index+1), ExtraData=self.MetaFile)
+
+ if self._InSubsection:
+ SectionType = self._SubsectionType
+ else:
+ SectionType = self._SectionType
+ self._ItemType = SectionType
+
+ self._ValueList = ['', '', '']
+ # "SET pcd = pcd_expression" syntax is not supported in Dsc file.
+ if self._CurrentLine.upper().strip().startswith("SET "):
+ EdkLogger.error('Parser', FORMAT_INVALID, '''"SET pcd = pcd_expression" syntax is not support in Dsc file''',
+ ExtraData=self._CurrentLine,
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ self._SectionParser[SectionType](self)
+ if self._ValueList is None:
+ continue
+ #
+ # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
+ # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
+ #
+ for Arch, ModuleType, DefaultStore in self._Scope:
+ Owner = self._Owner[-1]
+ if self._SubsectionType != MODEL_UNKNOWN and Arch in OwnerId:
+ Owner = OwnerId[Arch]
+ self._LastItem = self._Store(
+ self._ItemType,
+ self._ValueList[0],
+ self._ValueList[1],
+ self._ValueList[2],
+ Arch,
+ ModuleType,
+ DefaultStore,
+ Owner,
+ self._From,
+ self._LineIndex + 1,
+ - 1,
+ self._LineIndex + 1,
+ - 1,
+ self._Enabled
+ )
+ if self._SubsectionType == MODEL_UNKNOWN and self._InSubsection:
+ OwnerId[Arch] = self._LastItem
+
+ if self._DirectiveStack:
+ Type, Line, Text = self._DirectiveStack[-1]
+ EdkLogger.error('Parser', FORMAT_INVALID, "No matching '!endif' found",
+ ExtraData=Text, File=self.MetaFile, Line=Line)
+ self._Done()
+
+ ## <subsection_header> parser
+ def _SubsectionHeaderParser(self):
+ self._SubsectionName = self._CurrentLine[1:-1].upper()
+ if self._SubsectionName in self.DataType:
+ self._SubsectionType = self.DataType[self._SubsectionName]
+ else:
+ self._SubsectionType = MODEL_UNKNOWN
+ EdkLogger.warn("Parser", "Unrecognized sub-section", File=self.MetaFile,
+ Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
+ self._ValueList[0] = self._SubsectionName
+
+ ## Directive statement parser
+ def _DirectiveParser(self):
+ self._ValueList = ['', '', '']
+ TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)
+ self._ValueList[0:len(TokenList)] = TokenList
+
+ # Syntax check
+ DirectiveName = self._ValueList[0].upper()
+ if DirectiveName not in self.DataType:
+ EdkLogger.error("Parser", FORMAT_INVALID, "Unknown directive [%s]" % DirectiveName,
+ File=self.MetaFile, Line=self._LineIndex + 1)
+
+ if DirectiveName in ['!IF', '!IFDEF', '!IFNDEF']:
+ self._InDirective += 1
+
+ if DirectiveName in ['!ENDIF']:
+ self._InDirective -= 1
+
+ if DirectiveName in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self._ValueList[1] == '':
+ EdkLogger.error("Parser", FORMAT_INVALID, "Missing expression",
+ File=self.MetaFile, Line=self._LineIndex + 1,
+ ExtraData=self._CurrentLine)
+
+ ItemType = self.DataType[DirectiveName]
+ Scope = [[TAB_COMMON, TAB_COMMON, TAB_COMMON]]
+ if ItemType == MODEL_META_DATA_INCLUDE:
+ Scope = self._Scope
+ elif ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR:
+ Scope = self._Scope
+ if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
+ # Remove all directives between !if and !endif, including themselves
+ while self._DirectiveStack:
+ # Remove any !else or !elseif
+ DirectiveInfo = self._DirectiveStack.pop()
+ if DirectiveInfo[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
+ break
+ else:
+ EdkLogger.error("Parser", FORMAT_INVALID, "Redundant '!endif'",
+ File=self.MetaFile, Line=self._LineIndex + 1,
+ ExtraData=self._CurrentLine)
+ elif ItemType not in {MODEL_META_DATA_INCLUDE, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR}:
+ # Break if there's a !else is followed by a !elseif
+ if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF and \
+ self._DirectiveStack and \
+ self._DirectiveStack[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
+ EdkLogger.error("Parser", FORMAT_INVALID, "'!elseif' after '!else'",
+ File=self.MetaFile, Line=self._LineIndex + 1,
+ ExtraData=self._CurrentLine)
+ self._DirectiveStack.append((ItemType, self._LineIndex + 1, self._CurrentLine))
+
+ #
+ # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
+ # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
+ #
+ for Arch, ModuleType, DefaultStore in Scope:
+ self._LastItem = self._Store(
+ ItemType,
+ self._ValueList[0],
+ self._ValueList[1],
+ self._ValueList[2],
+ Arch,
+ ModuleType,
+ DefaultStore,
+ self._Owner[-1],
+ self._From,
+ self._LineIndex + 1,
+ - 1,
+ self._LineIndex + 1,
+ - 1,
+ 0
+ )
+
+ ## [defines] section parser
+ @ParseMacro
+ def _DefineParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+ self._ValueList[1:len(TokenList)] = TokenList
+
+ # Syntax check
+ if not self._ValueList[1]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ if not self._ValueList[2]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ if (not self._ValueList[1] in self.DefineKeywords and
+ (self._InSubsection and self._ValueList[1] not in self.SubSectionDefineKeywords)):
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "Unknown keyword found: %s. "
+ "If this is a macro you must "
+ "add it as a DEFINE in the DSC" % self._ValueList[1],
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ if not self._InSubsection:
+ self._Defines[self._ValueList[1]] = self._ValueList[2]
+ self._ItemType = self.DataType[TAB_DSC_DEFINES.upper()]
+
+ @ParseMacro
+ def _SkuIdParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+ if len(TokenList) not in (2, 3):
+ EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Number>|<UiName>[|<UiName>]'",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ self._ValueList[0:len(TokenList)] = TokenList
+ @ParseMacro
+ def _DefaultStoresParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+ if len(TokenList) != 2:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Number>|<UiName>'",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ self._ValueList[0:len(TokenList)] = TokenList
+
+ ## Parse Edk style of library modules
+ @ParseMacro
+ def _LibraryInstanceParser(self):
+ self._ValueList[0] = self._CurrentLine
+
+
+ def _DecodeCODEData(self):
+ pass
+ ## PCD sections parser
+ #
+ # [PcdsFixedAtBuild]
+ # [PcdsPatchableInModule]
+ # [PcdsFeatureFlag]
+ # [PcdsDynamicEx
+ # [PcdsDynamicExDefault]
+ # [PcdsDynamicExVpd]
+ # [PcdsDynamicExHii]
+ # [PcdsDynamic]
+ # [PcdsDynamicDefault]
+ # [PcdsDynamicVpd]
+ # [PcdsDynamicHii]
+ #
+ @ParseMacro
+ def _PcdParser(self):
+ if self._PcdDataTypeCODE:
+ self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine
+ if self._CurrentLine.endswith(")}"):
+ self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue))
+ self._PcdDataTypeCODE = False
+ self._PcdCodeValue = ""
+ else:
+ self._ValueList = None
+ return
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
+ self._CurrentPcdName = TokenList[0]
+ if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"):
+ self._PcdDataTypeCODE = True
+ self._PcdCodeValue = TokenList[1].strip()
+
+ if self._PcdDataTypeCODE:
+ if self._CurrentLine.endswith(")}"):
+ self._PcdDataTypeCODE = False
+ self._PcdCodeValue = ""
+ else:
+ self._ValueList = None
+ return
+ self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
+ PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)
+ if len(PcdNameTockens) == 2:
+ self._ValueList[0], self._ValueList[1] = PcdNameTockens[0], PcdNameTockens[1]
+ elif len(PcdNameTockens) == 3:
+ self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), PcdNameTockens[2]
+ elif len(PcdNameTockens) > 3:
+ self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), ".".join(PcdNameTockens[2:])
+ if len(TokenList) == 2:
+ self._ValueList[2] = TokenList[1]
+ if self._ValueList[0] == '' or self._ValueList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
+ ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ if self._ValueList[2] == '':
+ #
+ # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
+ #
+ if self._SectionType in (MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):
+ return
+ EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given",
+ ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+
+ # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
+ ValueList = GetSplitValueList(self._ValueList[2])
+ if len(ValueList) > 1 and ValueList[1] in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64] \
+ and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1],
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+
+ # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
+ if self._ItemType in [MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII]:
+ DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
+ if len(DscPcdValueList[0].replace('L', '').replace('"', '').strip()) == 0:
+ EdkLogger.error('Parser', FORMAT_INVALID, "The VariableName field in the HII format PCD entry must not be an empty string",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+
+ # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
+ DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
+ if DscPcdValueList[0] in ['True', 'true', 'TRUE']:
+ self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1);
+ elif DscPcdValueList[0] in ['False', 'false', 'FALSE']:
+ self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1);
+
+
+ ## [components] section parser
+ @ParseMacro
+ def _ComponentParser(self):
+ if self._CurrentLine[-1] == '{':
+ self._ValueList[0] = self._CurrentLine[0:-1].strip()
+ self._InSubsection = True
+ self._SubsectionType = MODEL_UNKNOWN
+ else:
+ self._ValueList[0] = self._CurrentLine
+
+ ## [LibraryClasses] section
+ @ParseMacro
+ def _LibraryClassParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+ if len(TokenList) < 2:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No library class or instance specified",
+ ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ if TokenList[0] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No library class specified",
+ ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ if TokenList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No library instance specified",
+ ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+
+ self._ValueList[0:len(TokenList)] = TokenList
+
+
+ ## [BuildOptions] section parser
+ @ParseMacro
+ def _BuildOptionParser(self):
+ self._CurrentLine = CleanString(self._CurrentLine, BuildOption=True)
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+ TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
+ if len(TokenList2) == 2:
+ self._ValueList[0] = TokenList2[0] # toolchain family
+ self._ValueList[1] = TokenList2[1] # keys
+ else:
+ self._ValueList[1] = TokenList[0]
+ if len(TokenList) == 2: # value
+ self._ValueList[2] = TokenList[1]
+
+ if self._ValueList[1].count('_') != 4:
+ EdkLogger.error(
+ 'Parser',
+ FORMAT_INVALID,
+ "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],
+ ExtraData=self._CurrentLine,
+ File=self.MetaFile,
+ Line=self._LineIndex + 1
+ )
+
+ ## Override parent's method since we'll do all macro replacements in parser
+ @property
+ def _Macros(self):
+ Macros = {}
+ Macros.update(self._FileLocalMacros)
+ Macros.update(self._GetApplicableSectionMacro())
+ Macros.update(GlobalData.gEdkGlobal)
+ Macros.update(GlobalData.gPlatformDefines)
+ Macros.update(GlobalData.gCommandLineDefines)
+ # PCD cannot be referenced in macro definition
+ if self._ItemType not in [MODEL_META_DATA_DEFINE, MODEL_META_DATA_GLOBAL_DEFINE]:
+ Macros.update(self._Symbols)
+ if GlobalData.BuildOptionPcd:
+ for Item in GlobalData.BuildOptionPcd:
+ if isinstance(Item, tuple):
+ continue
+ PcdName, TmpValue = Item.split("=")
+ TmpValue = BuildOptionValue(TmpValue, self._GuidDict)
+ Macros[PcdName.strip()] = TmpValue
+ return Macros
+
+ def _PostProcess(self):
+ Processer = {
+ MODEL_META_DATA_SECTION_HEADER : self.__ProcessSectionHeader,
+ MODEL_META_DATA_SUBSECTION_HEADER : self.__ProcessSubsectionHeader,
+ MODEL_META_DATA_HEADER : self.__ProcessDefine,
+ MODEL_META_DATA_DEFINE : self.__ProcessDefine,
+ MODEL_META_DATA_GLOBAL_DEFINE : self.__ProcessDefine,
+ MODEL_META_DATA_INCLUDE : self.__ProcessDirective,
+ MODEL_META_DATA_PACKAGE : self.__ProcessPackages,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IF : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF : self.__ProcessDirective,
+ MODEL_EFI_SKU_ID : self.__ProcessSkuId,
+ MODEL_EFI_DEFAULT_STORES : self.__ProcessDefaultStores,
+ MODEL_EFI_LIBRARY_INSTANCE : self.__ProcessLibraryInstance,
+ MODEL_EFI_LIBRARY_CLASS : self.__ProcessLibraryClass,
+ MODEL_PCD_FIXED_AT_BUILD : self.__ProcessPcd,
+ MODEL_PCD_PATCHABLE_IN_MODULE : self.__ProcessPcd,
+ MODEL_PCD_FEATURE_FLAG : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_DEFAULT : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_HII : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_VPD : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_EX_HII : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_EX_VPD : self.__ProcessPcd,
+ MODEL_META_DATA_COMPONENT : self.__ProcessComponent,
+ MODEL_META_DATA_BUILD_OPTION : self.__ProcessBuildOption,
+ MODEL_UNKNOWN : self._Skip,
+ MODEL_META_DATA_USER_EXTENSION : self._SkipUserExtension,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR : self._ProcessError,
+ }
+
+ self._Table = MetaFileStorage(self._RawTable.DB, self.MetaFile, MODEL_FILE_DSC, True)
+ self._DirectiveStack = []
+ self._DirectiveEvalStack = []
+ self._FileWithError = self.MetaFile
+ self._FileLocalMacros = {}
+ self._SectionsMacroDict.clear()
+ GlobalData.gPlatformDefines = {}
+
+ # Get all macro and PCD which has straitforward value
+ self.__RetrievePcdValue()
+ self._Content = self._RawTable.GetAll()
+ self._ContentIndex = 0
+ self._InSubsection = False
+ while self._ContentIndex < len(self._Content) :
+ Id, self._ItemType, V1, V2, V3, S1, S2, S3, Owner, self._From, \
+ LineStart, ColStart, LineEnd, ColEnd, Enabled = self._Content[self._ContentIndex]
+
+ if self._From < 0:
+ self._FileWithError = self.MetaFile
+
+ self._ContentIndex += 1
+
+ self._Scope = [[S1, S2, S3]]
+ #
+ # For !include directive, handle it specially,
+ # merge arch and module type in case of duplicate items
+ #
+ while self._ItemType == MODEL_META_DATA_INCLUDE:
+ if self._ContentIndex >= len(self._Content):
+ break
+ Record = self._Content[self._ContentIndex]
+ if LineStart == Record[10] and LineEnd == Record[12]:
+ if [Record[5], Record[6], Record[7]] not in self._Scope:
+ self._Scope.append([Record[5], Record[6], Record[7]])
+ self._ContentIndex += 1
+ else:
+ break
+
+ self._LineIndex = LineStart - 1
+ self._ValueList = [V1, V2, V3]
+
+ if Owner > 0 and Owner in self._IdMapping:
+ self._InSubsection = True
+ else:
+ self._InSubsection = False
+ try:
+ Processer[self._ItemType]()
+ except EvaluationException as Excpt:
+ #
+ # Only catch expression evaluation error here. We need to report
+ # the precise number of line on which the error occurred
+ #
+ if hasattr(Excpt, 'Pcd'):
+ if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
+ Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]
+ EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
+ " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
+ " of the DSC file, and it is currently defined in this section:"
+ " %s, line #: %d." % (Excpt.Pcd, Info[0], Info[1]),
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex + 1)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex + 1)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex + 1)
+ except MacroException as Excpt:
+ EdkLogger.error('Parser', FORMAT_INVALID, str(Excpt),
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex + 1)
+
+ if self._ValueList is None:
+ continue
+
+ NewOwner = self._IdMapping.get(Owner, -1)
+ self._Enabled = int((not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack))
+ self._LastItem = self._Store(
+ self._ItemType,
+ self._ValueList[0],
+ self._ValueList[1],
+ self._ValueList[2],
+ S1,
+ S2,
+ S3,
+ NewOwner,
+ self._From,
+ self._LineIndex + 1,
+ - 1,
+ self._LineIndex + 1,
+ - 1,
+ self._Enabled
+ )
+ self._IdMapping[Id] = self._LastItem
+
+ GlobalData.gPlatformDefines.update(self._FileLocalMacros)
+ self._PostProcessed = True
+ self._Content = None
+ def _ProcessError(self):
+ if not self._Enabled:
+ return
+ EdkLogger.error('Parser', ERROR_STATEMENT, self._ValueList[1], File=self.MetaFile, Line=self._LineIndex + 1)
+
+ def __ProcessSectionHeader(self):
+ self._SectionName = self._ValueList[0]
+ if self._SectionName in self.DataType:
+ self._SectionType = self.DataType[self._SectionName]
+ else:
+ self._SectionType = MODEL_UNKNOWN
+
+ def __ProcessSubsectionHeader(self):
+ self._SubsectionName = self._ValueList[0]
+ if self._SubsectionName in self.DataType:
+ self._SubsectionType = self.DataType[self._SubsectionName]
+ else:
+ self._SubsectionType = MODEL_UNKNOWN
+
+ def __RetrievePcdValue(self):
+ try:
+ with open(str(self.MetaFile), 'r') as File:
+ Content = File.readlines()
+ except:
+ EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
+
+ GlobalData.gPlatformOtherPcds['DSCFILE'] = str(self.MetaFile)
+ for PcdType in (MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_HII,
+ MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_DYNAMIC_EX_HII,
+ MODEL_PCD_DYNAMIC_EX_VPD):
+ Records = self._RawTable.Query(PcdType, BelongsToItem= -1.0)
+ for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, Dummy4, ID, Line in Records:
+ Name = TokenSpaceGuid + '.' + PcdName
+ if Name not in GlobalData.gPlatformOtherPcds:
+ PcdLine = Line
+ while not Content[Line - 1].lstrip().startswith(TAB_SECTION_START):
+ Line -= 1
+ GlobalData.gPlatformOtherPcds[Name] = (CleanString(Content[Line - 1]), PcdLine, PcdType)
+
+ def __ProcessDefine(self):
+ if not self._Enabled:
+ return
+
+ Type, Name, Value = self._ValueList
+ Value = ReplaceMacro(Value, self._Macros, False)
+ #
+ # If it is <Defines>, return
+ #
+ if self._InSubsection:
+ self._ValueList = [Type, Name, Value]
+ return
+
+ if self._ItemType == MODEL_META_DATA_DEFINE:
+ if self._SectionType == MODEL_META_DATA_HEADER:
+ self._FileLocalMacros[Name] = Value
+ else:
+ self._ConstructSectionMacroDict(Name, Value)
+ elif self._ItemType == MODEL_META_DATA_GLOBAL_DEFINE:
+ GlobalData.gEdkGlobal[Name] = Value
+
+ #
+ # Keyword in [Defines] section can be used as Macros
+ #
+ if (self._ItemType == MODEL_META_DATA_HEADER) and (self._SectionType == MODEL_META_DATA_HEADER):
+ self._FileLocalMacros[Name] = Value
+
+ self._ValueList = [Type, Name, Value]
+
+ def __ProcessDirective(self):
+ Result = None
+ if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF]:
+ Macros = self._Macros
+ Macros.update(GlobalData.gGlobalDefines)
+ try:
+ Result = ValueExpression(self._ValueList[1], Macros)()
+ except SymbolNotFound as Exc:
+ EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc), self._ValueList[1])
+ Result = False
+ except WrnExpression as Excpt:
+ #
+ # Catch expression evaluation warning here. We need to report
+ # the precise number of line and return the evaluation result
+ #
+ EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex + 1)
+ Result = Excpt.result
+
+ if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
+ self._DirectiveStack.append(self._ItemType)
+ if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IF:
+ Result = bool(Result)
+ else:
+ Macro = self._ValueList[1]
+ Macro = Macro[2:-1] if (Macro.startswith("$(") and Macro.endswith(")")) else Macro
+ Result = Macro in self._Macros
+ if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF:
+ Result = not Result
+ self._DirectiveEvalStack.append(Result)
+ elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF:
+ self._DirectiveStack.append(self._ItemType)
+ self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]
+ self._DirectiveEvalStack.append(bool(Result))
+ elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
+ self._DirectiveStack.append(self._ItemType)
+ self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]
+ self._DirectiveEvalStack.append(True)
+ elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
+ # Back to the nearest !if/!ifdef/!ifndef
+ while self._DirectiveStack:
+ self._DirectiveEvalStack.pop()
+ Directive = self._DirectiveStack.pop()
+ if Directive in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
+ break
+ elif self._ItemType == MODEL_META_DATA_INCLUDE:
+ # The included file must be relative to workspace or same directory as DSC file
+ __IncludeMacros = {}
+ #
+ # Allow using system environment variables in path after !include
+ #
+ __IncludeMacros['WORKSPACE'] = GlobalData.gGlobalDefines['WORKSPACE']
+ #
+ # Allow using MACROs comes from [Defines] section to keep compatible.
+ #
+ __IncludeMacros.update(self._Macros)
+
+ IncludedFile = NormPath(ReplaceMacro(self._ValueList[1], __IncludeMacros, RaiseError=True))
+ #
+ # First search the include file under the same directory as DSC file
+ #
+ IncludedFile1 = PathClass(IncludedFile, self.MetaFile.Dir)
+ if self._Enabled:
+ ErrorCode, ErrorInfo1 = IncludedFile1.Validate()
+ if ErrorCode != 0:
+ #
+ # Also search file under the WORKSPACE directory
+ #
+ IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)
+ ErrorCode, ErrorInfo2 = IncludedFile1.Validate()
+ if ErrorCode != 0:
+ EdkLogger.error('parser', ErrorCode, File=self._FileWithError,
+ Line=self._LineIndex + 1, ExtraData=ErrorInfo1 + "\n" + ErrorInfo2)
+
+ self._FileWithError = IncludedFile1
+
+ FromItem = self._Content[self._ContentIndex - 1][0]
+ if self._InSubsection:
+ Owner = self._Content[self._ContentIndex - 1][8]
+ else:
+ Owner = self._Content[self._ContentIndex - 1][0]
+ IncludedFileTable = MetaFileStorage(self._RawTable.DB, IncludedFile1, MODEL_FILE_DSC, False, FromItem=FromItem)
+ Parser = DscParser(IncludedFile1, self._FileType, self._Arch, IncludedFileTable,
+ Owner=Owner, From=FromItem)
+
+ self.IncludedFiles.add (IncludedFile1)
+
+ # set the parser status with current status
+ Parser._SectionName = self._SectionName
+ Parser._SubsectionType = self._SubsectionType
+ Parser._InSubsection = self._InSubsection
+ Parser._SectionType = self._SectionType
+ Parser._Scope = self._Scope
+ Parser._Enabled = self._Enabled
+ # Parse the included file
+ Parser.StartParse()
+ # Insert all records in the table for the included file into dsc file table
+ Records = IncludedFileTable.GetAll()
+ if Records:
+ self._Content[self._ContentIndex:self._ContentIndex] = Records
+ self._Content.pop(self._ContentIndex - 1)
+ self._ValueList = None
+ self._ContentIndex -= 1
+
+ def __ProcessPackages(self):
+ self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
+
+ def __ProcessSkuId(self):
+ self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)
+ for Value in self._ValueList]
+ def __ProcessDefaultStores(self):
+ self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)
+ for Value in self._ValueList]
+
+ def __ProcessLibraryInstance(self):
+ self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]
+
+ def __ProcessLibraryClass(self):
+ self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros, RaiseError=True)
+
+ def __ProcessPcd(self):
+ if self._ItemType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
+ self._ValueList[2] = ReplaceMacro(self._ValueList[2], self._Macros, RaiseError=True)
+ return
+
+ ValList, Valid, Index = AnalyzeDscPcd(self._ValueList[2], self._ItemType)
+ if not Valid:
+ if self._ItemType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):
+ if ValList[1] != TAB_VOID and StructPattern.match(ValList[1]) is None and ValList[2]:
+ EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect. The datum type info should be VOID* or a valid struct name.", File=self._FileWithError,
+ Line=self._LineIndex + 1, ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))
+ EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex + 1,
+ ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))
+ PcdValue = ValList[Index]
+ if PcdValue and "." not in self._ValueList[0]:
+ try:
+ ValList[Index] = ValueExpression(PcdValue, self._Macros)(True)
+ except WrnExpression as Value:
+ ValList[Index] = Value.result
+ except:
+ pass
+
+ if ValList[Index] == 'True':
+ ValList[Index] = '1'
+ if ValList[Index] == 'False':
+ ValList[Index] = '0'
+
+ if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):
+ GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue
+ self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue
+ try:
+ self._ValueList[2] = '|'.join(ValList)
+ except Exception:
+ print(ValList)
+
+ def __ProcessComponent(self):
+ self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
+
+ def __ProcessBuildOption(self):
+ self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=False)
+ for Value in self._ValueList]
+
+ def DisableOverrideComponent(self,module_id):
+ for ori_id in self._IdMapping:
+ if self._IdMapping[ori_id] == module_id:
+ self._RawTable.DisableComponent(ori_id)
+
+ _SectionParser = {
+ MODEL_META_DATA_HEADER : _DefineParser,
+ MODEL_EFI_SKU_ID : _SkuIdParser,
+ MODEL_EFI_DEFAULT_STORES : _DefaultStoresParser,
+ MODEL_EFI_LIBRARY_INSTANCE : _LibraryInstanceParser,
+ MODEL_EFI_LIBRARY_CLASS : _LibraryClassParser,
+ MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
+ MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
+ MODEL_PCD_FEATURE_FLAG : _PcdParser,
+ MODEL_PCD_DYNAMIC_DEFAULT : _PcdParser,
+ MODEL_PCD_DYNAMIC_HII : _PcdParser,
+ MODEL_PCD_DYNAMIC_VPD : _PcdParser,
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : _PcdParser,
+ MODEL_PCD_DYNAMIC_EX_HII : _PcdParser,
+ MODEL_PCD_DYNAMIC_EX_VPD : _PcdParser,
+ MODEL_META_DATA_COMPONENT : _ComponentParser,
+ MODEL_META_DATA_BUILD_OPTION : _BuildOptionParser,
+ MODEL_UNKNOWN : MetaFileParser._Skip,
+ MODEL_META_DATA_PACKAGE : MetaFileParser._PackageParser,
+ MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
+ MODEL_META_DATA_SECTION_HEADER : MetaFileParser._SectionHeaderParser,
+ MODEL_META_DATA_SUBSECTION_HEADER : _SubsectionHeaderParser,
+ }
+
+## DEC file parser class
+#
+# @param FilePath The path of platform description file
+# @param FileType The raw data of DSC file
+# @param Table Database used to retrieve module/package information
+# @param Macros Macros used for replacement in file
+#
+class DecParser(MetaFileParser):
+ # DEC file supported data types (one type per section)
+ DataType = {
+ TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER,
+ TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
+ TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
+ TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
+ TAB_GUIDS.upper() : MODEL_EFI_GUID,
+ TAB_PPIS.upper() : MODEL_EFI_PPI,
+ TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
+ TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
+ TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
+ TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
+ TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC,
+ TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX,
+ TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION,
+ }
+
+ ## Constructor of DecParser
+ #
+ # Initialize object of DecParser
+ #
+ # @param FilePath The path of platform description file
+ # @param FileType The raw data of DSC file
+ # @param Arch Default Arch value for filtering sections
+ # @param Table Database used to retrieve module/package information
+ #
+ def __init__(self, FilePath, FileType, Arch, Table):
+ # prevent re-initialization
+ if hasattr(self, "_Table"):
+ return
+ MetaFileParser.__init__(self, FilePath, FileType, Arch, Table, -1)
+ self._Comments = []
+ self._Version = 0x00010005 # Only EDK2 dec file is supported
+ self._AllPCDs = [] # Only for check duplicate PCD
+ self._AllPcdDict = {}
+
+ self._CurrentStructurePcdName = ""
+ self._include_flag = False
+ self._package_flag = False
+
+ self._RestofValue = ""
+
+ ## Parser starter
+ def Start(self):
+ Content = ''
+ try:
+ with open(str(self.MetaFile), 'r') as File:
+ Content = File.readlines()
+ except:
+ EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
+
+ Content = self.ProcessMultipleLineCODEValue(Content)
+
+ self._DefinesCount = 0
+ for Index in range(0, len(Content)):
+ Line, Comment = CleanString2(Content[Index])
+ self._CurrentLine = Line
+ self._LineIndex = Index
+
+ # save comment for later use
+ if Comment:
+ self._Comments.append((Comment, self._LineIndex + 1))
+ # skip empty line
+ if Line == '':
+ continue
+
+ # section header
+ if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
+ self._SectionHeaderParser()
+ if self._SectionName == TAB_DEC_DEFINES.upper():
+ self._DefinesCount += 1
+ self._Comments = []
+ continue
+ if self._SectionType == MODEL_UNKNOWN:
+ EdkLogger.error("Parser", FORMAT_INVALID,
+ ""
+ "Not able to determine \"%s\" in which section."%self._CurrentLine,
+ self.MetaFile, self._LineIndex + 1)
+ elif len(self._SectionType) == 0:
+ self._Comments = []
+ continue
+
+ # section content
+ self._ValueList = ['', '', '']
+ self._SectionParser[self._SectionType[0]](self)
+ if self._ValueList is None or self._ItemType == MODEL_META_DATA_DEFINE:
+ self._ItemType = -1
+ self._Comments = []
+ continue
+
+ #
+ # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
+ # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
+ #
+ for Arch, ModuleType, Type in self._Scope:
+ self._LastItem = self._Store(
+ Type,
+ self._ValueList[0],
+ self._ValueList[1],
+ self._ValueList[2],
+ Arch,
+ ModuleType,
+ self._Owner[-1],
+ self._LineIndex + 1,
+ - 1,
+ self._LineIndex + 1,
+ - 1,
+ 0
+ )
+ for Comment, LineNo in self._Comments:
+ self._Store(
+ MODEL_META_DATA_COMMENT,
+ Comment,
+ self._ValueList[0],
+ self._ValueList[1],
+ Arch,
+ ModuleType,
+ self._LastItem,
+ LineNo,
+ - 1,
+ LineNo,
+ - 1,
+ 0
+ )
+ self._Comments = []
+ if self._DefinesCount > 1:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'Multiple [Defines] section is exist.', self.MetaFile )
+ if self._DefinesCount == 0:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'No [Defines] section exist.', self.MetaFile)
+ self._Done()
+
+
+ ## Section header parser
+ #
+ # The section header is always in following format:
+ #
+ # [section_name.arch<.platform|module_type>]
+ #
+ def _SectionHeaderParser(self):
+ self._Scope = []
+ self._SectionName = ''
+ self._SectionType = []
+ ArchList = set()
+ PrivateList = set()
+ Line = re.sub(r',[\s]*', TAB_COMMA_SPLIT, self._CurrentLine)
+ for Item in Line[1:-1].split(TAB_COMMA_SPLIT):
+ if Item == '':
+ EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR,
+ "section name can NOT be empty or incorrectly use separator comma",
+ self.MetaFile, self._LineIndex + 1, self._CurrentLine)
+ ItemList = Item.split(TAB_SPLIT)
+
+ # different types of PCD are permissible in one section
+ self._SectionName = ItemList[0].upper()
+ if self._SectionName == TAB_DEC_DEFINES.upper() and (len(ItemList) > 1 or len(Line.split(TAB_COMMA_SPLIT)) > 1):
+ EdkLogger.error("Parser", FORMAT_INVALID, "Defines section format is invalid",
+ self.MetaFile, self._LineIndex + 1, self._CurrentLine)
+ if self._SectionName in self.DataType:
+ if self.DataType[self._SectionName] not in self._SectionType:
+ self._SectionType.append(self.DataType[self._SectionName])
+ else:
+ EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
+ self.MetaFile, self._LineIndex + 1, self._CurrentLine)
+
+ if MODEL_PCD_FEATURE_FLAG in self._SectionType and len(self._SectionType) > 1:
+ EdkLogger.error(
+ 'Parser',
+ FORMAT_INVALID,
+ "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL,
+ File=self.MetaFile,
+ Line=self._LineIndex + 1,
+ ExtraData=self._CurrentLine
+ )
+ # S1 is always Arch
+ if len(ItemList) > 1:
+ S1 = ItemList[1].upper()
+ else:
+ S1 = TAB_ARCH_COMMON
+ ArchList.add(S1)
+ # S2 may be Platform or ModuleType
+ if len(ItemList) > 2:
+ S2 = ItemList[2].upper()
+ # only Includes, GUIDs, PPIs, Protocols section have Private tag
+ if self._SectionName in [TAB_INCLUDES.upper(), TAB_GUIDS.upper(), TAB_PROTOCOLS.upper(), TAB_PPIS.upper()]:
+ if S2 != 'PRIVATE':
+ EdkLogger.error("Parser", FORMAT_INVALID, 'Please use keyword "Private" as section tag modifier.',
+ File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
+ else:
+ S2 = TAB_COMMON
+ PrivateList.add(S2)
+ if [S1, S2, self.DataType[self._SectionName]] not in self._Scope:
+ self._Scope.append([S1, S2, self.DataType[self._SectionName]])
+
+ # 'COMMON' must not be used with specific ARCHs at the same section
+ if TAB_ARCH_COMMON in ArchList and len(ArchList) > 1:
+ EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
+ File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
+
+ # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
+ if TAB_COMMON in PrivateList and len(PrivateList) > 1:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
+ File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
+
+ ## [guids], [ppis] and [protocols] section parser
+ @ParseMacro
+ def _GuidParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+ if len(TokenList) < 2:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name or value specified",
+ ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ if TokenList[0] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name specified",
+ ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ if TokenList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No GUID value specified",
+ ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidStructureStringToGuidString(TokenList[1]) == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid GUID value format",
+ ExtraData=self._CurrentLine + \
+ " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ self._ValueList[0] = TokenList[0]
+ self._ValueList[1] = TokenList[1]
+ if self._ValueList[0] not in self._GuidDict:
+ self._GuidDict[self._ValueList[0]] = self._ValueList[1]
+
+ def ParsePcdName(self,namelist):
+ if "[" in namelist[1]:
+ pcdname = namelist[1][:namelist[1].index("[")]
+ arrayindex = namelist[1][namelist[1].index("["):]
+ namelist[1] = pcdname
+ if len(namelist) == 2:
+ namelist.append(arrayindex)
+ else:
+ namelist[2] = ".".join((arrayindex,namelist[2]))
+ return namelist
+
+ ## PCD sections parser
+ #
+ # [PcdsFixedAtBuild]
+ # [PcdsPatchableInModule]
+ # [PcdsFeatureFlag]
+ # [PcdsDynamicEx
+ # [PcdsDynamic]
+ #
+ @ParseMacro
+ def _PcdParser(self):
+
+ if self._CurrentStructurePcdName:
+ self._ValueList[0] = self._CurrentStructurePcdName
+
+ if "|" not in self._CurrentLine:
+ if "<HeaderFiles>" == self._CurrentLine:
+ self._include_flag = True
+ self._package_flag = False
+ self._ValueList = None
+ return
+ if "<Packages>" == self._CurrentLine:
+ self._package_flag = True
+ self._ValueList = None
+ self._include_flag = False
+ return
+
+ if self._include_flag:
+ self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
+ self._ValueList[2] = self._CurrentLine
+ if self._package_flag and "}" != self._CurrentLine:
+ self._ValueList[1] = "<Packages>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()
+ self._ValueList[2] = self._CurrentLine
+ if self._CurrentLine == "}":
+ self._package_flag = False
+ self._include_flag = False
+ self._ValueList = None
+ return
+ else:
+ PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)
+ PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT))
+ if len(PcdNames) == 2:
+ if PcdNames[1].strip().endswith("]"):
+ PcdName = PcdNames[1][:PcdNames[1].index('[')]
+ Index = PcdNames[1][PcdNames[1].index('['):]
+ self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName))
+ self._ValueList[1] = Index
+ self._ValueList[2] = PcdTockens[1]
+ else:
+ self._CurrentStructurePcdName = ""
+ else:
+ if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]):
+ EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])),
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ self._ValueList[1] = TAB_SPLIT.join(PcdNames[2:])
+ self._ValueList[2] = PcdTockens[1]
+ if not self._CurrentStructurePcdName:
+ if self._PcdDataTypeCODE:
+ if ")}" in self._CurrentLine:
+ ValuePart,RestofValue = self._CurrentLine.split(")}")
+ self._PcdCodeValue = self._PcdCodeValue + "\n " + ValuePart
+ self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue,RestofValue))
+ self._PcdDataTypeCODE = False
+ self._PcdCodeValue = ""
+ else:
+ self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine
+ self._ValueList = None
+ return
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
+ self._CurrentPcdName = TokenList[0]
+ if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"):
+ if ")}" in self._CurrentLine:
+ self._PcdDataTypeCODE = False
+ self._PcdCodeValue = ""
+ else:
+ self._PcdDataTypeCODE = True
+ self._PcdCodeValue = TokenList[1].strip()
+ self._ValueList = None
+ return
+
+ self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
+ ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')
+ # check PCD information
+ if self._ValueList[0] == '' or self._ValueList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
+ ExtraData=self._CurrentLine + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check format of token space GUID CName
+ if not ValueRe.match(self._ValueList[0]):
+ EdkLogger.error('Parser', FORMAT_INVALID, "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
+ ExtraData=self._CurrentLine + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check format of PCD CName
+ if not ValueRe.match(self._ValueList[1]):
+ EdkLogger.error('Parser', FORMAT_INVALID, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
+ ExtraData=self._CurrentLine + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check PCD datum information
+ if len(TokenList) < 2 or TokenList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",
+ ExtraData=self._CurrentLine + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+
+
+ ValueRe = re.compile(r'^\s*L?\".*\|.*\"')
+ PtrValue = ValueRe.findall(TokenList[1])
+
+ # Has VOID* type string, may contain "|" character in the string.
+ if len(PtrValue) != 0:
+ ptrValueList = re.sub(ValueRe, '', TokenList[1])
+ ValueList = AnalyzePcdExpression(ptrValueList)
+ ValueList[0] = PtrValue[0]
+ else:
+ ValueList = AnalyzePcdExpression(TokenList[1])
+
+
+ # check if there's enough datum information given
+ if len(ValueList) != 3:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",
+ ExtraData=self._CurrentLine + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check default value
+ if ValueList[0] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",
+ ExtraData=self._CurrentLine + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check datum type
+ if ValueList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",
+ ExtraData=self._CurrentLine + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check token of the PCD
+ if ValueList[2] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",
+ ExtraData=self._CurrentLine + \
+ " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+
+ PcdValue = ValueList[0]
+ if PcdValue:
+ try:
+ self._GuidDict.update(self._AllPcdDict)
+ ValueList[0] = ValueExpressionEx(ValueList[0], ValueList[1], self._GuidDict)(True)
+ except BadExpression as Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, Value, ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ # check format of default value against the datum type
+ IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])
+ if not IsValid:
+ EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,
+ File=self.MetaFile, Line=self._LineIndex + 1)
+
+ if Cause == "StructurePcd":
+ self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2])
+ self._ValueList[0] = self._CurrentStructurePcdName
+ self._ValueList[1] = ValueList[1].strip()
+
+ if ValueList[0] in ['True', 'true', 'TRUE']:
+ ValueList[0] = '1'
+ elif ValueList[0] in ['False', 'false', 'FALSE']:
+ ValueList[0] = '0'
+
+ # check for duplicate PCD definition
+ if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "The same PCD name and GUID have been already defined",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ else:
+ self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))
+ self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]
+
+ self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()
+
+ _SectionParser = {
+ MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,
+ MODEL_EFI_INCLUDE : MetaFileParser._PathParser,
+ MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,
+ MODEL_EFI_GUID : _GuidParser,
+ MODEL_EFI_PPI : _GuidParser,
+ MODEL_EFI_PROTOCOL : _GuidParser,
+ MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
+ MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
+ MODEL_PCD_FEATURE_FLAG : _PcdParser,
+ MODEL_PCD_DYNAMIC : _PcdParser,
+ MODEL_PCD_DYNAMIC_EX : _PcdParser,
+ MODEL_UNKNOWN : MetaFileParser._Skip,
+ MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
+ }
+
+##
+#
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+#
+if __name__ == '__main__':
+ pass
+
diff --git a/BaseTools/Source/Python/Workspace/MetaFileTable.py b/BaseTools/Source/Python/Workspace/MetaFileTable.py
index bebf9062e8..7635d89332 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileTable.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileTable.py
@@ -1,430 +1,430 @@
-## @file
-# This file is used to create/update/query/erase a meta file table
-#
-# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-import uuid
-
-import Common.EdkLogger as EdkLogger
-from Common.BuildToolError import FORMAT_INVALID
-
-from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \
- MODEL_FILE_OTHERS
-from Common.DataType import *
-
-class MetaFileTable():
- # TRICK: use file ID as the part before '.'
- _ID_STEP_ = 1
- _ID_MAX_ = 99999999
-
- ## Constructor
- def __init__(self, DB, MetaFile, FileType, Temporary, FromItem=None):
- self.MetaFile = MetaFile
- self.TableName = ""
- self.DB = DB
- self._NumpyTab = None
-
- self.CurrentContent = []
- DB.TblFile.append([MetaFile.Name,
- MetaFile.Ext,
- MetaFile.Dir,
- MetaFile.Path,
- FileType,
- MetaFile.TimeStamp,
- FromItem])
- self.FileId = len(DB.TblFile)
- self.ID = self.FileId * 10**8
- if Temporary:
- self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex)
- else:
- self.TableName = "_%s_%s" % (FileType, len(DB.TblFile))
-
- def IsIntegrity(self):
- Result = False
- try:
- TimeStamp = self.MetaFile.TimeStamp
- if not self.CurrentContent:
- Result = False
- else:
- Result = self.CurrentContent[-1][0] < 0
- except Exception as Exc:
- EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))
- return False
- return Result
-
- def SetEndFlag(self):
- self.CurrentContent.append(self._DUMMY_)
-
- def GetAll(self):
- return [item for item in self.CurrentContent if item[0] >= 0 and item[-1]>=0]
-
-## Python class representation of table storing module data
-class ModuleTable(MetaFileTable):
- _COLUMN_ = '''
- ID REAL PRIMARY KEY,
- Model INTEGER NOT NULL,
- Value1 TEXT NOT NULL,
- Value2 TEXT,
- Value3 TEXT,
- Scope1 TEXT,
- Scope2 TEXT,
- BelongsToItem REAL NOT NULL,
- StartLine INTEGER NOT NULL,
- StartColumn INTEGER NOT NULL,
- EndLine INTEGER NOT NULL,
- EndColumn INTEGER NOT NULL,
- Enabled INTEGER DEFAULT 0
- '''
- # used as table end flag, in case the changes to database is not committed to db file
- _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
-
- ## Constructor
- def __init__(self, Db, MetaFile, Temporary):
- MetaFileTable.__init__(self, Db, MetaFile, MODEL_FILE_INF, Temporary)
-
- ## Insert a record into table Inf
- #
- # @param Model: Model of a Inf item
- # @param Value1: Value1 of a Inf item
- # @param Value2: Value2 of a Inf item
- # @param Value3: Value3 of a Inf item
- # @param Scope1: Arch of a Inf item
- # @param Scope2 Platform os a Inf item
- # @param BelongsToItem: The item belongs to which another item
- # @param StartLine: StartLine of a Inf item
- # @param StartColumn: StartColumn of a Inf item
- # @param EndLine: EndLine of a Inf item
- # @param EndColumn: EndColumn of a Inf item
- # @param Enabled: If this item enabled
- #
- def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,
- BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
-
- (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())
- self.ID = self.ID + self._ID_STEP_
- if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):
- self.ID = MODEL_FILE_INF + self._ID_STEP_
-
- row = [ self.ID,
- Model,
- Value1,
- Value2,
- Value3,
- Scope1,
- Scope2,
- BelongsToItem,
- StartLine,
- StartColumn,
- EndLine,
- EndColumn,
- Enabled
- ]
- self.CurrentContent.append(row)
- return self.ID
-
- ## Query table
- #
- # @param Model: The Model of Record
- # @param Arch: The Arch attribute of Record
- # @param Platform The Platform attribute of Record
- #
- # @retval: A recordSet of all found records
- #
- def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):
-
- QueryTab = self.CurrentContent
- result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]
-
- if Arch is not None and Arch != TAB_ARCH_COMMON:
- ArchList = set(['COMMON'])
- ArchList.add(Arch)
- result = [item for item in result if item[5] in ArchList]
-
- if Platform is not None and Platform != TAB_COMMON:
- Platformlist = set( ['COMMON','DEFAULT'])
- Platformlist.add(Platform)
- result = [item for item in result if item[6] in Platformlist]
-
- if BelongsToItem is not None:
- result = [item for item in result if item[7] == BelongsToItem]
-
- result = [ [r[2],r[3],r[4],r[5],r[6],r[0],r[8]] for r in result ]
- return result
-
-## Python class representation of table storing package data
-class PackageTable(MetaFileTable):
- _COLUMN_ = '''
- ID REAL PRIMARY KEY,
- Model INTEGER NOT NULL,
- Value1 TEXT NOT NULL,
- Value2 TEXT,
- Value3 TEXT,
- Scope1 TEXT,
- Scope2 TEXT,
- BelongsToItem REAL NOT NULL,
- StartLine INTEGER NOT NULL,
- StartColumn INTEGER NOT NULL,
- EndLine INTEGER NOT NULL,
- EndColumn INTEGER NOT NULL,
- Enabled INTEGER DEFAULT 0
- '''
- # used as table end flag, in case the changes to database is not committed to db file
- _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
-
- ## Constructor
- def __init__(self, Cursor, MetaFile, Temporary):
- MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)
-
- ## Insert table
- #
- # Insert a record into table Dec
- #
- # @param Model: Model of a Dec item
- # @param Value1: Value1 of a Dec item
- # @param Value2: Value2 of a Dec item
- # @param Value3: Value3 of a Dec item
- # @param Scope1: Arch of a Dec item
- # @param Scope2: Module type of a Dec item
- # @param BelongsToItem: The item belongs to which another item
- # @param StartLine: StartLine of a Dec item
- # @param StartColumn: StartColumn of a Dec item
- # @param EndLine: EndLine of a Dec item
- # @param EndColumn: EndColumn of a Dec item
- # @param Enabled: If this item enabled
- #
- def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,
- BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
- (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())
- self.ID = self.ID + self._ID_STEP_
-
- row = [ self.ID,
- Model,
- Value1,
- Value2,
- Value3,
- Scope1,
- Scope2,
- BelongsToItem,
- StartLine,
- StartColumn,
- EndLine,
- EndColumn,
- Enabled
- ]
- self.CurrentContent.append(row)
- return self.ID
-
- ## Query table
- #
- # @param Model: The Model of Record
- # @param Arch: The Arch attribute of Record
- #
- # @retval: A recordSet of all found records
- #
- def Query(self, Model, Arch=None):
-
- QueryTab = self.CurrentContent
- result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]
-
- if Arch is not None and Arch != TAB_ARCH_COMMON:
- ArchList = set(['COMMON'])
- ArchList.add(Arch)
- result = [item for item in result if item[5] in ArchList]
-
- return [[r[2], r[3], r[4], r[5], r[6], r[0], r[8]] for r in result]
-
- def GetValidExpression(self, TokenSpaceGuid, PcdCName):
-
- QueryTab = self.CurrentContent
- result = [[item[2], item[8]] for item in QueryTab if item[3] == TokenSpaceGuid and item[4] == PcdCName]
- validateranges = []
- validlists = []
- expressions = []
- try:
- for row in result:
- comment = row[0]
-
- LineNum = row[1]
- comment = comment.strip("#")
- comment = comment.strip()
- oricomment = comment
- if comment.startswith("@ValidRange"):
- comment = comment.replace("@ValidRange", "", 1)
- validateranges.append(comment.split("|")[1].strip())
- if comment.startswith("@ValidList"):
- comment = comment.replace("@ValidList", "", 1)
- validlists.append(comment.split("|")[1].strip())
- if comment.startswith("@Expression"):
- comment = comment.replace("@Expression", "", 1)
- expressions.append(comment.split("|")[1].strip())
- except Exception as Exc:
- ValidType = ""
- if oricomment.startswith("@ValidRange"):
- ValidType = "@ValidRange"
- if oricomment.startswith("@ValidList"):
- ValidType = "@ValidList"
- if oricomment.startswith("@Expression"):
- ValidType = "@Expression"
- EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType, TokenSpaceGuid, PcdCName),
- ExtraData=oricomment, File=self.MetaFile, Line=LineNum)
- return set(), set(), set()
- return set(validateranges), set(validlists), set(expressions)
-
-## Python class representation of table storing platform data
-class PlatformTable(MetaFileTable):
- _COLUMN_ = '''
- ID REAL PRIMARY KEY,
- Model INTEGER NOT NULL,
- Value1 TEXT NOT NULL,
- Value2 TEXT,
- Value3 TEXT,
- Scope1 TEXT,
- Scope2 TEXT,
- Scope3 TEXT,
- BelongsToItem REAL NOT NULL,
- FromItem REAL NOT NULL,
- StartLine INTEGER NOT NULL,
- StartColumn INTEGER NOT NULL,
- EndLine INTEGER NOT NULL,
- EndColumn INTEGER NOT NULL,
- Enabled INTEGER DEFAULT 0
- '''
- # used as table end flag, in case the changes to database is not committed to db file
- _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]
-
- ## Constructor
- def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):
- MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)
-
- ## Insert table
- #
- # Insert a record into table Dsc
- #
- # @param Model: Model of a Dsc item
- # @param Value1: Value1 of a Dsc item
- # @param Value2: Value2 of a Dsc item
- # @param Value3: Value3 of a Dsc item
- # @param Scope1: Arch of a Dsc item
- # @param Scope2: Module type of a Dsc item
- # @param BelongsToItem: The item belongs to which another item
- # @param FromItem: The item belongs to which dsc file
- # @param StartLine: StartLine of a Dsc item
- # @param StartColumn: StartColumn of a Dsc item
- # @param EndLine: EndLine of a Dsc item
- # @param EndColumn: EndColumn of a Dsc item
- # @param Enabled: If this item enabled
- #
- def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,
- FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):
- (Value1, Value2, Value3, Scope1, Scope2, Scope3) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip(), Scope3.strip())
- self.ID = self.ID + self._ID_STEP_
-
- row = [ self.ID,
- Model,
- Value1,
- Value2,
- Value3,
- Scope1,
- Scope2,
- Scope3,
- BelongsToItem,
- FromItem,
- StartLine,
- StartColumn,
- EndLine,
- EndColumn,
- Enabled
- ]
- self.CurrentContent.append(row)
- return self.ID
-
-
- ## Query table
- #
- # @param Model: The Model of Record
- # @param Scope1: Arch of a Dsc item
- # @param Scope2: Module type of a Dsc item
- # @param BelongsToItem: The item belongs to which another item
- # @param FromItem: The item belongs to which dsc file
- #
- # @retval: A recordSet of all found records
- #
- def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):
-
- QueryTab = self.CurrentContent
- result = [item for item in QueryTab if item[1] == Model and item[-1]>0 ]
- if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:
- Sc1 = set(['COMMON'])
- Sc1.add(Scope1)
- result = [item for item in result if item[5] in Sc1]
- Sc2 = set( ['COMMON','DEFAULT'])
- if Scope2 and Scope2 != TAB_COMMON:
- if '.' in Scope2:
- Index = Scope2.index('.')
- NewScope = TAB_COMMON + Scope2[Index:]
- Sc2.add(NewScope)
- Sc2.add(Scope2)
- result = [item for item in result if item[6] in Sc2]
-
- if BelongsToItem is not None:
- result = [item for item in result if item[8] == BelongsToItem]
- else:
- result = [item for item in result if item[8] < 0]
- if FromItem is not None:
- result = [item for item in result if item[9] == FromItem]
-
- result = [ [r[2],r[3],r[4],r[5],r[6],r[7],r[0],r[10]] for r in result ]
- return result
-
- def DisableComponent(self,comp_id):
- for item in self.CurrentContent:
- if item[0] == comp_id or item[8] == comp_id:
- item[-1] = -1
-
-## Factory class to produce different storage for different type of meta-file
-class MetaFileStorage(object):
- _FILE_TABLE_ = {
- MODEL_FILE_INF : ModuleTable,
- MODEL_FILE_DEC : PackageTable,
- MODEL_FILE_DSC : PlatformTable,
- MODEL_FILE_OTHERS : MetaFileTable,
- }
-
- _FILE_TYPE_ = {
- ".inf" : MODEL_FILE_INF,
- ".dec" : MODEL_FILE_DEC,
- ".dsc" : MODEL_FILE_DSC,
- }
- _ObjectCache = {}
- ## Constructor
- def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):
- # no type given, try to find one
- key = (MetaFile.Path, FileType,Temporary,FromItem)
- if key in Class._ObjectCache:
- return Class._ObjectCache[key]
- if not FileType:
- if MetaFile.Type in self._FILE_TYPE_:
- FileType = Class._FILE_TYPE_[MetaFile.Type]
- else:
- FileType = MODEL_FILE_OTHERS
-
- # don't pass the type around if it's well known
- if FileType == MODEL_FILE_OTHERS:
- Args = (Cursor, MetaFile, FileType, Temporary)
- else:
- Args = (Cursor, MetaFile, Temporary)
- if FromItem:
- Args = Args + (FromItem,)
-
- # create the storage object and return it to caller
- reval = Class._FILE_TABLE_[FileType](*Args)
- if not Temporary:
- Class._ObjectCache[key] = reval
- return reval
-
+## @file
+# This file is used to create/update/query/erase a meta file table
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+##
+# Import Modules
+#
+from __future__ import absolute_import
+import uuid
+
+import Common.EdkLogger as EdkLogger
+from Common.BuildToolError import FORMAT_INVALID
+
+from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \
+ MODEL_FILE_OTHERS
+from Common.DataType import *
+
+class MetaFileTable():
+ # TRICK: use file ID as the part before '.'
+ _ID_STEP_ = 1
+ _ID_MAX_ = 99999999
+
+ ## Constructor
+ def __init__(self, DB, MetaFile, FileType, Temporary, FromItem=None):
+ self.MetaFile = MetaFile
+ self.TableName = ""
+ self.DB = DB
+ self._NumpyTab = None
+
+ self.CurrentContent = []
+ DB.TblFile.append([MetaFile.Name,
+ MetaFile.Ext,
+ MetaFile.Dir,
+ MetaFile.Path,
+ FileType,
+ MetaFile.TimeStamp,
+ FromItem])
+ self.FileId = len(DB.TblFile)
+ self.ID = self.FileId * 10**8
+ if Temporary:
+ self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex)
+ else:
+ self.TableName = "_%s_%s" % (FileType, len(DB.TblFile))
+
+ def IsIntegrity(self):
+ Result = False
+ try:
+ TimeStamp = self.MetaFile.TimeStamp
+ if not self.CurrentContent:
+ Result = False
+ else:
+ Result = self.CurrentContent[-1][0] < 0
+ except Exception as Exc:
+ EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))
+ return False
+ return Result
+
+ def SetEndFlag(self):
+ self.CurrentContent.append(self._DUMMY_)
+
+ def GetAll(self):
+ return [item for item in self.CurrentContent if item[0] >= 0 and item[-1]>=0]
+
+## Python class representation of table storing module data
+class ModuleTable(MetaFileTable):
+ _COLUMN_ = '''
+ ID REAL PRIMARY KEY,
+ Model INTEGER NOT NULL,
+ Value1 TEXT NOT NULL,
+ Value2 TEXT,
+ Value3 TEXT,
+ Scope1 TEXT,
+ Scope2 TEXT,
+ BelongsToItem REAL NOT NULL,
+ StartLine INTEGER NOT NULL,
+ StartColumn INTEGER NOT NULL,
+ EndLine INTEGER NOT NULL,
+ EndColumn INTEGER NOT NULL,
+ Enabled INTEGER DEFAULT 0
+ '''
+ # used as table end flag, in case the changes to database is not committed to db file
+ _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
+
+ ## Constructor
+ def __init__(self, Db, MetaFile, Temporary):
+ MetaFileTable.__init__(self, Db, MetaFile, MODEL_FILE_INF, Temporary)
+
+ ## Insert a record into table Inf
+ #
+ # @param Model: Model of a Inf item
+ # @param Value1: Value1 of a Inf item
+ # @param Value2: Value2 of a Inf item
+ # @param Value3: Value3 of a Inf item
+ # @param Scope1: Arch of a Inf item
+ # @param Scope2 Platform os a Inf item
+ # @param BelongsToItem: The item belongs to which another item
+ # @param StartLine: StartLine of a Inf item
+ # @param StartColumn: StartColumn of a Inf item
+ # @param EndLine: EndLine of a Inf item
+ # @param EndColumn: EndColumn of a Inf item
+ # @param Enabled: If this item enabled
+ #
+ def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,
+ BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
+
+ (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())
+ self.ID = self.ID + self._ID_STEP_
+ if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):
+ self.ID = MODEL_FILE_INF + self._ID_STEP_
+
+ row = [ self.ID,
+ Model,
+ Value1,
+ Value2,
+ Value3,
+ Scope1,
+ Scope2,
+ BelongsToItem,
+ StartLine,
+ StartColumn,
+ EndLine,
+ EndColumn,
+ Enabled
+ ]
+ self.CurrentContent.append(row)
+ return self.ID
+
+ ## Query table
+ #
+ # @param Model: The Model of Record
+ # @param Arch: The Arch attribute of Record
+ # @param Platform The Platform attribute of Record
+ #
+ # @retval: A recordSet of all found records
+ #
+ def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):
+
+ QueryTab = self.CurrentContent
+ result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]
+
+ if Arch is not None and Arch != TAB_ARCH_COMMON:
+ ArchList = set(['COMMON'])
+ ArchList.add(Arch)
+ result = [item for item in result if item[5] in ArchList]
+
+ if Platform is not None and Platform != TAB_COMMON:
+ Platformlist = set( ['COMMON','DEFAULT'])
+ Platformlist.add(Platform)
+ result = [item for item in result if item[6] in Platformlist]
+
+ if BelongsToItem is not None:
+ result = [item for item in result if item[7] == BelongsToItem]
+
+ result = [ [r[2],r[3],r[4],r[5],r[6],r[0],r[8]] for r in result ]
+ return result
+
+## Python class representation of table storing package data
+class PackageTable(MetaFileTable):
+ _COLUMN_ = '''
+ ID REAL PRIMARY KEY,
+ Model INTEGER NOT NULL,
+ Value1 TEXT NOT NULL,
+ Value2 TEXT,
+ Value3 TEXT,
+ Scope1 TEXT,
+ Scope2 TEXT,
+ BelongsToItem REAL NOT NULL,
+ StartLine INTEGER NOT NULL,
+ StartColumn INTEGER NOT NULL,
+ EndLine INTEGER NOT NULL,
+ EndColumn INTEGER NOT NULL,
+ Enabled INTEGER DEFAULT 0
+ '''
+ # used as table end flag, in case the changes to database is not committed to db file
+ _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
+
+ ## Constructor
+ def __init__(self, Cursor, MetaFile, Temporary):
+ MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)
+
+ ## Insert table
+ #
+ # Insert a record into table Dec
+ #
+ # @param Model: Model of a Dec item
+ # @param Value1: Value1 of a Dec item
+ # @param Value2: Value2 of a Dec item
+ # @param Value3: Value3 of a Dec item
+ # @param Scope1: Arch of a Dec item
+ # @param Scope2: Module type of a Dec item
+ # @param BelongsToItem: The item belongs to which another item
+ # @param StartLine: StartLine of a Dec item
+ # @param StartColumn: StartColumn of a Dec item
+ # @param EndLine: EndLine of a Dec item
+ # @param EndColumn: EndColumn of a Dec item
+ # @param Enabled: If this item enabled
+ #
+ def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,
+ BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
+ (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())
+ self.ID = self.ID + self._ID_STEP_
+
+ row = [ self.ID,
+ Model,
+ Value1,
+ Value2,
+ Value3,
+ Scope1,
+ Scope2,
+ BelongsToItem,
+ StartLine,
+ StartColumn,
+ EndLine,
+ EndColumn,
+ Enabled
+ ]
+ self.CurrentContent.append(row)
+ return self.ID
+
+ ## Query table
+ #
+ # @param Model: The Model of Record
+ # @param Arch: The Arch attribute of Record
+ #
+ # @retval: A recordSet of all found records
+ #
+ def Query(self, Model, Arch=None):
+
+ QueryTab = self.CurrentContent
+ result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]
+
+ if Arch is not None and Arch != TAB_ARCH_COMMON:
+ ArchList = set(['COMMON'])
+ ArchList.add(Arch)
+ result = [item for item in result if item[5] in ArchList]
+
+ return [[r[2], r[3], r[4], r[5], r[6], r[0], r[8]] for r in result]
+
+ def GetValidExpression(self, TokenSpaceGuid, PcdCName):
+
+ QueryTab = self.CurrentContent
+ result = [[item[2], item[8]] for item in QueryTab if item[3] == TokenSpaceGuid and item[4] == PcdCName]
+ validateranges = []
+ validlists = []
+ expressions = []
+ try:
+ for row in result:
+ comment = row[0]
+
+ LineNum = row[1]
+ comment = comment.strip("#")
+ comment = comment.strip()
+ oricomment = comment
+ if comment.startswith("@ValidRange"):
+ comment = comment.replace("@ValidRange", "", 1)
+ validateranges.append(comment.split("|")[1].strip())
+ if comment.startswith("@ValidList"):
+ comment = comment.replace("@ValidList", "", 1)
+ validlists.append(comment.split("|")[1].strip())
+ if comment.startswith("@Expression"):
+ comment = comment.replace("@Expression", "", 1)
+ expressions.append(comment.split("|")[1].strip())
+ except Exception as Exc:
+ ValidType = ""
+ if oricomment.startswith("@ValidRange"):
+ ValidType = "@ValidRange"
+ if oricomment.startswith("@ValidList"):
+ ValidType = "@ValidList"
+ if oricomment.startswith("@Expression"):
+ ValidType = "@Expression"
+ EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType, TokenSpaceGuid, PcdCName),
+ ExtraData=oricomment, File=self.MetaFile, Line=LineNum)
+ return set(), set(), set()
+ return set(validateranges), set(validlists), set(expressions)
+
+## Python class representation of table storing platform data
+class PlatformTable(MetaFileTable):
+ _COLUMN_ = '''
+ ID REAL PRIMARY KEY,
+ Model INTEGER NOT NULL,
+ Value1 TEXT NOT NULL,
+ Value2 TEXT,
+ Value3 TEXT,
+ Scope1 TEXT,
+ Scope2 TEXT,
+ Scope3 TEXT,
+ BelongsToItem REAL NOT NULL,
+ FromItem REAL NOT NULL,
+ StartLine INTEGER NOT NULL,
+ StartColumn INTEGER NOT NULL,
+ EndLine INTEGER NOT NULL,
+ EndColumn INTEGER NOT NULL,
+ Enabled INTEGER DEFAULT 0
+ '''
+ # used as table end flag, in case the changes to database is not committed to db file
+ _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]
+
+ ## Constructor
+ def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):
+ MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)
+
+ ## Insert table
+ #
+ # Insert a record into table Dsc
+ #
+ # @param Model: Model of a Dsc item
+ # @param Value1: Value1 of a Dsc item
+ # @param Value2: Value2 of a Dsc item
+ # @param Value3: Value3 of a Dsc item
+ # @param Scope1: Arch of a Dsc item
+ # @param Scope2: Module type of a Dsc item
+ # @param BelongsToItem: The item belongs to which another item
+ # @param FromItem: The item belongs to which dsc file
+ # @param StartLine: StartLine of a Dsc item
+ # @param StartColumn: StartColumn of a Dsc item
+ # @param EndLine: EndLine of a Dsc item
+ # @param EndColumn: EndColumn of a Dsc item
+ # @param Enabled: If this item enabled
+ #
+ def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,
+ FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):
+ (Value1, Value2, Value3, Scope1, Scope2, Scope3) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip(), Scope3.strip())
+ self.ID = self.ID + self._ID_STEP_
+
+ row = [ self.ID,
+ Model,
+ Value1,
+ Value2,
+ Value3,
+ Scope1,
+ Scope2,
+ Scope3,
+ BelongsToItem,
+ FromItem,
+ StartLine,
+ StartColumn,
+ EndLine,
+ EndColumn,
+ Enabled
+ ]
+ self.CurrentContent.append(row)
+ return self.ID
+
+
+ ## Query table
+ #
+ # @param Model: The Model of Record
+ # @param Scope1: Arch of a Dsc item
+ # @param Scope2: Module type of a Dsc item
+ # @param BelongsToItem: The item belongs to which another item
+ # @param FromItem: The item belongs to which dsc file
+ #
+ # @retval: A recordSet of all found records
+ #
+ def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):
+
+ QueryTab = self.CurrentContent
+ result = [item for item in QueryTab if item[1] == Model and item[-1]>0 ]
+ if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:
+ Sc1 = set(['COMMON'])
+ Sc1.add(Scope1)
+ result = [item for item in result if item[5] in Sc1]
+ Sc2 = set( ['COMMON','DEFAULT'])
+ if Scope2 and Scope2 != TAB_COMMON:
+ if '.' in Scope2:
+ Index = Scope2.index('.')
+ NewScope = TAB_COMMON + Scope2[Index:]
+ Sc2.add(NewScope)
+ Sc2.add(Scope2)
+ result = [item for item in result if item[6] in Sc2]
+
+ if BelongsToItem is not None:
+ result = [item for item in result if item[8] == BelongsToItem]
+ else:
+ result = [item for item in result if item[8] < 0]
+ if FromItem is not None:
+ result = [item for item in result if item[9] == FromItem]
+
+ result = [ [r[2],r[3],r[4],r[5],r[6],r[7],r[0],r[10]] for r in result ]
+ return result
+
+ def DisableComponent(self,comp_id):
+ for item in self.CurrentContent:
+ if item[0] == comp_id or item[8] == comp_id:
+ item[-1] = -1
+
+## Factory class to produce different storage for different type of meta-file
+class MetaFileStorage(object):
+ _FILE_TABLE_ = {
+ MODEL_FILE_INF : ModuleTable,
+ MODEL_FILE_DEC : PackageTable,
+ MODEL_FILE_DSC : PlatformTable,
+ MODEL_FILE_OTHERS : MetaFileTable,
+ }
+
+ _FILE_TYPE_ = {
+ ".inf" : MODEL_FILE_INF,
+ ".dec" : MODEL_FILE_DEC,
+ ".dsc" : MODEL_FILE_DSC,
+ }
+ _ObjectCache = {}
+ ## Constructor
+ def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):
+ # no type given, try to find one
+ key = (MetaFile.Path, FileType,Temporary,FromItem)
+ if key in Class._ObjectCache:
+ return Class._ObjectCache[key]
+ if not FileType:
+ if MetaFile.Type in self._FILE_TYPE_:
+ FileType = Class._FILE_TYPE_[MetaFile.Type]
+ else:
+ FileType = MODEL_FILE_OTHERS
+
+ # don't pass the type around if it's well known
+ if FileType == MODEL_FILE_OTHERS:
+ Args = (Cursor, MetaFile, FileType, Temporary)
+ else:
+ Args = (Cursor, MetaFile, Temporary)
+ if FromItem:
+ Args = Args + (FromItem,)
+
+ # create the storage object and return it to caller
+ reval = Class._FILE_TABLE_[FileType](*Args)
+ if not Temporary:
+ Class._ObjectCache[key] = reval
+ return reval
+
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
index 6ad7a3b940..e6fc44fc35 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
@@ -1,260 +1,260 @@
-## @file
-# Common routines used by workspace
-#
-# Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-from __future__ import absolute_import
-from collections import OrderedDict, defaultdict
-from Common.DataType import SUP_MODULE_USER_DEFINED
-from Common.DataType import SUP_MODULE_HOST_APPLICATION
-from .BuildClassObject import LibraryClassObject
-import Common.GlobalData as GlobalData
-from Workspace.BuildClassObject import StructurePcd
-from Common.BuildToolError import RESOURCE_NOT_AVAILABLE
-from Common.BuildToolError import OPTION_MISSING
-from Common.BuildToolError import BUILD_ERROR
-import Common.EdkLogger as EdkLogger
-
-class OrderedListDict(OrderedDict):
- def __init__(self, *args, **kwargs):
- super(OrderedListDict, self).__init__(*args, **kwargs)
- self.default_factory = list
-
- def __missing__(self, key):
- self[key] = Value = self.default_factory()
- return Value
-
-## Get all packages from platform for specified arch, target and toolchain
-#
-# @param Platform: DscBuildData instance
-# @param BuildDatabase: The database saves all data for all metafiles
-# @param Arch: Current arch
-# @param Target: Current target
-# @param Toolchain: Current toolchain
-# @retval: List of packages which are DecBuildData instances
-#
-def GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain):
- PkgSet = set()
- if Platform.Packages:
- PkgSet.update(Platform.Packages)
- for ModuleFile in Platform.Modules:
- Data = BuildDatabase[ModuleFile, Arch, Target, Toolchain]
- PkgSet.update(Data.Packages)
- for Lib in GetLiabraryInstances(Data, Platform, BuildDatabase, Arch, Target, Toolchain):
- PkgSet.update(Lib.Packages)
- return list(PkgSet)
-
-## Get all declared PCD from platform for specified arch, target and toolchain
-#
-# @param Platform: DscBuildData instance
-# @param BuildDatabase: The database saves all data for all metafiles
-# @param Arch: Current arch
-# @param Target: Current target
-# @param Toolchain: Current toolchain
-# @retval: A dictionary contains instances of PcdClassObject with key (PcdCName, TokenSpaceGuid)
-# @retval: A dictionary contains real GUIDs of TokenSpaceGuid
-#
-def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain, additionalPkgs):
- PkgList = GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain)
- PkgList = set(PkgList)
- PkgList |= additionalPkgs
- DecPcds = {}
- GuidDict = {}
- for Pkg in PkgList:
- Guids = Pkg.Guids
- GuidDict.update(Guids)
- for Pcd in Pkg.Pcds:
- PcdCName = Pcd[0]
- PcdTokenName = Pcd[1]
- if GlobalData.MixedPcd:
- for PcdItem in GlobalData.MixedPcd:
- if (PcdCName, PcdTokenName) in GlobalData.MixedPcd[PcdItem]:
- PcdCName = PcdItem[0]
- break
- if (PcdCName, PcdTokenName) not in DecPcds:
- DecPcds[PcdCName, PcdTokenName] = Pkg.Pcds[Pcd]
- return DecPcds, GuidDict
-
-## Get all dependent libraries for a module
-#
-# @param Module: InfBuildData instance
-# @param Platform: DscBuildData instance
-# @param BuildDatabase: The database saves all data for all metafiles
-# @param Arch: Current arch
-# @param Target: Current target
-# @param Toolchain: Current toolchain
-# @retval: List of dependent libraries which are InfBuildData instances
-#
-def GetLiabraryInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain):
- return GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain,Platform.MetaFile,EdkLogger)
-
-def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain, FileName = '', EdkLogger = None):
- if Module.LibInstances:
- return Module.LibInstances
- ModuleType = Module.ModuleType
-
- # add forced library instances (specified under LibraryClasses sections)
- #
- # If a module has a MODULE_TYPE of USER_DEFINED,
- # do not link in NULL library class instances from the global [LibraryClasses.*] sections.
- #
- if Module.ModuleType != SUP_MODULE_USER_DEFINED:
- for LibraryClass in Platform.LibraryClasses.GetKeys():
- if LibraryClass.startswith("NULL") and LibraryClass[4:].isdigit() and Platform.LibraryClasses[LibraryClass, Module.ModuleType]:
- Module.LibraryClasses[LibraryClass] = Platform.LibraryClasses[LibraryClass, Module.ModuleType]
-
- # add forced library instances (specified in module overrides)
- for LibraryClass in Platform.Modules[str(Module)].LibraryClasses:
- if LibraryClass.startswith("NULL") and LibraryClass[4:].isdigit():
- Module.LibraryClasses[LibraryClass] = Platform.Modules[str(Module)].LibraryClasses[LibraryClass]
-
- # EdkII module
- LibraryConsumerList = [Module]
- Constructor = []
- ConsumedByList = OrderedListDict()
- LibraryInstance = OrderedDict()
-
- if not Module.LibraryClass:
- EdkLogger.verbose("")
- EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch))
-
- while len(LibraryConsumerList) > 0:
- M = LibraryConsumerList.pop()
- for LibraryClassName in M.LibraryClasses:
- if LibraryClassName.startswith("NULL") and LibraryClassName[4:].isdigit() and bool(M.LibraryClass):
- continue
- if LibraryClassName not in LibraryInstance:
- # override library instance for this module
- LibraryPath = Platform.Modules[str(Module)].LibraryClasses.get(LibraryClassName,Platform.LibraryClasses[LibraryClassName, ModuleType])
- if LibraryPath is None:
- LibraryPath = M.LibraryClasses.get(LibraryClassName)
- if LibraryPath is None:
- if not Module.LibraryClass:
- EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
- "Instance of library class [%s] is not found" % LibraryClassName,
- File=FileName,
- ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), Arch, str(Module)))
- else:
- return []
-
- LibraryModule = BuildDatabase[LibraryPath, Arch, Target, Toolchain]
- # for those forced library instance (NULL library), add a fake library class
- if LibraryClassName.startswith("NULL") and LibraryClassName[4:].isdigit():
- LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
- elif LibraryModule.LibraryClass is None \
- or len(LibraryModule.LibraryClass) == 0 \
- or (ModuleType != SUP_MODULE_USER_DEFINED and ModuleType != SUP_MODULE_HOST_APPLICATION
- and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
- # only USER_DEFINED can link against any library instance despite of its SupModList
- if not Module.LibraryClass:
- EdkLogger.error("build", OPTION_MISSING,
- "Module type [%s] is not supported by library instance [%s]" \
- % (ModuleType, LibraryPath), File=FileName,
- ExtraData="consumed by library instance [%s] which is consumed by module [%s]" \
- % (str(M), str(Module))
- )
- else:
- return []
-
- LibraryInstance[LibraryClassName] = LibraryModule
- LibraryConsumerList.append(LibraryModule)
- if not Module.LibraryClass:
- EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
- else:
- LibraryModule = LibraryInstance[LibraryClassName]
-
- if LibraryModule is None:
- continue
-
- if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
- Constructor.append(LibraryModule)
-
- # don't add current module itself to consumer list
- if M != Module:
- if M in ConsumedByList[LibraryModule]:
- continue
- ConsumedByList[LibraryModule].append(M)
- #
- # Initialize the sorted output list to the empty set
- #
- SortedLibraryList = []
- #
- # Q <- Set of all nodes with no incoming edges
- #
- LibraryList = [] #LibraryInstance.values()
- Q = []
- for LibraryClassName in LibraryInstance:
- M = LibraryInstance[LibraryClassName]
- LibraryList.append(M)
- if not ConsumedByList[M]:
- Q.append(M)
-
- #
- # start the DAG algorithm
- #
- while True:
- EdgeRemoved = True
- while Q == [] and EdgeRemoved:
- EdgeRemoved = False
- # for each node Item with a Constructor
- for Item in LibraryList:
- if Item not in Constructor:
- continue
- # for each Node without a constructor with an edge e from Item to Node
- for Node in ConsumedByList[Item]:
- if Node in Constructor:
- continue
- # remove edge e from the graph if Node has no constructor
- ConsumedByList[Item].remove(Node)
- EdgeRemoved = True
- if not ConsumedByList[Item]:
- # insert Item into Q
- Q.insert(0, Item)
- break
- if Q != []:
- break
- # DAG is done if there's no more incoming edge for all nodes
- if Q == []:
- break
-
- # remove node from Q
- Node = Q.pop()
- # output Node
- SortedLibraryList.append(Node)
-
- # for each node Item with an edge e from Node to Item do
- for Item in LibraryList:
- if Node not in ConsumedByList[Item]:
- continue
- # remove edge e from the graph
- ConsumedByList[Item].remove(Node)
-
- if ConsumedByList[Item]:
- continue
- # insert Item into Q, if Item has no other incoming edges
- Q.insert(0, Item)
-
- #
- # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
- #
- for Item in LibraryList:
- if ConsumedByList[Item] and Item in Constructor and len(Constructor) > 1:
- if not Module.LibraryClass:
- ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join(str(L) for L in ConsumedByList[Item])
- EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
- ExtraData=ErrorMessage, File=FileName)
- else:
- return []
- if Item not in SortedLibraryList:
- SortedLibraryList.append(Item)
-
- #
- # Build the list of constructor and destructor names
- # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
- #
- SortedLibraryList.reverse()
- Module.LibInstances = SortedLibraryList
- SortedLibraryList = [lib.SetReferenceModule(Module) for lib in SortedLibraryList]
- return SortedLibraryList
+## @file
+# Common routines used by workspace
+#
+# Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+from __future__ import absolute_import
+from collections import OrderedDict, defaultdict
+from Common.DataType import SUP_MODULE_USER_DEFINED
+from Common.DataType import SUP_MODULE_HOST_APPLICATION
+from .BuildClassObject import LibraryClassObject
+import Common.GlobalData as GlobalData
+from Workspace.BuildClassObject import StructurePcd
+from Common.BuildToolError import RESOURCE_NOT_AVAILABLE
+from Common.BuildToolError import OPTION_MISSING
+from Common.BuildToolError import BUILD_ERROR
+import Common.EdkLogger as EdkLogger
+
+class OrderedListDict(OrderedDict):
+ def __init__(self, *args, **kwargs):
+ super(OrderedListDict, self).__init__(*args, **kwargs)
+ self.default_factory = list
+
+ def __missing__(self, key):
+ self[key] = Value = self.default_factory()
+ return Value
+
+## Get all packages from platform for specified arch, target and toolchain
+#
+# @param Platform: DscBuildData instance
+# @param BuildDatabase: The database saves all data for all metafiles
+# @param Arch: Current arch
+# @param Target: Current target
+# @param Toolchain: Current toolchain
+# @retval: List of packages which are DecBuildData instances
+#
+def GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain):
+ PkgSet = set()
+ if Platform.Packages:
+ PkgSet.update(Platform.Packages)
+ for ModuleFile in Platform.Modules:
+ Data = BuildDatabase[ModuleFile, Arch, Target, Toolchain]
+ PkgSet.update(Data.Packages)
+ for Lib in GetLiabraryInstances(Data, Platform, BuildDatabase, Arch, Target, Toolchain):
+ PkgSet.update(Lib.Packages)
+ return list(PkgSet)
+
+## Get all declared PCD from platform for specified arch, target and toolchain
+#
+# @param Platform: DscBuildData instance
+# @param BuildDatabase: The database saves all data for all metafiles
+# @param Arch: Current arch
+# @param Target: Current target
+# @param Toolchain: Current toolchain
+# @retval: A dictionary contains instances of PcdClassObject with key (PcdCName, TokenSpaceGuid)
+# @retval: A dictionary contains real GUIDs of TokenSpaceGuid
+#
+def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain, additionalPkgs):
+ PkgList = GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain)
+ PkgList = set(PkgList)
+ PkgList |= additionalPkgs
+ DecPcds = {}
+ GuidDict = {}
+ for Pkg in PkgList:
+ Guids = Pkg.Guids
+ GuidDict.update(Guids)
+ for Pcd in Pkg.Pcds:
+ PcdCName = Pcd[0]
+ PcdTokenName = Pcd[1]
+ if GlobalData.MixedPcd:
+ for PcdItem in GlobalData.MixedPcd:
+ if (PcdCName, PcdTokenName) in GlobalData.MixedPcd[PcdItem]:
+ PcdCName = PcdItem[0]
+ break
+ if (PcdCName, PcdTokenName) not in DecPcds:
+ DecPcds[PcdCName, PcdTokenName] = Pkg.Pcds[Pcd]
+ return DecPcds, GuidDict
+
+## Get all dependent libraries for a module
+#
+# @param Module: InfBuildData instance
+# @param Platform: DscBuildData instance
+# @param BuildDatabase: The database saves all data for all metafiles
+# @param Arch: Current arch
+# @param Target: Current target
+# @param Toolchain: Current toolchain
+# @retval: List of dependent libraries which are InfBuildData instances
+#
+def GetLiabraryInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain):
+ return GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain,Platform.MetaFile,EdkLogger)
+
+def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain, FileName = '', EdkLogger = None):
+ if Module.LibInstances:
+ return Module.LibInstances
+ ModuleType = Module.ModuleType
+
+ # add forced library instances (specified under LibraryClasses sections)
+ #
+ # If a module has a MODULE_TYPE of USER_DEFINED,
+ # do not link in NULL library class instances from the global [LibraryClasses.*] sections.
+ #
+ if Module.ModuleType != SUP_MODULE_USER_DEFINED:
+ for LibraryClass in Platform.LibraryClasses.GetKeys():
+ if LibraryClass.startswith("NULL") and LibraryClass[4:].isdigit() and Platform.LibraryClasses[LibraryClass, Module.ModuleType]:
+ Module.LibraryClasses[LibraryClass] = Platform.LibraryClasses[LibraryClass, Module.ModuleType]
+
+ # add forced library instances (specified in module overrides)
+ for LibraryClass in Platform.Modules[str(Module)].LibraryClasses:
+ if LibraryClass.startswith("NULL") and LibraryClass[4:].isdigit():
+ Module.LibraryClasses[LibraryClass] = Platform.Modules[str(Module)].LibraryClasses[LibraryClass]
+
+ # EdkII module
+ LibraryConsumerList = [Module]
+ Constructor = []
+ ConsumedByList = OrderedListDict()
+ LibraryInstance = OrderedDict()
+
+ if not Module.LibraryClass:
+ EdkLogger.verbose("")
+ EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch))
+
+ while len(LibraryConsumerList) > 0:
+ M = LibraryConsumerList.pop()
+ for LibraryClassName in M.LibraryClasses:
+ if LibraryClassName.startswith("NULL") and LibraryClassName[4:].isdigit() and bool(M.LibraryClass):
+ continue
+ if LibraryClassName not in LibraryInstance:
+ # override library instance for this module
+ LibraryPath = Platform.Modules[str(Module)].LibraryClasses.get(LibraryClassName,Platform.LibraryClasses[LibraryClassName, ModuleType])
+ if LibraryPath is None:
+ LibraryPath = M.LibraryClasses.get(LibraryClassName)
+ if LibraryPath is None:
+ if not Module.LibraryClass:
+ EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
+ "Instance of library class [%s] is not found" % LibraryClassName,
+ File=FileName,
+ ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), Arch, str(Module)))
+ else:
+ return []
+
+ LibraryModule = BuildDatabase[LibraryPath, Arch, Target, Toolchain]
+ # for those forced library instance (NULL library), add a fake library class
+ if LibraryClassName.startswith("NULL") and LibraryClassName[4:].isdigit():
+ LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
+ elif LibraryModule.LibraryClass is None \
+ or len(LibraryModule.LibraryClass) == 0 \
+ or (ModuleType != SUP_MODULE_USER_DEFINED and ModuleType != SUP_MODULE_HOST_APPLICATION
+ and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
+ # only USER_DEFINED can link against any library instance despite of its SupModList
+ if not Module.LibraryClass:
+ EdkLogger.error("build", OPTION_MISSING,
+ "Module type [%s] is not supported by library instance [%s]" \
+ % (ModuleType, LibraryPath), File=FileName,
+ ExtraData="consumed by library instance [%s] which is consumed by module [%s]" \
+ % (str(M), str(Module))
+ )
+ else:
+ return []
+
+ LibraryInstance[LibraryClassName] = LibraryModule
+ LibraryConsumerList.append(LibraryModule)
+ if not Module.LibraryClass:
+ EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
+ else:
+ LibraryModule = LibraryInstance[LibraryClassName]
+
+ if LibraryModule is None:
+ continue
+
+ if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
+ Constructor.append(LibraryModule)
+
+ # don't add current module itself to consumer list
+ if M != Module:
+ if M in ConsumedByList[LibraryModule]:
+ continue
+ ConsumedByList[LibraryModule].append(M)
+ #
+ # Initialize the sorted output list to the empty set
+ #
+ SortedLibraryList = []
+ #
+ # Q <- Set of all nodes with no incoming edges
+ #
+ LibraryList = [] #LibraryInstance.values()
+ Q = []
+ for LibraryClassName in LibraryInstance:
+ M = LibraryInstance[LibraryClassName]
+ LibraryList.append(M)
+ if not ConsumedByList[M]:
+ Q.append(M)
+
+ #
+ # start the DAG algorithm
+ #
+ while True:
+ EdgeRemoved = True
+ while Q == [] and EdgeRemoved:
+ EdgeRemoved = False
+ # for each node Item with a Constructor
+ for Item in LibraryList:
+ if Item not in Constructor:
+ continue
+ # for each Node without a constructor with an edge e from Item to Node
+ for Node in ConsumedByList[Item]:
+ if Node in Constructor:
+ continue
+ # remove edge e from the graph if Node has no constructor
+ ConsumedByList[Item].remove(Node)
+ EdgeRemoved = True
+ if not ConsumedByList[Item]:
+ # insert Item into Q
+ Q.insert(0, Item)
+ break
+ if Q != []:
+ break
+ # DAG is done if there's no more incoming edge for all nodes
+ if Q == []:
+ break
+
+ # remove node from Q
+ Node = Q.pop()
+ # output Node
+ SortedLibraryList.append(Node)
+
+ # for each node Item with an edge e from Node to Item do
+ for Item in LibraryList:
+ if Node not in ConsumedByList[Item]:
+ continue
+ # remove edge e from the graph
+ ConsumedByList[Item].remove(Node)
+
+ if ConsumedByList[Item]:
+ continue
+ # insert Item into Q, if Item has no other incoming edges
+ Q.insert(0, Item)
+
+ #
+ # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
+ #
+ for Item in LibraryList:
+ if ConsumedByList[Item] and Item in Constructor and len(Constructor) > 1:
+ if not Module.LibraryClass:
+ ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join(str(L) for L in ConsumedByList[Item])
+ EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
+ ExtraData=ErrorMessage, File=FileName)
+ else:
+ return []
+ if Item not in SortedLibraryList:
+ SortedLibraryList.append(Item)
+
+ #
+ # Build the list of constructor and destructor names
+ # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
+ #
+ SortedLibraryList.reverse()
+ Module.LibInstances = SortedLibraryList
+ SortedLibraryList = [lib.SetReferenceModule(Module) for lib in SortedLibraryList]
+ return SortedLibraryList
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index d955c78b25..0764e27243 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -1,204 +1,204 @@
-## @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
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from Common.StringUtils import *
-from Common.DataType import *
-from Common.Misc import *
-from types import *
-
-from .MetaDataTable import *
-from .MetaFileTable import *
-from .MetaFileParser import *
-
-from Workspace.DecBuildData import DecBuildData
-from Workspace.DscBuildData import DscBuildData
-from Workspace.InfBuildData import InfBuildData
-
-## Database
-#
-# This class defined the build database for all modules, packages and platform.
-# It will call corresponding parser for the given file if it cannot find it in
-# the database.
-#
-# @param DbPath Path of database file
-# @param GlobalMacros Global macros used for replacement during file parsing
-# @param RenewDb=False Create new database file if it's already there
-#
-class WorkspaceDatabase(object):
-
- #
- # internal class used for call corresponding file parser and caching the result
- # to avoid unnecessary re-parsing
- #
- class BuildObjectFactory(object):
-
- _FILE_TYPE_ = {
- ".inf" : MODEL_FILE_INF,
- ".dec" : MODEL_FILE_DEC,
- ".dsc" : MODEL_FILE_DSC,
- }
-
- # file parser
- _FILE_PARSER_ = {
- MODEL_FILE_INF : InfParser,
- MODEL_FILE_DEC : DecParser,
- MODEL_FILE_DSC : DscParser,
- }
-
- # convert to xxxBuildData object
- _GENERATOR_ = {
- MODEL_FILE_INF : InfBuildData,
- MODEL_FILE_DEC : DecBuildData,
- MODEL_FILE_DSC : DscBuildData,
- }
-
- _CACHE_ = {} # (FilePath, Arch) : <object>
- def GetCache(self):
- return self._CACHE_
-
- # constructor
- def __init__(self, WorkspaceDb):
- self.WorkspaceDb = WorkspaceDb
-
- # key = (FilePath, Arch=None)
- def __contains__(self, Key):
- FilePath = Key[0]
- if len(Key) > 1:
- Arch = Key[1]
- else:
- Arch = None
- return (FilePath, Arch) in self._CACHE_
-
- # key = (FilePath, Arch=None, Target=None, Toolchain=None)
- def __getitem__(self, Key):
- FilePath = Key[0]
- KeyLength = len(Key)
- if KeyLength > 1:
- Arch = Key[1]
- else:
- Arch = None
- if KeyLength > 2:
- Target = Key[2]
- else:
- Target = None
- if KeyLength > 3:
- Toolchain = Key[3]
- else:
- Toolchain = None
-
- # if it's generated before, just return the cached one
- Key = (FilePath, Arch, Target, Toolchain)
- if Key in self._CACHE_:
- return self._CACHE_[Key]
-
- # check file type
- BuildObject = self.CreateBuildObject(FilePath, Arch, Target, Toolchain)
- self._CACHE_[Key] = BuildObject
- return BuildObject
- def CreateBuildObject(self,FilePath, Arch, Target, Toolchain):
- Ext = FilePath.Type
- if Ext not in self._FILE_TYPE_:
- return None
- FileType = self._FILE_TYPE_[Ext]
- if FileType not in self._GENERATOR_:
- return None
-
- # get the parser ready for this file
- MetaFile = self._FILE_PARSER_[FileType](
- FilePath,
- FileType,
- Arch,
- MetaFileStorage(self.WorkspaceDb, FilePath, FileType)
- )
- # always do post-process, in case of macros change
- MetaFile.DoPostProcess()
- # object the build is based on
- BuildObject = self._GENERATOR_[FileType](
- FilePath,
- MetaFile,
- self,
- Arch,
- Target,
- Toolchain
- )
- return BuildObject
-
- # placeholder for file format conversion
- class TransformObjectFactory:
- def __init__(self, WorkspaceDb):
- self.WorkspaceDb = WorkspaceDb
-
- # key = FilePath, Arch
- def __getitem__(self, Key):
- pass
-
- ## Constructor of WorkspaceDatabase
- #
- # @param DbPath Path of database file
- # @param GlobalMacros Global macros used for replacement during file parsing
- # @param RenewDb=False Create new database file if it's already there
- #
- def __init__(self):
- self.DB = dict()
- # create table for internal uses
- self.TblDataModel = DataClass.MODEL_LIST
- self.TblFile = []
- self.Platform = None
-
- # conversion object for build or file format conversion purpose
- self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)
- self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)
-
-
- ## Summarize all packages in the database
- def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):
- self.Platform = Platform
- PackageList = []
- Pa = self.BuildObject[self.Platform, Arch, TargetName, ToolChainTag]
- #
- # Get Package related to Modules
- #
- for Module in Pa.Modules:
- ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]
- for Package in ModuleObj.Packages:
- if Package not in PackageList:
- PackageList.append(Package)
- #
- # Get Packages related to Libraries
- #
- for Lib in Pa.LibraryInstances:
- LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]
- for Package in LibObj.Packages:
- if Package not in PackageList:
- PackageList.append(Package)
- for Package in Pa.Packages:
- if Package in PackageList:
- continue
- PackageList.append(Package)
-
- return PackageList
-
- def MapPlatform(self, Dscfile):
- Platform = self.BuildObject[PathClass(Dscfile), TAB_COMMON]
- if Platform is None:
- EdkLogger.error('build', PARSER_ERROR, "Failed to parser DSC file: %s" % Dscfile)
- return Platform
-
-BuildDB = WorkspaceDatabase()
-##
-#
-# This acts like the main() function for the script, unless it is 'import'ed into another
-# script.
-#
-if __name__ == '__main__':
- pass
-
+## @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
+#
+
+##
+# Import Modules
+#
+from __future__ import absolute_import
+from Common.StringUtils import *
+from Common.DataType import *
+from Common.Misc import *
+from types import *
+
+from .MetaDataTable import *
+from .MetaFileTable import *
+from .MetaFileParser import *
+
+from Workspace.DecBuildData import DecBuildData
+from Workspace.DscBuildData import DscBuildData
+from Workspace.InfBuildData import InfBuildData
+
+## Database
+#
+# This class defined the build database for all modules, packages and platform.
+# It will call corresponding parser for the given file if it cannot find it in
+# the database.
+#
+# @param DbPath Path of database file
+# @param GlobalMacros Global macros used for replacement during file parsing
+# @param RenewDb=False Create new database file if it's already there
+#
+class WorkspaceDatabase(object):
+
+ #
+ # internal class used for call corresponding file parser and caching the result
+ # to avoid unnecessary re-parsing
+ #
+ class BuildObjectFactory(object):
+
+ _FILE_TYPE_ = {
+ ".inf" : MODEL_FILE_INF,
+ ".dec" : MODEL_FILE_DEC,
+ ".dsc" : MODEL_FILE_DSC,
+ }
+
+ # file parser
+ _FILE_PARSER_ = {
+ MODEL_FILE_INF : InfParser,
+ MODEL_FILE_DEC : DecParser,
+ MODEL_FILE_DSC : DscParser,
+ }
+
+ # convert to xxxBuildData object
+ _GENERATOR_ = {
+ MODEL_FILE_INF : InfBuildData,
+ MODEL_FILE_DEC : DecBuildData,
+ MODEL_FILE_DSC : DscBuildData,
+ }
+
+ _CACHE_ = {} # (FilePath, Arch) : <object>
+ def GetCache(self):
+ return self._CACHE_
+
+ # constructor
+ def __init__(self, WorkspaceDb):
+ self.WorkspaceDb = WorkspaceDb
+
+ # key = (FilePath, Arch=None)
+ def __contains__(self, Key):
+ FilePath = Key[0]
+ if len(Key) > 1:
+ Arch = Key[1]
+ else:
+ Arch = None
+ return (FilePath, Arch) in self._CACHE_
+
+ # key = (FilePath, Arch=None, Target=None, Toolchain=None)
+ def __getitem__(self, Key):
+ FilePath = Key[0]
+ KeyLength = len(Key)
+ if KeyLength > 1:
+ Arch = Key[1]
+ else:
+ Arch = None
+ if KeyLength > 2:
+ Target = Key[2]
+ else:
+ Target = None
+ if KeyLength > 3:
+ Toolchain = Key[3]
+ else:
+ Toolchain = None
+
+ # if it's generated before, just return the cached one
+ Key = (FilePath, Arch, Target, Toolchain)
+ if Key in self._CACHE_:
+ return self._CACHE_[Key]
+
+ # check file type
+ BuildObject = self.CreateBuildObject(FilePath, Arch, Target, Toolchain)
+ self._CACHE_[Key] = BuildObject
+ return BuildObject
+ def CreateBuildObject(self,FilePath, Arch, Target, Toolchain):
+ Ext = FilePath.Type
+ if Ext not in self._FILE_TYPE_:
+ return None
+ FileType = self._FILE_TYPE_[Ext]
+ if FileType not in self._GENERATOR_:
+ return None
+
+ # get the parser ready for this file
+ MetaFile = self._FILE_PARSER_[FileType](
+ FilePath,
+ FileType,
+ Arch,
+ MetaFileStorage(self.WorkspaceDb, FilePath, FileType)
+ )
+ # always do post-process, in case of macros change
+ MetaFile.DoPostProcess()
+ # object the build is based on
+ BuildObject = self._GENERATOR_[FileType](
+ FilePath,
+ MetaFile,
+ self,
+ Arch,
+ Target,
+ Toolchain
+ )
+ return BuildObject
+
+ # placeholder for file format conversion
+ class TransformObjectFactory:
+ def __init__(self, WorkspaceDb):
+ self.WorkspaceDb = WorkspaceDb
+
+ # key = FilePath, Arch
+ def __getitem__(self, Key):
+ pass
+
+ ## Constructor of WorkspaceDatabase
+ #
+ # @param DbPath Path of database file
+ # @param GlobalMacros Global macros used for replacement during file parsing
+ # @param RenewDb=False Create new database file if it's already there
+ #
+ def __init__(self):
+ self.DB = dict()
+ # create table for internal uses
+ self.TblDataModel = DataClass.MODEL_LIST
+ self.TblFile = []
+ self.Platform = None
+
+ # conversion object for build or file format conversion purpose
+ self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)
+ self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)
+
+
+ ## Summarize all packages in the database
+ def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):
+ self.Platform = Platform
+ PackageList = []
+ Pa = self.BuildObject[self.Platform, Arch, TargetName, ToolChainTag]
+ #
+ # Get Package related to Modules
+ #
+ for Module in Pa.Modules:
+ ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]
+ for Package in ModuleObj.Packages:
+ if Package not in PackageList:
+ PackageList.append(Package)
+ #
+ # Get Packages related to Libraries
+ #
+ for Lib in Pa.LibraryInstances:
+ LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]
+ for Package in LibObj.Packages:
+ if Package not in PackageList:
+ PackageList.append(Package)
+ for Package in Pa.Packages:
+ if Package in PackageList:
+ continue
+ PackageList.append(Package)
+
+ return PackageList
+
+ def MapPlatform(self, Dscfile):
+ Platform = self.BuildObject[PathClass(Dscfile), TAB_COMMON]
+ if Platform is None:
+ EdkLogger.error('build', PARSER_ERROR, "Failed to parser DSC file: %s" % Dscfile)
+ return Platform
+
+BuildDB = WorkspaceDatabase()
+##
+#
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+#
+if __name__ == '__main__':
+ pass
+
diff --git a/BaseTools/Source/Python/Workspace/__init__.py b/BaseTools/Source/Python/Workspace/__init__.py
index 85ae9937c4..4183055e28 100644
--- a/BaseTools/Source/Python/Workspace/__init__.py
+++ b/BaseTools/Source/Python/Workspace/__init__.py
@@ -1,9 +1,9 @@
-## @file
-# Python 'Workspace' package initialization file.
-#
-# This file is required to make Python interpreter treat the directory
-# as containing package.
-#
-# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
+## @file
+# Python 'Workspace' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#