diff options
Diffstat (limited to 'BaseTools/Source/Python')
36 files changed, 3534 insertions, 420 deletions
diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index 700b689a54..cb3369ffdf 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -184,6 +184,7 @@ class WorkspaceAutoGen(AutoGen): self.MetaFile = ActivePlatform
self.WorkspaceDir = WorkspaceDir
self.Platform = self.BuildDatabase[self.MetaFile, 'COMMON', Target, Toolchain]
+ GlobalData.gActivePlatform = self.Platform
self.BuildTarget = Target
self.ToolChain = Toolchain
self.ArchList = ArchList
@@ -960,8 +961,7 @@ class PlatformAutoGen(AutoGen): "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile))
if VpdFile.GetCount() != 0:
- WorkspaceDb = self.BuildDatabase.WorkspaceDb
- DscTimeStamp = WorkspaceDb.GetTimeStamp(WorkspaceDb.GetFileId(str(self.Platform.MetaFile)))
+ DscTimeStamp = self.Platform.MetaFile.TimeStamp
FvPath = os.path.join(self.BuildDir, "FV")
if not os.path.exists(FvPath):
try:
@@ -1001,7 +1001,7 @@ class PlatformAutoGen(AutoGen): # just pick the a value to determine whether is unicode string type
Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
if Sku.VpdOffset == "*":
- Sku.VpdOffset = VpdFile.GetOffset(Pcd)[0]
+ Sku.VpdOffset = VpdFile.GetOffset(Pcd)[0].strip()
else:
EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)
@@ -1242,18 +1242,43 @@ class PlatformAutoGen(AutoGen): if self._PcdTokenNumber == None:
self._PcdTokenNumber = sdict()
TokenNumber = 1
+ #
+ # Make the Dynamic and DynamicEx PCD use within different TokenNumber area.
+ # Such as:
+ #
+ # Dynamic PCD:
+ # TokenNumber 0 ~ 10
+ # DynamicEx PCD:
+ # TokeNumber 11 ~ 20
+ #
for Pcd in self.DynamicPcdList:
if Pcd.Phase == "PEI":
- EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
- self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
- TokenNumber += 1
-
+ if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
+ EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
+ self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
+ TokenNumber += 1
+
+ for Pcd in self.DynamicPcdList:
+ if Pcd.Phase == "PEI":
+ if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
+ EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
+ self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
+ TokenNumber += 1
+
for Pcd in self.DynamicPcdList:
if Pcd.Phase == "DXE":
- EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
- self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
- TokenNumber += 1
-
+ if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
+ EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
+ self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
+ TokenNumber += 1
+
+ for Pcd in self.DynamicPcdList:
+ if Pcd.Phase == "DXE":
+ if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
+ EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
+ self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
+ TokenNumber += 1
+
for Pcd in self.NonDynamicPcdList:
self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
TokenNumber += 1
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py index 5638bfd043..530dfd7c97 100644 --- a/BaseTools/Source/Python/AutoGen/GenC.py +++ b/BaseTools/Source/Python/AutoGen/GenC.py @@ -312,7 +312,7 @@ gAutoGenHPrologueString = TemplateString(""" """) -gAutoGenHCppPrologueString = """ +gAutoGenHCppPrologueString = """\ #ifdef __cplusplus extern "C" { #endif @@ -971,9 +971,9 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd): if Pcd.DatumType == 'BOOLEAN': BoolValue = Value.upper() - if BoolValue == 'TRUE': + if BoolValue == 'TRUE' or BoolValue == '1': Value = '1U' - elif BoolValue == 'FALSE': + elif BoolValue == 'FALSE' or BoolValue == '0': Value = '0U' if Pcd.DatumType in ['UINT64', 'UINT32', 'UINT16', 'UINT8']: @@ -1193,14 +1193,14 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): Dict = { 'PHASE' : Phase, - 'GUID_TABLE_SIZE' : '1', - 'STRING_TABLE_SIZE' : '1', - 'SKUID_TABLE_SIZE' : '1', - 'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '1', - 'LOCAL_TOKEN_NUMBER' : '0', - 'EXMAPPING_TABLE_SIZE' : '1', - 'EX_TOKEN_NUMBER' : '0', - 'SIZE_TABLE_SIZE' : '2', + 'GUID_TABLE_SIZE' : '1U', + 'STRING_TABLE_SIZE' : '1U', + 'SKUID_TABLE_SIZE' : '1U', + 'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '1U', + 'LOCAL_TOKEN_NUMBER' : '0U', + 'EXMAPPING_TABLE_SIZE' : '1U', + 'EX_TOKEN_NUMBER' : '0U', + 'SIZE_TABLE_SIZE' : '2U', 'GUID_TABLE_EMPTY' : 'TRUE', 'STRING_TABLE_EMPTY' : 'TRUE', 'SKUID_TABLE_EMPTY' : 'TRUE', @@ -1208,7 +1208,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): 'EXMAP_TABLE_EMPTY' : 'TRUE', 'PCD_DATABASE_UNINIT_EMPTY' : ' UINT8 dummy; /* PCD_DATABASE_UNINIT is emptry */', 'SYSTEM_SKU_ID' : ' SKU_ID SystemSkuId;', - 'SYSTEM_SKU_ID_VALUE' : '0' + 'SYSTEM_SKU_ID_VALUE' : '0U' } for DatumType in ['UINT64','UINT32','UINT16','UINT8','BOOLEAN', "VOID*"]: @@ -1313,10 +1313,10 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): if SkuId == None or SkuId == '': continue - if SkuId not in Dict['SKUID_VALUE']: - Dict['SKUID_VALUE'].append(SkuId) + if (SkuId + 'U') not in Dict['SKUID_VALUE']: + Dict['SKUID_VALUE'].append(SkuId + 'U') - SkuIdIndex = Dict['SKUID_VALUE'].index(SkuId) + SkuIdIndex = Dict['SKUID_VALUE'].index(SkuId + 'U') if len(Sku.VariableName) > 0: Pcd.TokenTypeList += ['PCD_TYPE_HII'] Pcd.InitString = 'INIT' @@ -1346,11 +1346,11 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): VariableHeadGuidIndex = GuidList.index(VariableGuid) if "PCD_TYPE_STRING" in Pcd.TokenTypeList: - VariableHeadValueList.append('%d, %d, %s, offsetof(%s_PCD_DATABASE, Init.%s_%s)' % + VariableHeadValueList.append('%dU, %dU, %sU, offsetof(%s_PCD_DATABASE, Init.%s_%s)' % (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, Phase, CName, TokenSpaceGuid)) else: - VariableHeadValueList.append('%d, %d, %s, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s)' % + VariableHeadValueList.append('%dU, %dU, %sU, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s)' % (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, Phase, CName, TokenSpaceGuid, SkuIdIndex)) Dict['VARDEF_CNAME_'+Pcd.DatumType].append(CName) @@ -1359,11 +1359,24 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): if "PCD_TYPE_STRING" in Pcd.TokenTypeList: Dict['VARDEF_VALUE_' + Pcd.DatumType].append("%s_%s[%d]" % (Pcd.TokenCName, TokenSpaceGuid, SkuIdIndex)) else: - Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue) + # + # ULL (for UINT64) or U(other integer type) should be append to avoid + # warning under linux building environment. + # + if Pcd.DatumType == "UINT64": + Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "ULL") + elif Pcd.DatumType in ("UINT32", "UINT16", "UINT8"): + Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "U") + elif Pcd.DatumType == "BOOLEAN": + if Sku.HiiDefaultValue in ["1", "0"]: + Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "U") + else: + Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue) + elif Sku.VpdOffset != '': Pcd.TokenTypeList += ['PCD_TYPE_VPD'] Pcd.InitString = 'INIT' - VpdHeadOffsetList.append(Sku.VpdOffset) + VpdHeadOffsetList.append(str(Sku.VpdOffset) + 'U') continue if Pcd.DatumType == 'VOID*': @@ -1390,11 +1403,11 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): Size = len(Sku.DefaultValue.replace(',',' ').split()) Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue) - StringHeadOffsetList.append(str(StringTableSize)) + StringHeadOffsetList.append(str(StringTableSize) + 'U') Dict['SIZE_TABLE_CNAME'].append(CName) Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid) - Dict['SIZE_TABLE_CURRENT_LENGTH'].append(Size) - Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(Pcd.MaxDatumSize) + Dict['SIZE_TABLE_CURRENT_LENGTH'].append(str(Size) + 'U') + Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(str(Pcd.MaxDatumSize) + 'U') if Pcd.MaxDatumSize != '': MaxDatumSize = int(Pcd.MaxDatumSize, 0) if MaxDatumSize < Size: @@ -1425,6 +1438,9 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): ValueList.append(Sku.DefaultValue + "ULL") elif Pcd.DatumType in ("UINT32", "UINT16", "UINT8"): ValueList.append(Sku.DefaultValue + "U") + elif Pcd.DatumType == "BOOLEAN": + if Sku.DefaultValue in ["1", "0"]: + ValueList.append(Sku.DefaultValue + "U") else: ValueList.append(Sku.DefaultValue) @@ -1489,8 +1505,19 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): Dict['TOKEN_CNAME'][GeneratedTokenNumber] = CName Dict['TOKEN_GUID'][GeneratedTokenNumber] = TokenSpaceGuid Dict['TOKEN_TYPE'][GeneratedTokenNumber] = ' | '.join(Pcd.TokenTypeList) + + Pcd.TokenTypeList = list(set(Pcd.TokenTypeList)) + # + # Update VARDEF_HEADER + # + if 'PCD_TYPE_HII' in Pcd.TokenTypeList: + Dict['VARDEF_HEADER'][GeneratedTokenNumber] = '_Variable_Header' + else: + Dict['VARDEF_HEADER'][GeneratedTokenNumber] = '' + + if Pcd.Type in gDynamicExPcd: - Dict['EXMAPPING_TABLE_EXTOKEN'].append(Pcd.TokenValue) + Dict['EXMAPPING_TABLE_EXTOKEN'].append(str(Pcd.TokenValue) + 'U') if Phase == 'DXE': GeneratedTokenNumber += NumberOfPeiLocalTokens # @@ -1502,12 +1529,12 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): # Therefore, 1 is added to GeneratedTokenNumber to generate a PCD Token Number before being inserted # to the EXMAPPING_TABLE. # - Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(GeneratedTokenNumber + 1) - Dict['EXMAPPING_TABLE_GUID_INDEX'].append(GuidList.index(TokenSpaceGuid)) + Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(str(GeneratedTokenNumber + 1) + 'U') + Dict['EXMAPPING_TABLE_GUID_INDEX'].append(str(GuidList.index(TokenSpaceGuid)) + 'U') if GuidList != []: Dict['GUID_TABLE_EMPTY'] = 'FALSE' - Dict['GUID_TABLE_SIZE'] = len(GuidList) + Dict['GUID_TABLE_SIZE'] = str(len(GuidList)) + 'U' else: Dict['GUID_STRUCTURE'] = [GuidStringToGuidStructureString('00000000-0000-0000-0000-000000000000')] @@ -1519,13 +1546,13 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): Dict['STRING_TABLE_VALUE'].append('{ 0 }') else: Dict['STRING_TABLE_EMPTY'] = 'FALSE' - Dict['STRING_TABLE_SIZE'] = StringTableSize + Dict['STRING_TABLE_SIZE'] = str(StringTableSize) + 'U' if Dict['SIZE_TABLE_CNAME'] == []: Dict['SIZE_TABLE_CNAME'].append('') Dict['SIZE_TABLE_GUID'].append('') - Dict['SIZE_TABLE_CURRENT_LENGTH'].append(0) - Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(0) + Dict['SIZE_TABLE_CURRENT_LENGTH'].append('0U') + Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append('0U') if NumberOfLocalTokens != 0: Dict['DATABASE_EMPTY'] = 'FALSE' @@ -1534,15 +1561,15 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): if NumberOfExTokens != 0: Dict['EXMAP_TABLE_EMPTY'] = 'FALSE' - Dict['EXMAPPING_TABLE_SIZE'] = NumberOfExTokens - Dict['EX_TOKEN_NUMBER'] = NumberOfExTokens + Dict['EXMAPPING_TABLE_SIZE'] = str(NumberOfExTokens) + 'U' + Dict['EX_TOKEN_NUMBER'] = str(NumberOfExTokens) + 'U' else: - Dict['EXMAPPING_TABLE_EXTOKEN'].append(0) - Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(0) - Dict['EXMAPPING_TABLE_GUID_INDEX'].append(0) + Dict['EXMAPPING_TABLE_EXTOKEN'].append('0U') + Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append('0U') + Dict['EXMAPPING_TABLE_GUID_INDEX'].append('0U') if NumberOfSizeItems != 0: - Dict['SIZE_TABLE_SIZE'] = NumberOfSizeItems * 2 + Dict['SIZE_TABLE_SIZE'] = str(NumberOfSizeItems * 2) + 'U' AutoGenH.Append(gPcdDatabaseAutoGenH.Replace(Dict)) if NumberOfLocalTokens == 0: @@ -1716,8 +1743,8 @@ def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH): UefiSpecVersion = '0x00000000' Dict = { 'Function' : Info.Module.ModuleEntryPointList, - 'PiSpecVersion' : PiSpecVersion, - 'UefiSpecVersion': UefiSpecVersion + 'PiSpecVersion' : PiSpecVersion + 'U', + 'UefiSpecVersion': UefiSpecVersion + 'U' } if Info.ModuleType in ['PEI_CORE', 'DXE_CORE', 'SMM_CORE']: @@ -1777,7 +1804,7 @@ def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH): # Unload Image Handlers # NumUnloadImage = len(Info.Module.ModuleUnloadImageList) - Dict = {'Count':NumUnloadImage, 'Function':Info.Module.ModuleUnloadImageList} + Dict = {'Count':str(NumUnloadImage) + 'U', 'Function':Info.Module.ModuleUnloadImageList} if NumUnloadImage < 2: AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage].Replace(Dict)) else: diff --git a/BaseTools/Source/Python/Common/BuildVersion.py b/BaseTools/Source/Python/Common/BuildVersion.py index 4bb9a8b521..fc3239135c 100644 --- a/BaseTools/Source/Python/Common/BuildVersion.py +++ b/BaseTools/Source/Python/Common/BuildVersion.py @@ -1,3 +1,3 @@ #This file is for build version number auto generation
#
-gBUILD_VERSION = "Build 2423"
+gBUILD_VERSION = "Build 2460"
diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py index e2889a8dd3..8b112d50b3 100644 --- a/BaseTools/Source/Python/Common/Expression.py +++ b/BaseTools/Source/Python/Common/Expression.py @@ -14,7 +14,6 @@ #
from Common.GlobalData import *
from CommonDataClass.Exceptions import BadExpression
-from CommonDataClass.Exceptions import SymbolNotFound
from CommonDataClass.Exceptions import WrnExpression
from Misc import GuidStringToGuidStructureString
@@ -36,6 +35,7 @@ ERR_RELCMP_STR_OTHERS = 'Operator taking Operand of string type and Boolean/Nu ERR_STRING_CMP = 'Unicode string and general string cannot be compared: [%s %s %s]'
ERR_ARRAY_TOKEN = 'Bad C array or C format GUID token: [%s].'
ERR_ARRAY_ELE = 'This must be HEX value for NList or Array: [%s].'
+ERR_EMPTY_EXPR = 'Empty expression is not allowed.'
## SplitString
# Split string to list according double quote
@@ -133,7 +133,7 @@ class ValueExpression(object): @staticmethod
def Eval(Operator, Oprand1, Oprand2 = None):
WrnExp = None
-
+
if Operator not in ["==", "!=", ">=", "<=", ">", "<", "in", "not in"] and \
(type(Oprand1) == type('') or type(Oprand2) == type('')):
raise BadExpression(ERR_STRING_EXPR % Operator)
@@ -166,13 +166,13 @@ class ValueExpression(object): raise WrnExp
else:
raise BadExpression(ERR_RELCMP_STR_OTHERS % Operator)
- elif TypeDict[type(Oprand1)] != TypeDict[type(Oprand2)]:
+ elif TypeDict[type(Oprand1)] != TypeDict[type(Oprand2)]:
if Operator in ["==", "!=", ">=", "<=", ">", "<"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):
# comparison between number and boolean is allowed
pass
- elif Operator in ['&', '|', '^', "&&", "||"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):
+ elif Operator in ['&', '|', '^', "and", "or"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):
# bitwise and logical operation between number and boolean is allowed
- pass
+ pass
else:
raise BadExpression(ERR_EXPR_TYPE)
if type(Oprand1) == type('') and type(Oprand2) == type(''):
@@ -198,7 +198,7 @@ class ValueExpression(object): Val = True
else:
Val = False
-
+
if WrnExp:
WrnExp.result = Val
raise WrnExp
@@ -216,8 +216,7 @@ class ValueExpression(object): ['TARGET', 'TOOL_CHAIN_TAG', 'ARCH'])
if not self._Expr.strip():
- self._NoProcess = True
- return
+ raise BadExpression(ERR_EMPTY_EXPR)
#
# The symbol table including PCD and macro mapping
@@ -227,25 +226,64 @@ class ValueExpression(object): self._Idx = 0
self._Len = len(self._Expr)
self._Token = ''
+ self._WarnExcept = None
# Literal token without any conversion
self._LiteralToken = ''
# Public entry for this class
- def __call__(self):
+ # @param RealValue: False: only evaluate if the expression is true or false, used for conditional expression
+ # True : return the evaluated str(value), used for PCD value
+ #
+ # @return: True or False if RealValue is False
+ # Evaluated value of string format if RealValue is True
+ #
+ def __call__(self, RealValue=False):
if self._NoProcess:
return self._Expr
+ self._Expr = self._Expr.strip()
+ if RealValue:
+ self._Token = self._Expr
+ if self.__IsNumberToken():
+ return self._Expr
+
+ Token = self._GetToken()
+ if type(Token) == type('') and Token.startswith('{') and Token.endswith('}') and self._Idx >= self._Len:
+ return self._Expr
+
+ self._Idx = 0
+ self._Token = ''
+
Val = self._OrExpr()
- if type(Val) == type('') and Val == 'L""':
- Val = ''
+ RealVal = Val
+ if type(Val) == type(''):
+ if Val == 'L""':
+ Val = False
+ elif not Val:
+ Val = False
+ RealVal = '""'
+ elif not Val.startswith('L"') and not Val.startswith('{'):
+ Val = True
+ RealVal = '"' + RealVal + '"'
# The expression has been parsed, but the end of expression is not reached
# It means the rest does not comply EBNF of <Expression>
if self._Idx != self._Len:
raise BadExpression(ERR_SNYTAX % self._Expr[self._Idx:])
- return Val
+ if RealValue:
+ RetVal = str(RealVal)
+ elif Val:
+ RetVal = True
+ else:
+ RetVal = False
+
+ if self._WarnExcept:
+ self._WarnExcept.result = RetVal
+ raise self._WarnExcept
+ else:
+ return RetVal
# Template function to parse binary operators which have same precedence
# Expr [Operator Expr]*
@@ -253,7 +291,11 @@ class ValueExpression(object): Val = EvalFunc()
while self._IsOperator(OpLst):
Op = self._Token
- Val = self.Eval(Op, Val, EvalFunc())
+ try:
+ Val = self.Eval(Op, Val, EvalFunc())
+ except WrnExpression, Warn:
+ self._WarnExcept = Warn
+ Val = Warn.result
return Val
# A [|| B]*
@@ -285,7 +327,11 @@ class ValueExpression(object): if not self._IsOperator(["IN", "in"]):
raise BadExpression(ERR_REL_NOT_IN)
Op += ' ' + self._Token
- Val = self.Eval(Op, Val, self._RelExpr())
+ try:
+ Val = self.Eval(Op, Val, self._RelExpr())
+ except WrnExpression, Warn:
+ self._WarnExcept = Warn
+ Val = Warn.result
return Val
# A [ > B]*
@@ -300,7 +346,11 @@ class ValueExpression(object): def _UnaryExpr(self):
if self._IsOperator(["!", "NOT", "not"]):
Val = self._UnaryExpr()
- return self.Eval('not', Val)
+ try:
+ return self.Eval('not', Val)
+ except WrnExpression, Warn:
+ self._WarnExcept = Warn
+ return Warn.result
return self._IdenExpr()
# Parse identifier or encapsulated expression
@@ -407,8 +457,8 @@ class ValueExpression(object): # PCD token
if self.PcdPattern.match(self._Token):
if self._Token not in self._Symb:
- raise SymbolNotFound(ERR_PCD_RESOLVE % self._Token)
- self._Token = ValueExpression(self._Symb[self._Token], self._Symb)()
+ raise BadExpression(ERR_PCD_RESOLVE % self._Token)
+ self._Token = ValueExpression(self._Symb[self._Token], self._Symb)(True)
if type(self._Token) != type(''):
self._LiteralToken = hex(self._Token)
return
@@ -459,7 +509,7 @@ class ValueExpression(object): if not Token:
self._LiteralToken = '0x0'
else:
- self._LiteralToken = '0x' + Token
+ self._LiteralToken = '0x' + Token.lower()
return True
return False
@@ -488,7 +538,7 @@ class ValueExpression(object): if Match and not Expr[Match.end():Match.end()+1].isalnum() \
and Expr[Match.end():Match.end()+1] != '_':
self._Idx += Match.end()
- self._Token = ValueExpression(GuidStringToGuidStructureString(Expr[0:Match.end()]))()
+ self._Token = ValueExpression(GuidStringToGuidStructureString(Expr[0:Match.end()]))(True)
return self._Token
elif self.__IsIdChar(Ch):
return self.__GetIdToken()
@@ -526,7 +576,7 @@ class ValueExpression(object): OpToken = ''
for Ch in Expr:
if Ch in self.NonLetterOpLst:
- if '!' == Ch and OpToken in ['!=', '!']:
+ if '!' == Ch and OpToken:
break
self._Idx += 1
OpToken += Ch
@@ -551,5 +601,15 @@ class ValueExpression(object): if __name__ == '__main__':
pass
-
-
+ while True:
+ input = raw_input('Input expr: ')
+ if input in 'qQ':
+ break
+ try:
+ print ValueExpression(input)(True)
+ print ValueExpression(input)(False)
+ except WrnExpression, Ex:
+ print Ex.result
+ print str(Ex)
+ except Exception, Ex:
+ print str(Ex)
diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py index bc7e047676..492aa39962 100644 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -26,6 +26,7 @@ gAllFiles = None gGlobalDefines = {} gPlatformDefines = {} +gActivePlatform = None gCommandLineDefines = {} gEdkGlobal = {} gOverrideDir = {} diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py index 50504aa73c..8b5598b5f0 100644 --- a/BaseTools/Source/Python/Common/Misc.py +++ b/BaseTools/Source/Python/Common/Misc.py @@ -445,8 +445,10 @@ def RealPath2(File, Dir='', OverrideDir=''): return NewFile[len(OverrideDir):], NewFile[0:len(OverrideDir)] else: return NewFile[len(OverrideDir)+1:], NewFile[0:len(OverrideDir)] - - NewFile = GlobalData.gAllFiles[os.path.normpath(os.path.join(Dir, File))] + if GlobalData.gAllFiles: + NewFile = GlobalData.gAllFiles[os.path.normpath(os.path.join(Dir, File))] + else: + NewFile = os.path.normpath(os.path.join(Dir, File)) if NewFile: if Dir: if Dir[-1] == os.path.sep: diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py index 6f5f9fd0b5..73d7318de0 100644 --- a/BaseTools/Source/Python/Ecc/Check.py +++ b/BaseTools/Source/Python/Ecc/Check.py @@ -15,6 +15,7 @@ import re from CommonDataClass.DataClass import *
from Common.DataType import SUP_MODULE_LIST_STRING, TAB_VALUE_SPLIT
from EccToolError import *
+from MetaDataParser import ParseHeaderCommentSection
import EccGlobalData
import c
@@ -48,7 +49,7 @@ class Check(object): if EccGlobalData.gConfig.GeneralCheckNonAcsii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Non-ACSII char in file ...")
SqlCommand = """select ID, FullPath, ExtName from File"""
- RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
+ RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:
op = open(Record[1]).readlines()
@@ -415,13 +416,81 @@ class Check(object): elif Ext in ('.inf', '.dec', '.dsc', '.fdf'):
FullName = os.path.join(Dirpath, F)
op = open(FullName).readlines()
- if not op[0].startswith('## @file') and op[6].startswith('## @file') and op[7].startswith('## @file'):
+ FileLinesList = op
+ LineNo = 0
+ CurrentSection = MODEL_UNKNOWN
+ HeaderSectionLines = []
+ HeaderCommentStart = False
+ HeaderCommentEnd = False
+
+ for Line in FileLinesList:
+ LineNo = LineNo + 1
+ Line = Line.strip()
+ if (LineNo < len(FileLinesList) - 1):
+ NextLine = FileLinesList[LineNo].strip()
+
+ #
+ # blank line
+ #
+ if (Line == '' or not Line) and LineNo == len(FileLinesList):
+ LastSectionFalg = True
+
+ #
+ # check whether file header comment section started
+ #
+ if Line.startswith('#') and \
+ (Line.find('@file') > -1) and \
+ not HeaderCommentStart:
+ if CurrentSection != MODEL_UNKNOWN:
+ SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName
+ ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
+ for Result in ResultSet:
+ Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'
+ EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
+
+ else:
+ CurrentSection = MODEL_IDENTIFIER_FILE_HEADER
+ #
+ # Append the first line to section lines.
+ #
+ HeaderSectionLines.append((Line, LineNo))
+ HeaderCommentStart = True
+ continue
+
+ #
+ # Collect Header content.
+ #
+ if (Line.startswith('#') and CurrentSection == MODEL_IDENTIFIER_FILE_HEADER) and\
+ HeaderCommentStart and not Line.startswith('##') and not\
+ HeaderCommentEnd and NextLine != '':
+ HeaderSectionLines.append((Line, LineNo))
+ continue
+ #
+ # Header content end
+ #
+ if (Line.startswith('##') or not Line.strip().startswith("#")) and HeaderCommentStart \
+ and not HeaderCommentEnd:
+ if Line.startswith('##'):
+ HeaderCommentEnd = True
+ HeaderSectionLines.append((Line, LineNo))
+ ParseHeaderCommentSection(HeaderSectionLines, FullName)
+ break
+ if HeaderCommentStart == False:
SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName
ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
for Result in ResultSet:
- Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file""'
+ Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'
EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
+ if HeaderCommentEnd == False:
+ SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName
+ ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
+ for Result in ResultSet:
+ Msg = 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'
+ # Check whether File header Comment End with '##'
+ if EccGlobalData.gConfig.HeaderCheckFileCommentEnd == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
+ EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
+
# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
def DoxygenCheckFunctionHeader(self):
@@ -504,9 +573,9 @@ class Check(object): def MetaDataFileCheckLibraryInstance(self):
if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for library instance type issue ...")
- SqlCommand = """select A.ID, A.Value2, B.Value2 from Inf as A left join Inf as B
- where A.Value1 = 'LIBRARY_CLASS' and A.Model = %s
- and B.Value1 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
+ SqlCommand = """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B
+ where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s
+ and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
LibraryClasses = {}
@@ -528,8 +597,8 @@ class Check(object): if Record[2] != 'BASE' and Record[2] not in SupModType:
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2, OtherMsg="The Library Class '%s' does not specify its supported module types" % (List[0]), BelongsToTable='Inf', BelongsToItem=Record[0])
- SqlCommand = """select A.ID, A.Value1, B.Value2 from Inf as A left join Inf as B
- where A.Model = %s and B.Value1 = '%s' and B.Model = %s
+ SqlCommand = """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B
+ where A.Model = %s and B.Value2 = '%s' and B.Model = %s
and B.BelongsToFile = A.BelongsToFile""" \
% (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
@@ -558,11 +627,13 @@ class Check(object): SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
for LibraryClass in LibraryClasses:
- if LibraryClass[1].upper() != 'NULL':
+ if LibraryClass[1].upper() == 'NULL' or LibraryClass[1].startswith('!ifdef') or LibraryClass[1].startswith('!ifndef') or LibraryClass[1].endswith('!endif'):
+ continue
+ else:
LibraryIns = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, LibraryClass[2]))
- SqlCommand = """select Value2 from Inf where BelongsToFile =
+ SqlCommand = """select Value3 from Inf where BelongsToFile =
(select ID from File where lower(FullPath) = lower('%s'))
- and Value1 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')
+ and Value2 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
IsFound = False
for Record in RecordSet:
@@ -591,8 +662,8 @@ class Check(object): EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, OtherMsg="The Library Class [%s] is not used in any platform" % (Record[1]), BelongsToTable='Inf', BelongsToItem=Record[0])
SqlCommand = """
select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B
- where A.Model = %s and B.Model = %s and A.Value3 = B.Value3 and A.Arch = B.Arch and A.ID <> B.ID
- and A.Value1 = B.Value1 and A.StartLine <> B.StartLine and B.BelongsToFile = A.BelongsToFile""" \
+ where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID <> B.ID
+ and A.Value1 = B.Value1 and A.Value2 <> B.Value2 and A.BelongsToItem = -1 and B.BelongsToItem = -1 and A.StartLine <> B.StartLine and B.BelongsToFile = A.BelongsToFile""" \
% (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)
RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
for Record in RecordSet:
@@ -631,9 +702,10 @@ class Check(object): if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
SqlCommand = """
- select A.ID, A.Value2, A.BelongsToFile, B.ID, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
+ select A.ID, A.Value1, A.Value2, A.BelongsToFile, B.ID, B.Value1, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
where A.Model >= %s and A.Model < %s
and B.Model >= %s and B.Model < %s
+ and A.Value1 = B.Value1
and A.Value2 = B.Value2
and A.Enabled > -1
and B.Enabled > -1
@@ -641,71 +713,74 @@ class Check(object): """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
for Record in RecordSet:
- SqlCommand1 = """select Name from File where ID = %s""" % Record[2]
- SqlCommand2 = """select Name from File where ID = %s""" % Record[5]
+ SqlCommand1 = """select Name from File where ID = %s""" % Record[3]
+ SqlCommand2 = """select Name from File where ID = %s""" % Record[7]
DscFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand1)[0][0])[0]
FdfFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand2)[0][0])[0]
if DscFileName != FdfFileName:
continue
- if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):
- EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined in both FDF file and DSC file" % (Record[1]), BelongsToTable='Dsc', BelongsToItem=Record[0])
- if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[3]):
- EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined in both FDF file and DSC file" % (Record[4]), BelongsToTable='Fdf', BelongsToItem=Record[3])
+ if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1] + '.' + Record[2]):
+ EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined in both FDF file and DSC file" % (Record[1] + '.' + Record[2]), BelongsToTable='Dsc', BelongsToItem=Record[0])
+ if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[5] + '.' + Record[6]):
+ EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined in both FDF file and DSC file" % (Record[5] + '.' + Record[6]), BelongsToTable='Fdf', BelongsToItem=Record[4])
EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")
SqlCommand = """
- select A.ID, A.Value2 from Dec as A, Dec as B
+ select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B
where A.Model >= %s and A.Model < %s
and B.Model >= %s and B.Model < %s
+ and A.Value1 = B.Value1
and A.Value2 = B.Value2
- and ((A.Arch = B.Arch) and (A.Arch != 'COMMON' or B.Arch != 'COMMON'))
- and A.ID != B.ID
+ and A.Scope1 = B.Scope1
+ and A.ID <> B.ID
+ and A.Model = B.Model
and A.Enabled > -1
and B.Enabled > -1
and A.BelongsToFile = B.BelongsToFile
group by A.ID
""" % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
- RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
+ RecordSet = EccGlobalData.gDb.TblDec.Exec(SqlCommand)
for Record in RecordSet:
- if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):
- EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined duplicated in DEC file" % (Record[1]), BelongsToTable='Dec', BelongsToItem=Record[0])
+ RecordCat = Record[1] + '.' + Record[2]
+ if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, RecordCat):
+ EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined duplicated in DEC file" % RecordCat, BelongsToTable='Dec', BelongsToItem=Record[0])
# Check whether PCD settings in the FDF file can only be related to flash.
def MetaDataFileCheckPcdFlash(self):
if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")
SqlCommand = """
- select ID, Value2, BelongsToFile from Fdf as A
+ select ID, Value1, Value2, BelongsToFile from Fdf as A
where A.Model >= %s and Model < %s
and A.Enabled > -1
and A.Value2 not like '%%Flash%%'
""" % (MODEL_PCD, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
for Record in RecordSet:
- if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1]):
- EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, OtherMsg="The PCD [%s] defined in FDF file is not related to Flash" % (Record[1]), BelongsToTable='Fdf', BelongsToItem=Record[0])
+ if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1] + '.' + Record[2]):
+ EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, OtherMsg="The PCD [%s] defined in FDF file is not related to Flash" % (Record[1] + '.' + Record[2]), BelongsToTable='Fdf', BelongsToItem=Record[0])
# Check whether PCDs used in Inf files but not specified in Dsc or FDF files
def MetaDataFileCheckPcdNoUse(self):
if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for non-specified PCDs ...")
SqlCommand = """
- select ID, Value2, BelongsToFile from Inf as A
+ select ID, Value1, Value2, BelongsToFile from Inf as A
where A.Model >= %s and Model < %s
and A.Enabled > -1
- and A.Value2 not in
- (select Value2 from Dsc as B
+ and (A.Value1, A.Value2) not in
+ (select Value1, Value2 from Dsc as B
where B.Model >= %s and B.Model < %s
and B.Enabled > -1)
- and A.Value2 not in
- (select Value2 from Fdf as C
+ and (A.Value1, A.Value2) not in
+ (select Value1, Value2 from Fdf as C
where C.Model >= %s and C.Model < %s
and C.Enabled > -1)
""" % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
for Record in RecordSet:
- if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1]):
- EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, OtherMsg="The PCD [%s] defined in INF file is not specified in either DSC or FDF files" % (Record[1]), BelongsToTable='Inf', BelongsToItem=Record[0])
+ if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1] + '.' + Record[2]):
+ EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, OtherMsg="The PCD [%s] defined in INF file is not specified in either DSC or FDF files" % (Record[1] + '.' + Record[2]), BelongsToTable='Inf', BelongsToItem=Record[0])
# Check whether having duplicate guids defined for Guid/Protocol/Ppi
def MetaDataFileCheckGuidDuplicate(self):
@@ -729,7 +804,7 @@ class Check(object): if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for no used module files ...")
SqlCommand = """
- select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1)
+ select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)
"""
InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
InfPathList = []
@@ -756,15 +831,15 @@ class Check(object): if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking for pcd type in c code function usage ...")
SqlCommand = """
- select ID, Model, Value1, BelongsToFile from INF where Model > %s and Model < %s
+ select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s
""" % (MODEL_PCD, MODEL_META_DATA_HEADER)
PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
for Pcd in PcdSet:
Model = Pcd[1]
PcdName = Pcd[2]
- if len(Pcd[2].split(".")) > 1:
- PcdName = Pcd[2].split(".")[1]
- BelongsToFile = Pcd[3]
+ if Pcd[3]:
+ PcdName = Pcd[3]
+ BelongsToFile = Pcd[4]
SqlCommand = """
select ID from File where FullPath in
(select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
@@ -809,9 +884,9 @@ class Check(object): EdkLogger.quiet("Checking for pcd type in c code function usage ...")
Table = EccGlobalData.gDb.TblInf
SqlCommand = """
- select A.ID, A.Value2, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
- where A.Value1 = 'FILE_GUID' and B.Value1 = 'FILE_GUID' and
- A.Value2 = B.Value2 and A.ID <> B.ID group by A.ID
+ select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
+ where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and
+ A.Value3 = B.Value3 and A.ID <> B.ID group by A.ID
""" % (Table.Table, Table.Table)
RecordSet = Table.Exec(SqlCommand)
for Record in RecordSet:
@@ -836,7 +911,7 @@ class Check(object): select A.ID, A.Value1 from %s as A, %s as B
where A.Model = %s and B.Model = %s
and A.Value1 = B.Value1 and A.ID <> B.ID
- and A.Arch = B.Arch
+ and A.Scope1 = B.Scope1
and A.Enabled > -1
and B.Enabled > -1
group by A.ID
@@ -857,16 +932,16 @@ class Check(object): if Model == MODEL_EFI_PPI:
Name = 'ppi'
SqlCommand = """
- select A.ID, A.Value2 from %s as A, %s as B
+ select A.ID, A.Value1, A.Value2 from %s as A, %s as B
where A.Model = %s and B.Model = %s
and A.Value2 = B.Value2 and A.ID <> B.ID
- and A.Arch = B.Arch
+ and A.Scope1 = B.Scope1 and A.Value1 <> B.Value1
group by A.ID
""" % (Table.Table, Table.Table, Model, Model)
RecordSet = Table.Exec(SqlCommand)
- for Record in RecordSet:
- if not EccGlobalData.gException.IsException(ErrorID, Record[1]):
- EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg="The %s value [%s] is used more than one time" % (Name.upper(), Record[1]), BelongsToTable=Table.Table, BelongsToItem=Record[0])
+ for Record in RecordSet:
+ if not EccGlobalData.gException.IsException(ErrorID, Record[1] + ':' + Record[2]):
+ EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg="The %s value [%s] is used more than one time" % (Name.upper(), Record[2]), BelongsToTable=Table.Table, BelongsToItem=Record[0])
# Naming Convention Check
def NamingConventionCheck(self):
diff --git a/BaseTools/Source/Python/Ecc/Configuration.py b/BaseTools/Source/Python/Ecc/Configuration.py index 1478ee6351..0ba8d732d7 100644 --- a/BaseTools/Source/Python/Ecc/Configuration.py +++ b/BaseTools/Source/Python/Ecc/Configuration.py @@ -100,7 +100,15 @@ class Configuration(object): self.HeaderCheckFile = 1
# Check whether Function header exists
self.HeaderCheckFunction = 1
-
+ # Check whether Meta data File header Comment End with '##'
+ self.HeaderCheckFileCommentEnd = 1
+ # Check whether C File header Comment content start with two spaces
+ self.HeaderCheckCFileCommentStartSpacesNum = 1
+ # Check whether C File header Comment's each reference at list should begin with a bullet character '-'
+ self.HeaderCheckCFileCommentReferenceFormat = 1
+ # Check whether C File header Comment have the License immediately after the ""Copyright"" line
+ self.HeaderCheckCFileCommentLicenseFormat = 1
+
## C Function Layout Checking
self.CFunctionLayoutCheckAll = 0
diff --git a/BaseTools/Source/Python/Ecc/Database.py b/BaseTools/Source/Python/Ecc/Database.py index 4b79cb708f..f3e2b5934a 100644 --- a/BaseTools/Source/Python/Ecc/Database.py +++ b/BaseTools/Source/Python/Ecc/Database.py @@ -26,9 +26,9 @@ from Table.TableFunction import TableFunction from Table.TablePcd import TablePcd
from Table.TableIdentifier import TableIdentifier
from Table.TableReport import TableReport
-from Table.TableInf import TableInf
-from Table.TableDec import TableDec
-from Table.TableDsc import TableDsc
+from MetaFileWorkspace.MetaFileTable import ModuleTable
+from MetaFileWorkspace.MetaFileTable import PackageTable
+from MetaFileWorkspace.MetaFileTable import PlatformTable
from Table.TableFdf import TableFdf
##
@@ -92,9 +92,9 @@ class Database(object): self.TblIdentifier = TableIdentifier(self.Cur)
self.TblPcd = TablePcd(self.Cur)
self.TblReport = TableReport(self.Cur)
- self.TblInf = TableInf(self.Cur)
- self.TblDec = TableDec(self.Cur)
- self.TblDsc = TableDsc(self.Cur)
+ self.TblInf = ModuleTable(self.Cur)
+ self.TblDec = PackageTable(self.Cur)
+ self.TblDsc = PlatformTable(self.Cur)
self.TblFdf = TableFdf(self.Cur)
#
diff --git a/BaseTools/Source/Python/Ecc/Ecc.py b/BaseTools/Source/Python/Ecc/Ecc.py index 05dba2568b..ab438c7e86 100644 --- a/BaseTools/Source/Python/Ecc/Ecc.py +++ b/BaseTools/Source/Python/Ecc/Ecc.py @@ -22,13 +22,17 @@ from MetaDataParser import * from optparse import OptionParser
from Configuration import Configuration
from Check import Check
-from Common.InfClassObject import Inf
-from Common.DecClassObject import Dec
-from Common.DscClassObject import Dsc
-from Common.FdfClassObject import Fdf
+
+
from Common.String import NormPath
from Common.BuildVersion import gBUILD_VERSION
from Common import BuildToolError
+
+from MetaFileWorkspace.MetaFileParser import DscParser
+from MetaFileWorkspace.MetaFileParser import DecParser
+from MetaFileWorkspace.MetaFileParser import InfParser
+from MetaFileWorkspace.MetaFileParser import Fdf
+from MetaFileWorkspace.MetaFileTable import MetaFileStorage
import c
import re, string
from Exception import *
@@ -53,6 +57,7 @@ class Ecc(object): self.IsInit = True
self.ScanSourceCode = True
self.ScanMetaData = True
+ self.MetaFile = ''
# Parse the options and args
self.ParseOption()
@@ -124,7 +129,6 @@ class Ecc(object): for Root, Dirs, Files in os.walk(EccGlobalData.gTarget):
if p.match(Root.upper()):
continue
-
for Dir in Dirs:
Dirname = os.path.join(Root, Dir)
if os.path.islink(Dirname):
@@ -139,19 +143,28 @@ class Ecc(object): Filename = os.path.normpath(os.path.join(Root, File))
EdkLogger.quiet("Parsing %s" % Filename)
Op.write("%s\r" % Filename)
- Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
+ #Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
+ self.MetaFile = DecParser(Filename, MODEL_FILE_DEC, EccGlobalData.gDb.TblDec)
+ self.MetaFile.Start()
continue
if len(File) > 4 and File[-4:].upper() == ".DSC":
Filename = os.path.normpath(os.path.join(Root, File))
EdkLogger.quiet("Parsing %s" % Filename)
Op.write("%s\r" % Filename)
- Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
+ #Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
+ self.MetaFile = DscParser(Filename, MODEL_FILE_DSC, MetaFileStorage(EccGlobalData.gDb.TblDsc.Cur, Filename, MODEL_FILE_DSC, True))
+ # alwasy do post-process, in case of macros change
+ self.MetaFile.DoPostProcess()
+ self.MetaFile.Start()
+ self.MetaFile._PostProcess()
continue
if len(File) > 4 and File[-4:].upper() == ".INF":
Filename = os.path.normpath(os.path.join(Root, File))
EdkLogger.quiet("Parsing %s" % Filename)
Op.write("%s\r" % Filename)
- Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
+ #Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
+ self.MetaFile = InfParser(Filename, MODEL_FILE_INF, EccGlobalData.gDb.TblInf)
+ self.MetaFile.Start()
continue
if len(File) > 4 and File[-4:].upper() == ".FDF":
Filename = os.path.normpath(os.path.join(Root, File))
diff --git a/BaseTools/Source/Python/Ecc/MetaDataParser.py b/BaseTools/Source/Python/Ecc/MetaDataParser.py index 4dda2e5360..bbafa00ddd 100644 --- a/BaseTools/Source/Python/Ecc/MetaDataParser.py +++ b/BaseTools/Source/Python/Ecc/MetaDataParser.py @@ -13,8 +13,9 @@ import os
from CommonDataClass.DataClass import *
-
-
+from EccToolError import *
+import EccGlobalData
+import re
## Get the inlcude path list for a source file
#
# 1. Find the source file belongs to which inf file
@@ -76,3 +77,188 @@ def GetTableList(FileModelList, Table, Db): return TableList
+## ParseHeaderCommentSection
+#
+# Parse Header comment section lines, extract Abstract, Description, Copyright
+# , License lines
+#
+# @param CommentList: List of (Comment, LineNumber)
+# @param FileName: FileName of the comment
+#
+def ParseHeaderCommentSection(CommentList, FileName = None):
+
+ Abstract = ''
+ Description = ''
+ Copyright = ''
+ License = ''
+ EndOfLine = "\n"
+ STR_HEADER_COMMENT_START = "@file"
+
+ #
+ # used to indicate the state of processing header comment section of dec,
+ # inf files
+ #
+ HEADER_COMMENT_NOT_STARTED = -1
+ HEADER_COMMENT_STARTED = 0
+ HEADER_COMMENT_FILE = 1
+ HEADER_COMMENT_ABSTRACT = 2
+ HEADER_COMMENT_DESCRIPTION = 3
+ HEADER_COMMENT_COPYRIGHT = 4
+ HEADER_COMMENT_LICENSE = 5
+ HEADER_COMMENT_END = 6
+ #
+ # first find the last copyright line
+ #
+ Last = 0
+ HeaderCommentStage = HEADER_COMMENT_NOT_STARTED
+ for Index in xrange(len(CommentList)-1, 0, -1):
+ Line = CommentList[Index][0]
+ if _IsCopyrightLine(Line):
+ Last = Index
+ break
+
+ for Item in CommentList:
+ Line = Item[0]
+ LineNo = Item[1]
+
+ if not Line.startswith('#') and Line:
+ SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName
+ ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
+ for Result in ResultSet:
+ Msg = 'Comment must start with #'
+ EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
+ Comment = CleanString2(Line)[1]
+ Comment = Comment.strip()
+ #
+ # if there are blank lines between License or Description, keep them as they would be
+ # indication of different block; or in the position that Abstract should be, also keep it
+ # as it indicates that no abstract
+ #
+ if not Comment and HeaderCommentStage not in [HEADER_COMMENT_LICENSE, \
+ HEADER_COMMENT_DESCRIPTION, HEADER_COMMENT_ABSTRACT]:
+ continue
+
+ if HeaderCommentStage == HEADER_COMMENT_NOT_STARTED:
+ if Comment.startswith(STR_HEADER_COMMENT_START):
+ HeaderCommentStage = HEADER_COMMENT_ABSTRACT
+ else:
+ License += Comment + EndOfLine
+ else:
+ if HeaderCommentStage == HEADER_COMMENT_ABSTRACT:
+ #
+ # in case there is no abstract and description
+ #
+ if not Comment:
+ Abstract = ''
+ HeaderCommentStage = HEADER_COMMENT_DESCRIPTION
+ elif _IsCopyrightLine(Comment):
+ Copyright += Comment + EndOfLine
+ HeaderCommentStage = HEADER_COMMENT_COPYRIGHT
+ else:
+ Abstract += Comment + EndOfLine
+ HeaderCommentStage = HEADER_COMMENT_DESCRIPTION
+ elif HeaderCommentStage == HEADER_COMMENT_DESCRIPTION:
+ #
+ # in case there is no description
+ #
+ if _IsCopyrightLine(Comment):
+ Copyright += Comment + EndOfLine
+ HeaderCommentStage = HEADER_COMMENT_COPYRIGHT
+ else:
+ Description += Comment + EndOfLine
+ elif HeaderCommentStage == HEADER_COMMENT_COPYRIGHT:
+ if _IsCopyrightLine(Comment):
+ Copyright += Comment + EndOfLine
+ else:
+ #
+ # Contents after copyright line are license, those non-copyright lines in between
+ # copyright line will be discarded
+ #
+ if LineNo > Last:
+ if License:
+ License += EndOfLine
+ License += Comment + EndOfLine
+ HeaderCommentStage = HEADER_COMMENT_LICENSE
+ else:
+ if not Comment and not License:
+ continue
+ License += Comment + EndOfLine
+
+ if not Copyright:
+ SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName
+ ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
+ for Result in ResultSet:
+ Msg = 'Header comment section must have copyright information'
+ EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
+
+ if not License:
+ SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName
+ ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
+ for Result in ResultSet:
+ Msg = 'Header comment section must have license information'
+ EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
+
+ return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip()
+
+## _IsCopyrightLine
+# check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright"
+# followed by zero or more white space characters followed by a "(" character
+#
+# @param LineContent: the line need to be checked
+# @return: True if current line is copyright line, False else
+#
+def _IsCopyrightLine (LineContent):
+ LineContent = LineContent.upper()
+ Result = False
+
+ ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL)
+ if ReIsCopyrightRe.search(LineContent):
+ Result = True
+
+ return Result
+
+
+## CleanString2
+#
+# Split comments in a string
+# Remove spaces
+#
+# @param Line: The string to be cleaned
+# @param CommentCharacter: Comment char, used to ignore comment content,
+# default is DataType.TAB_COMMENT_SPLIT
+#
+def CleanString2(Line, CommentCharacter='#', AllowCppStyleComment=False):
+ #
+ # remove whitespace
+ #
+ Line = Line.strip()
+ #
+ # Replace EDK1's comment character
+ #
+ if AllowCppStyleComment:
+ Line = Line.replace('//', CommentCharacter)
+ #
+ # separate comments and statements
+ #
+ LineParts = Line.split(CommentCharacter, 1)
+ #
+ # remove whitespace again
+ #
+ Line = LineParts[0].strip()
+ if len(LineParts) > 1:
+ Comment = LineParts[1].strip()
+ #
+ # Remove prefixed and trailing comment characters
+ #
+ Start = 0
+ End = len(Comment)
+ while Start < End and Comment.startswith(CommentCharacter, Start, End):
+ Start += 1
+ while End >= 0 and Comment.endswith(CommentCharacter, Start, End):
+ End -= 1
+ Comment = Comment[Start:End]
+ Comment = Comment.strip()
+ else:
+ Comment = ''
+
+ return Line, Comment
diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaDataTable.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaDataTable.py new file mode 100644 index 0000000000..3060698288 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaDataTable.py @@ -0,0 +1,215 @@ +## @file
+# This file is used to create/update/query/erase table for files
+#
+# Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+##
+# Import Modules
+#
+import 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 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, Cursor, Name='', IdBase=0, Temporary=False):
+ self.Cur = Cursor
+ self.Table = Name
+ self.IdBase = int(IdBase)
+ self.ID = int(IdBase)
+ self.Temporary = Temporary
+
+ def __str__(self):
+ return self.Table
+
+ ## Create table
+ #
+ # Create a table
+ #
+ def Create(self, NewTable=True):
+ if NewTable:
+ self.Drop()
+
+ if self.Temporary:
+ SqlCommand = """create temp table IF NOT EXISTS %s (%s)""" % (self.Table, self._COLUMN_)
+ else:
+ SqlCommand = """create table IF NOT EXISTS %s (%s)""" % (self.Table, self._COLUMN_)
+ EdkLogger.debug(EdkLogger.DEBUG_8, SqlCommand)
+ self.Cur.execute(SqlCommand)
+ 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_
+ Values = ", ".join([str(Arg) for Arg in Args])
+ SqlCommand = "insert into %s values(%s, %s)" % (self.Table, self.ID, Values)
+ EdkLogger.debug(EdkLogger.DEBUG_5, SqlCommand)
+ self.Cur.execute(SqlCommand)
+ return self.ID
+
+ ## Query table
+ #
+ # Query all records of the table
+ #
+ def Query(self):
+ SqlCommand = """select * from %s""" % self.Table
+ self.Cur.execute(SqlCommand)
+ for Rs in self.Cur:
+ EdkLogger.verbose(str(Rs))
+ TotalCount = self.GetId()
+
+ ## Drop a table
+ #
+ # Drop the table
+ #
+ def Drop(self):
+ SqlCommand = """drop table IF EXISTS %s""" % self.Table
+ self.Cur.execute(SqlCommand)
+
+ ## Get count
+ #
+ # Get a count of all records of the table
+ #
+ # @retval Count: Total count of all records
+ #
+ def GetCount(self):
+ SqlCommand = """select count(ID) from %s""" % self.Table
+ Record = self.Cur.execute(SqlCommand).fetchall()
+ return Record[0][0]
+
+ def GetId(self):
+ SqlCommand = """select max(ID) from %s""" % self.Table
+ Record = self.Cur.execute(SqlCommand).fetchall()
+ Id = Record[0][0]
+ if Id == 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.Cur.execute(SqlCommand)
+ RecordSet = self.Cur.fetchall()
+ return RecordSet
+
+ def SetEndFlag(self):
+ pass
+
+ def IsIntegral(self):
+ Result = self.Exec("select min(ID) from %s" % (self.Table))
+ if Result[0][0] != -1:
+ return False
+ return True
+
+ def GetAll(self):
+ return self.Exec("select * from %s where ID > 0 order by ID" % (self.Table))
+
+
+## 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 != 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.Cur.execute(SqlCommand)
+ for Item in self.Cur:
+ CrossIndex = Item[0]
+
+ return CrossIndex
+
diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py new file mode 100644 index 0000000000..fc29bafc58 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py @@ -0,0 +1,1849 @@ +## @file +# This file is used to parse meta files +# +# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR> +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +## +# Import Modules +# +import os +import re +import time +import copy + +import Common.EdkLogger as EdkLogger +import Common.GlobalData as GlobalData +import EccGlobalData + +from CommonDataClass.DataClass import * +from Common.DataType import * +from Common.String import * +from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData +from Common.Expression import * +from CommonDataClass.Exceptions import * + +from MetaFileTable import MetaFileStorage +from GenFds.FdfParser import FdfParser + +## A decorator used to parse macro definition +def ParseMacro(Parser): + def MacroParser(self): + Match = 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 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) + self._ItemType = MODEL_META_DATA_DEFINE + # DEFINE defined macros + if Type == TAB_DSC_DEFINES_DEFINE: + if type(self) == DecParser: + if MODEL_META_DATA_HEADER in self._SectionType: + self._FileLocalMacros[Name] = Value + else: + for Scope in self._Scope: + self._SectionsMacroDict.setdefault((Scope[2], Scope[0], Scope[1]), {})[Name] = Value + elif self._SectionType == MODEL_META_DATA_HEADER: + self._FileLocalMacros[Name] = Value + else: + SectionDictKey = self._SectionType, self._Scope[0][0], self._Scope[0][1] + if SectionDictKey not in self._SectionsMacroDict: + self._SectionsMacroDict[SectionDictKey] = {} + SectionLocalMacros = self._SectionsMacroDict[SectionDictKey] + SectionLocalMacros[Name] = Value + # EDK_GLOBAL defined macros + elif type(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 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) + # + def __init__(self, FilePath, FileType, Table, Owner=-1, From=-1): + self._Table = Table + self._RawTable = Table + self._FileType = FileType + self.MetaFile = FilePath + self._Defines = {} + self._FileLocalMacros = {} + self._SectionsMacroDict = {} + + # 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 + + ## 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 + ## Do not set end flag when processing included files + if self._From == -1: + self._Table.SetEndFlag() + + def _PostProcess(self): + self._PostProcessed = True + + ## Get the parse complete flag + def _GetFinished(self): + return self._Finished + + ## Set the complete flag + def _SetFinished(self, Value): + self._Finished = Value + + ## Use [] style to query data in table, just for readability + # + # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)] + # + def __getitem__(self, DataInfo): + if type(DataInfo) != type(()): + DataInfo = (DataInfo,) + + # Parse the file first, if necessary + if not self._Finished: + if self._RawTable.IsIntegrity(): + self._Finished = True + else: + self._Table = self._RawTable + self._PostProcessed = False + self.Start() + + # No specific ARCH or Platform given, use raw data + if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] == None): + return self._RawTable.Query(*DataInfo) + + # Do post-process if necessary + if not self._PostProcessed: + self._PostProcess() + + return self._Table.Query(*DataInfo) + + ## 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 type(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] + + ## 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) + # 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] + else: + self._SectionType = MODEL_UNKNOWN + EdkLogger.warn("Parser", "Unrecognized section", File=self.MetaFile, + Line=self._LineIndex+1, ExtraData=self._CurrentLine) + # S1 is always Arch + if len(ItemList) > 1: + S1 = ItemList[1].upper() + else: + S1 = 'COMMON' + ArchList.add(S1) + # S2 may be Platform or ModuleType + if len(ItemList) > 2: + S2 = ItemList[2].upper() + else: + S2 = 'COMMON' + self._Scope.append([S1, S2]) + + # 'COMMON' must not be used with specific ARCHs at the same section + if '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 + + ## [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] + # Sometimes, we need to make differences between EDK and EDK2 modules + if Name == 'INF_VERSION': + try: + self._Version = int(Value, 0) + except: + EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) + + if type(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): + 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 type(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 _GetMacros(self): + Macros = {} + Macros.update(self._FileLocalMacros) + Macros.update(self._GetApplicableSectionMacro()) + return Macros + + + ## 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 = {} + for Scope1, Scope2 in [("COMMON", "COMMON"), ("COMMON", self._Scope[0][1]), + (self._Scope[0][0], "COMMON"), (self._Scope[0][0], self._Scope[0][1])]: + if (self._SectionType, Scope1, Scope2) in self._SectionsMacroDict: + Macros.update(self._SectionsMacroDict[(self._SectionType, Scope1, Scope2)]) + return Macros + + _SectionParser = {} + Finished = property(_GetFinished, _SetFinished) + _Macros = property(_GetMacros) + + +## 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 Table Database used to retrieve module/package information + # @param Macros Macros used for replacement in file + # + def __init__(self, FilePath, FileType, Table): + # prevent re-initialization + if hasattr(self, "_Table"): + return + MetaFileParser.__init__(self, FilePath, FileType, Table) + self.TblFile = EccGlobalData.gDb.TblFile + self.FileID = -1 + + ## Parser starter + def Start(self): + NmakeLine = '' + Content = '' + try: + Content = open(str(self.MetaFile), 'r').readlines() + except: + EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) + # + # Insert a record for file + # + Filename = NormPath(self.MetaFile) + FileID = self.TblFile.GetFileId(Filename) + if FileID: + self.FileID = FileID + else: + self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_INF) + + # parse the file line by line + IsFindBlockComment = False + + for Index in range(0, len(Content)): + # skip empty, commented, block commented lines + Line = CleanString(Content[Index], AllowCppStyleComment=True) + NextLine = '' + if Index + 1 < len(Content): + NextLine = CleanString(Content[Index + 1]) + if Line == '': + continue + if Line.find(DataType.TAB_COMMENT_EDK_START) > -1: + IsFindBlockComment = True + continue + if Line.find(DataType.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: + 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 == None or self._ItemType == MODEL_META_DATA_DEFINE: + self._ItemType = -1 + continue + # + # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1, + # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1 + # + self._ValueList[0] = self._ValueList[0].replace('/', '\\') + for Arch, Platform in self._Scope: + self._Store(self._SectionType, + self._ValueList[0], + self._ValueList[1], + self._ValueList[2], + Arch, + Platform, + self._Owner[-1], + self.FileID, + self._LineIndex+1, + -1, + self._LineIndex+1, + -1, + 0 + ) + if IsFindBlockComment: + EdkLogger.error("Parser", FORMAT_INVALID, "Open block comments (starting with /*) are expected to end with */", + File=self.MetaFile) + 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 + + if Value.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1: + Value = '$(EDK_SOURCE)' + Value[17:] + if Value.find('$(EFI_SOURCE)') > -1 or Value.find('$(EDK_SOURCE)') > -1: + pass + elif Value.startswith('.'): + pass + elif Value.startswith('$('): + pass + else: + Value = '$(EFI_SOURCE)/' + Value + + 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) + 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); + + ## [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._Skip, + } + +## 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_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION, + 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_COMPONENTS_SOURCE_OVERRIDE_PATH.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, + 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, + } + + # Valid names in define section + DefineKeywords = [ + "DSC_SPECIFICATION", + "PLATFORM_NAME", + "PLATFORM_GUID", + "PLATFORM_VERSION", + "SKUID_IDENTIFIER", + "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" + ] + + SymbolPattern = ValueExpression.SymbolPattern + + ## Constructor of DscParser + # + # Initialize object of DscParser + # + # @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) + # + def __init__(self, FilePath, FileType, Table, Owner=-1, From=-1): + # prevent re-initialization + if hasattr(self, "_Table"): + return + MetaFileParser.__init__(self, FilePath, FileType, 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 + + # 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.TblFile = EccGlobalData.gDb.TblFile + self.FileID = -1 + + ## Parser starter + def Start(self): + Content = '' + try: + Content = open(str(self.MetaFile), 'r').readlines() + except: + EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) + # + # Insert a record for file + # + Filename = NormPath(self.MetaFile) + FileID = self.TblFile.GetFileId(Filename) + if FileID: + self.FileID = FileID + else: + self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_DSC) + + + 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 + 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] == '!': + self._DirectiveParser() + continue + + if self._InSubsection: + SectionType = self._SubsectionType + else: + SectionType = self._SectionType + self._ItemType = SectionType + + self._ValueList = ['', '', ''] + self._SectionParser[SectionType](self) + if self._ValueList == 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 in self._Scope: + self._LastItem = self._Store( + self._ItemType, + self._ValueList[0], + self._ValueList[1], + self._ValueList[2], + Arch, + ModuleType, + self._Owner[-1], + self.FileID, + self._From, + self._LineIndex+1, + -1, + self._LineIndex+1, + -1, + self._Enabled + ) + + 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', '!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] + 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 != MODEL_META_DATA_INCLUDE: + # 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)) + elif self._From > 0: + EdkLogger.error('Parser', FORMAT_INVALID, + "No '!include' allowed in included file", + ExtraData=self._CurrentLine, File=self.MetaFile, + Line=self._LineIndex+1) + + # + # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1, + # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1 + # + self._LastItem = self._Store( + ItemType, + self._ValueList[0], + self._ValueList[1], + self._ValueList[2], + 'COMMON', + 'COMMON', + self._Owner[-1], + self.FileID, + 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: + 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) + 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) != 2: + EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Integer>|<UiName>'", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) + self._ValueList[0:len(TokenList)] = TokenList + + ## Parse Edk style of library modules + def _LibraryInstanceParser(self): + self._ValueList[0] = self._CurrentLine + + ## PCD sections parser + # + # [PcdsFixedAtBuild] + # [PcdsPatchableInModule] + # [PcdsFeatureFlag] + # [PcdsDynamicEx + # [PcdsDynamicExDefault] + # [PcdsDynamicExVpd] + # [PcdsDynamicExHii] + # [PcdsDynamic] + # [PcdsDynamicDefault] + # [PcdsDynamicVpd] + # [PcdsDynamicHii] + # + @ParseMacro + def _PcdParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) + self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) + 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] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given", + ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)", + 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 + 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 + + def _CompponentSourceOverridePathParser(self): + self._ValueList[0] = self._CurrentLine + + ## [BuildOptions] section parser + @ParseMacro + def _BuildOptionParser(self): + 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 + def _GetMacros(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) + 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_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_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_COMPONENT_SOURCE_OVERRIDE_PATH : self.__ProcessSourceOverridePath, + MODEL_META_DATA_BUILD_OPTION : self.__ProcessBuildOption, + MODEL_UNKNOWN : self._Skip, + MODEL_META_DATA_USER_EXTENSION : self._Skip, + } + + self._RawTable = self._Table + self._Table = MetaFileStorage(self._RawTable.Cur, self.MetaFile, MODEL_FILE_DSC, True) + self._DirectiveStack = [] + self._DirectiveEvalStack = [] + self._FileWithError = self.MetaFile + self._FileLocalMacros = {} + self._SectionsMacroDict = {} + GlobalData.gPlatformDefines = {} + + # Get all macro and PCD which has straitforward value + self.__RetrievePcdValue() + self._Content = self._RawTable.GetAll() + self._ContentIndex = 0 + while self._ContentIndex < len(self._Content) : + Id, self._ItemType, V1, V2, V3, S1, S2, Owner, BelongsToFile, 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]] + self._LineIndex = LineStart - 1 + self._ValueList = [V1, V2, V3] + + try: + Processer[self._ItemType]() + except EvaluationException, Excpt: + # + # Only catch expression evaluation error here. We need to report + # the precise number of line on which the error occurred + # + EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt), + File=self._FileWithError, ExtraData=' '.join(self._ValueList), + Line=self._LineIndex+1) + except MacroException, Excpt: + EdkLogger.error('Parser', FORMAT_INVALID, str(Excpt), + File=self._FileWithError, ExtraData=' '.join(self._ValueList), + Line=self._LineIndex+1) + + if self._ValueList == 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, + NewOwner, + BelongsToFile, + self._From, + self._LineIndex+1, + -1, + self._LineIndex+1, + -1, + self._Enabled + ) + self._IdMapping[Id] = self._LastItem + + RecordList = self._Table.GetAll() + for Record in RecordList: + EccGlobalData.gDb.TblDsc.Insert(Record[1],Record[2],Record[3],Record[4],Record[5],Record[6],Record[7],Record[8],Record[9],Record[10],Record[11],Record[12],Record[13],Record[14]) + GlobalData.gPlatformDefines.update(self._FileLocalMacros) + self._PostProcessed = True + self._Content = None + + 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): + Records = self._RawTable.Query(MODEL_PCD_FEATURE_FLAG, BelongsToItem=-1.0) + for TokenSpaceGuid,PcdName,Value,Dummy2,Dummy3,ID,Line in Records: + Value, DatumType, MaxDatumSize = AnalyzePcdData(Value) + # Only use PCD whose value is straitforward (no macro and PCD) + if self.SymbolPattern.findall(Value): + continue + Name = TokenSpaceGuid + '.' + PcdName + # Don't use PCD with different values. + if Name in self._Symbols and self._Symbols[Name] != Value: + self._Symbols.pop(Name) + continue + self._Symbols[Name] = Value + + Records = self._RawTable.Query(MODEL_PCD_FIXED_AT_BUILD, BelongsToItem=-1.0) + for TokenSpaceGuid,PcdName,Value,Dummy2,Dummy3,ID,Line in Records: + Value, DatumType, MaxDatumSize = AnalyzePcdData(Value) + # Only use PCD whose value is straitforward (no macro and PCD) + if self.SymbolPattern.findall(Value): + continue + Name = TokenSpaceGuid+'.'+PcdName + # Don't use PCD with different values. + if Name in self._Symbols and self._Symbols[Name] != Value: + self._Symbols.pop(Name) + continue + self._Symbols[Name] = Value + + def __ProcessDefine(self): + if not self._Enabled: + return + + Type, Name, Value = self._ValueList + Value = ReplaceMacro(Value, self._Macros, False) + if self._ItemType == MODEL_META_DATA_DEFINE: + if self._SectionType == MODEL_META_DATA_HEADER: + self._FileLocalMacros[Name] = Value + else: + SectionDictKey = self._SectionType, self._Scope[0][0], self._Scope[0][1] + if SectionDictKey not in self._SectionsMacroDict: + self._SectionsMacroDict[SectionDictKey] = {} + SectionLocalMacros = self._SectionsMacroDict[SectionDictKey] + SectionLocalMacros[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, Exc: + EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc), self._ValueList[1]) + Result = False + except WrnExpression, 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[-1] = self._ItemType + self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1] + 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_ELSE, + 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'] + if "ECP_SOURCE" in GlobalData.gGlobalDefines.keys(): + __IncludeMacros['ECP_SOURCE'] = GlobalData.gGlobalDefines['ECP_SOURCE'] + # + # During GenFds phase call DSC parser, will go into this branch. + # + elif "ECP_SOURCE" in GlobalData.gCommandLineDefines.keys(): + __IncludeMacros['ECP_SOURCE'] = GlobalData.gCommandLineDefines['ECP_SOURCE'] + + __IncludeMacros['EFI_SOURCE'] = GlobalData.gGlobalDefines['EFI_SOURCE'] + __IncludeMacros['EDK_SOURCE'] = GlobalData.gGlobalDefines['EDK_SOURCE'] + # + # 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) + 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 + + IncludedFileTable = MetaFileStorage(self._Table.Cur, IncludedFile1, MODEL_FILE_DSC, True) + Owner = self._Content[self._ContentIndex-1][0] + Parser = DscParser(IncludedFile1, self._FileType, IncludedFileTable, + Owner=Owner, From=Owner) + + # set the parser status with current status + Parser._SectionName = self._SectionName + Parser._SectionType = self._SectionType + Parser._Scope = self._Scope + Parser._Enabled = self._Enabled + # Parse the included file + Parser.Start() + + # update current status with sub-parser's status + self._SectionName = Parser._SectionName + self._SectionType = Parser._SectionType + self._Scope = Parser._Scope + self._Enabled = Parser._Enabled + + # 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 __ProcessSkuId(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): + ValueList = GetSplitValueList(self._ValueList[2]) + # + # PCD value can be an expression + # + if len(ValueList) > 1 and ValueList[1] == 'VOID*': + PcdValue = ValueList[0] + try: + ValueList[0] = ValueExpression(PcdValue, self._Macros)(True) + except WrnExpression, Value: + ValueList[0] = Value.result + else: + PcdValue = ValueList[-1] + try: + ValueList[-1] = ValueExpression(PcdValue, self._Macros)(True) + except WrnExpression, Value: + ValueList[-1] = Value.result + + if ValueList[-1] == 'True': + ValueList[-1] = '1' + if ValueList[-1] == 'False': + ValueList[-1] = '0' + + self._ValueList[2] = '|'.join(ValueList) + + def __ProcessComponent(self): + self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros) + + def __ProcessSourceOverridePath(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] + + _SectionParser = { + MODEL_META_DATA_HEADER : _DefineParser, + MODEL_EFI_SKU_ID : _SkuIdParser, + 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_COMPONENT_SOURCE_OVERRIDE_PATH : _CompponentSourceOverridePathParser, + MODEL_META_DATA_BUILD_OPTION : _BuildOptionParser, + MODEL_UNKNOWN : MetaFileParser._Skip, + MODEL_META_DATA_USER_EXTENSION : MetaFileParser._Skip, + MODEL_META_DATA_SECTION_HEADER : MetaFileParser._SectionHeaderParser, + MODEL_META_DATA_SUBSECTION_HEADER : _SubsectionHeaderParser, + } + + _Macros = property(_GetMacros) + +## 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, + } + + ## Constructor of DecParser + # + # Initialize object of DecParser + # + # @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 + # + def __init__(self, FilePath, FileType, Table): + # prevent re-initialization + if hasattr(self, "_Table"): + return + MetaFileParser.__init__(self, FilePath, FileType, Table) + self._Comments = [] + self._Version = 0x00010005 # Only EDK2 dec file is supported + self.TblFile = EccGlobalData.gDb.TblFile + self.FileID = -1 + + ## Parser starter + def Start(self): + Content = '' + try: + Content = open(str(self.MetaFile), 'r').readlines() + except: + EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) + + # + # Insert a record for file + # + Filename = NormPath(self.MetaFile) + FileID = self.TblFile.GetFileId(Filename) + if FileID: + self.FileID = FileID + else: + self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_DEC) + + 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() + self._Comments = [] + continue + elif len(self._SectionType) == 0: + self._Comments = [] + continue + + # section content + self._ValueList = ['','',''] + self._SectionParser[self._SectionType[0]](self) + if self._ValueList == 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.FileID, + 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, + self.FileID, + LineNo, + -1, + LineNo, + -1, + 0 + ) + self._Comments = [] + self._Done() + + def _GetApplicableSectionMacro(self): + Macros = {} + for S1, S2, SectionType in self._Scope: + for Scope1, Scope2 in [("COMMON", "COMMON"), ("COMMON", S2), (S1, "COMMON"), (S1, S2)]: + if (SectionType, Scope1, Scope2) in self._SectionsMacroDict: + Macros.update(self._SectionsMacroDict[(SectionType, Scope1, Scope2)]) + return Macros + + ## 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() + for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT): + if Item == '': + continue + ItemList = GetSplitValueList(Item, TAB_SPLIT) + + # different types of PCD are permissible in one section + self._SectionName = ItemList[0].upper() + if self._SectionName in self.DataType: + if self.DataType[self._SectionName] not in self._SectionType: + self._SectionType.append(self.DataType[self._SectionName]) + else: + EdkLogger.warn("Parser", "Unrecognized section", File=self.MetaFile, + Line=self._LineIndex+1, ExtraData=self._CurrentLine) + continue + + 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 = 'COMMON' + ArchList.add(S1) + # S2 may be Platform or ModuleType + if len(ItemList) > 2: + S2 = ItemList[2].upper() + else: + S2 = 'COMMON' + 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 '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) + + ## [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] + #Parse the Guid value format + GuidValueList = TokenList[1].strip(' {}').split(',') + Index = 0 + HexList = [] + if len(GuidValueList) == 11: + for GuidValue in GuidValueList: + GuidValue = GuidValue.strip() + if GuidValue.startswith('0x') or GuidValue.startswith('0X'): + HexList.append('0x' + str(GuidValue[2:])) + Index += 1 + continue + else: + if GuidValue.startswith('{'): + HexList.append('0x' + str(GuidValue[3:])) + Index += 1 + self._ValueList[1] = "{ %s, %s, %s, { %s, %s, %s, %s, %s, %s, %s, %s }}" % (HexList[0], HexList[1], HexList[2],HexList[3],HexList[4],HexList[5],HexList[6],HexList[7],HexList[8],HexList[9],HexList[10]) + else: + 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] = '' + + ## PCD sections parser + # + # [PcdsFixedAtBuild] + # [PcdsPatchableInModule] + # [PcdsFeatureFlag] + # [PcdsDynamicEx + # [PcdsDynamic] + # + @ParseMacro + def _PcdParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) + self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) + # 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 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 = GetSplitValueList(ptrValueList) + ValueList[0] = PtrValue[0] + else: + ValueList = GetSplitValueList(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) + # 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 ValueList[0] in ['True', 'true', 'TRUE']: + ValueList[0] = '1' + elif ValueList[0] in ['False', 'false', 'FALSE']: + ValueList[0] = '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._Skip, + } + + +## FdfObject +# +# This class defined basic Fdf object which is used by inheriting +# +# @param object: Inherited from object class +# +class FdfObject(object): + def __init__(self): + object.__init__() + +## Fdf +# +# This class defined the structure used in Fdf object +# +# @param FdfObject: Inherited from FdfObject class +# @param Filename: Input value for Ffilename of Fdf file, default is None +# @param WorkspaceDir: Input value for current workspace directory, default is None +# +class Fdf(FdfObject): + def __init__(self, Filename = None, IsToDatabase = False, WorkspaceDir = None, Database = None): + self.WorkspaceDir = WorkspaceDir + self.IsToDatabase = IsToDatabase + + self.Cur = Database.Cur + self.TblFile = Database.TblFile + self.TblFdf = Database.TblFdf + self.FileID = -1 + self.FileList = {} + + # + # Load Fdf file if filename is not None + # + if Filename != None: + self.LoadFdfFile(Filename) + + # + # Insert a FDF file record into database + # + def InsertFile(self, Filename): + FileID = -1 + Filename = NormPath(Filename) + if Filename not in self.FileList: + FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_FDF) + self.FileList[Filename] = FileID + + return self.FileList[Filename] + + + ## Load Fdf file + # + # Load the file if it exists + # + # @param Filename: Input value for filename of Fdf file + # + def LoadFdfFile(self, Filename): + FileList = [] + # + # Parse Fdf file + # + Filename = NormPath(Filename) + Fdf = FdfParser(Filename) + Fdf.ParseFile() + + # + # Insert inf file and pcd information + # + if self.IsToDatabase: + (Model, Value1, Value2, Value3, Scope1, Scope2, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) = \ + (0, '', '', '', 'COMMON', 'COMMON', -1, -1, -1, -1, -1, -1, 0) + for Index in range(0, len(Fdf.Profile.PcdDict)): + pass + for Key in Fdf.Profile.PcdDict.keys(): + Model = MODEL_PCD + Value1 = Key[1] + Value2 = Key[0] + FileName = Fdf.Profile.PcdFileLineDict[Key][0] + StartLine = Fdf.Profile.PcdFileLineDict[Key][1] + BelongsToFile = self.InsertFile(FileName) + self.TblFdf.Insert(Model, Value1, Value2, Value3, Scope1, Scope2, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) + for Index in range(0, len(Fdf.Profile.InfList)): + Model = MODEL_META_DATA_COMPONENT + Value1 = Fdf.Profile.InfList[Index] + Value2 = '' + FileName = Fdf.Profile.InfFileLineList[Index][0] + StartLine = Fdf.Profile.InfFileLineList[Index][1] + BelongsToFile = self.InsertFile(FileName) + self.TblFdf.Insert(Model, Value1, Value2, Value3, Scope1, Scope2, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) + +## +# +# 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/Ecc/MetaFileWorkspace/MetaFileTable.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileTable.py new file mode 100644 index 0000000000..89bc7f262f --- /dev/null +++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileTable.py @@ -0,0 +1,332 @@ +## @file
+# This file is used to create/update/query/erase a meta file table
+#
+# Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+##
+# Import Modules
+#
+import uuid
+
+import Common.EdkLogger as EdkLogger
+import EccGlobalData
+
+from MetaDataTable import Table
+from MetaDataTable import ConvertToSqlString
+from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \
+ MODEL_FILE_OTHERS
+
+class MetaFileTable(Table):
+ ## Constructor
+ def __init__(self, Cursor, MetaFile, FileType, TableName, Temporary = False):
+ self.MetaFile = MetaFile
+ self.TblFile = EccGlobalData.gDb.TblFile
+ if (FileType == MODEL_FILE_INF):
+ TableName = "Inf"
+ if (FileType == MODEL_FILE_DSC):
+ if Temporary:
+ TableName = "_%s_%s" % ("Dsc", uuid.uuid4().hex)
+ else:
+ TableName = "Dsc"
+ if (FileType == MODEL_FILE_DEC):
+ TableName = "Dec"
+
+ Table.__init__(self, Cursor, TableName, 0, Temporary)
+ self.Create(False)
+
+
+## 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,
+ BelongsToFile SINGLE 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):
+ MetaFileTable.__init__(self, Cursor, '', MODEL_FILE_INF, "Inf", False)
+
+ ## 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='COMMON', Scope2='COMMON',
+ BelongsToItem=-1, BelongsToFile = -1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
+ (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))
+ return Table.Insert(
+ self,
+ Model,
+ Value1,
+ Value2,
+ Value3,
+ Scope1,
+ Scope2,
+ BelongsToItem,
+ BelongsToFile,
+ StartLine,
+ StartColumn,
+ EndLine,
+ EndColumn,
+ Enabled
+ )
+
+ ## 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):
+ ConditionString = "Model=%s AND Enabled>=0" % Model
+ ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"
+
+ if Arch != None and Arch != 'COMMON':
+ ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch
+ if Platform != None and Platform != 'COMMON':
+ ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform
+
+ SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
+ return self.Exec(SqlCommand)
+
+## 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,
+ BelongsToFile SINGLE 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):
+ MetaFileTable.__init__(self, Cursor, '', MODEL_FILE_DEC, "Dec", False)
+
+ ## 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='COMMON', Scope2='COMMON',
+ BelongsToItem=-1, BelongsToFile = -1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
+ (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))
+ return Table.Insert(
+ self,
+ Model,
+ Value1,
+ Value2,
+ Value3,
+ Scope1,
+ Scope2,
+ BelongsToItem,
+ BelongsToFile,
+ StartLine,
+ StartColumn,
+ EndLine,
+ EndColumn,
+ Enabled
+ )
+
+ ## 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):
+ ConditionString = "Model=%s AND Enabled>=0" % Model
+ ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine"
+
+ if Arch != None and Arch != 'COMMON':
+ ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch
+
+ SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
+ return self.Exec(SqlCommand)
+
+## 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,
+ BelongsToItem REAL NOT NULL,
+ BelongsToFile SINGLE 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, -1"
+
+ ## Constructor
+ def __init__(self, Cursor, MetaFile = '', FileType = MODEL_FILE_DSC, Temporary = False):
+ MetaFileTable.__init__(self, Cursor, MetaFile, FileType, "Dsc", Temporary)
+
+ ## 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='COMMON', Scope2='COMMON', BelongsToItem=-1, BelongsToFile = -1,
+ FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):
+ (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))
+ return Table.Insert(
+ self,
+ Model,
+ Value1,
+ Value2,
+ Value3,
+ Scope1,
+ Scope2,
+ BelongsToItem,
+ BelongsToFile,
+ FromItem,
+ StartLine,
+ StartColumn,
+ EndLine,
+ EndColumn,
+ Enabled
+ )
+
+ ## 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):
+ ConditionString = "Model=%s AND Enabled>0" % Model
+ ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"
+
+ if Scope1 != None and Scope1 != 'COMMON':
+ ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1
+ if Scope2 != None and Scope2 != 'COMMON':
+ ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Scope2
+
+ if BelongsToItem != None:
+ ConditionString += " AND BelongsToItem=%s" % BelongsToItem
+ else:
+ ConditionString += " AND BelongsToItem<0"
+
+ if FromItem != None:
+ ConditionString += " AND FromItem=%s" % FromItem
+
+ SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
+ return self.Exec(SqlCommand)
+
+## 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,
+ }
+
+ ## Constructor
+ def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False):
+ # no type given, try to find one
+ 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, FileType, Temporary)
+
+ # create the storage object and return it to caller
+ return Class._FILE_TABLE_[FileType](*Args)
+
diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/__init__.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/__init__.py new file mode 100644 index 0000000000..05cd34bad5 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/__init__.py @@ -0,0 +1,15 @@ +## @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>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
diff --git a/BaseTools/Source/Python/Ecc/c.py b/BaseTools/Source/Python/Ecc/c.py index 532f4a0918..ea7d99fecd 100644 --- a/BaseTools/Source/Python/Ecc/c.py +++ b/BaseTools/Source/Python/Ecc/c.py @@ -2305,28 +2305,90 @@ def CheckFileHeaderDoxygenComments(FullFileName): """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)
ResultSet = Db.TblFile.Exec(SqlStatement)
if len(ResultSet) == 0:
- PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No Comment appear at the very beginning of file.', 'File', FileID)
+ PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)
return ErrorMsgList
- IsFoundError1 = True
- IsFoundError2 = True
- IsFoundError3 = True
+ NoHeaderCommentStartFlag = True
+ NoHeaderCommentEndFlag = True
+ NoHeaderCommentPeriodFlag = True
+ NoCopyrightFlag = True
+ NoLicenseFlag = True
+ NoRevReferFlag = True
+ NextLineIndex = 0
for Result in ResultSet:
+ FileStartFlag = False
+ CommentStrList = []
CommentStr = Result[0].strip()
+ CommentStrListTemp = CommentStr.split('\n')
+ if (len(CommentStrListTemp) <= 1):
+ # For Mac
+ CommentStrListTemp = CommentStr.split('\r')
+ # Skip the content before the file header
+ for CommentLine in CommentStrListTemp:
+ if CommentLine.strip().startswith('/** @file'):
+ FileStartFlag = True
+ if FileStartFlag == True:
+ CommentStrList.append(CommentLine)
+
ID = Result[1]
- if CommentStr.startswith('/** @file'):
- IsFoundError1 = False
- if CommentStr.endswith('**/'):
- IsFoundError2 = False
- if CommentStr.find('.') != -1:
- IsFoundError3 = False
-
- if IsFoundError1:
+ Index = 0
+ if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):
+ NoHeaderCommentStartFlag = False
+ else:
+ continue
+ if CommentStrList and CommentStrList[-1].strip().endswith('**/'):
+ NoHeaderCommentEndFlag = False
+ else:
+ continue
+
+ for CommentLine in CommentStrList:
+ Index = Index + 1
+ NextLineIndex = Index
+ if CommentLine.startswith('/** @file'):
+ continue
+ if CommentLine.startswith('**/'):
+ break
+ # Check whether C File header Comment content start with two spaces.
+ if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
+ if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith(' ') == False:
+ PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID)
+
+ CommentLine = CommentLine.strip()
+ if CommentLine.startswith('Copyright'):
+ NoCopyrightFlag = False
+ if CommentLine.find('All rights reserved') == -1:
+ PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID)
+ if CommentLine.endswith('<BR>') == -1:
+ PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'The ""<BR>"" at the end of the Copyright line is required', FileTable, ID)
+ if NextLineIndex < len(CommentStrList) and CommentStrList[NextLineIndex].strip().startswith('Copyright') == False and CommentStrList[NextLineIndex].strip():
+ NoLicenseFlag = False
+ if CommentLine.startswith('@par Revision Reference:'):
+ NoRevReferFlag = False
+ RefListFlag = False
+ for RefLine in CommentStrList[NextLineIndex:]:
+ if RefLine.strip() and (NextLineIndex + 1) < len(CommentStrList) and CommentStrList[NextLineIndex+1].strip() and CommentStrList[NextLineIndex+1].strip().startswith('**/') == False:
+ RefListFlag = True
+ if RefLine.strip() == False or RefLine.strip().startswith('**/'):
+ RefListFlag = False
+ break
+ # Check whether C File header Comment's each reference at list should begin with a bullet character.
+ if EccGlobalData.gConfig.HeaderCheckCFileCommentReferenceFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
+ if RefListFlag == True:
+ if RefLine.strip() and RefLine.strip().startswith('**/') == False and RefLine.startswith(' -') == False:
+ PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'Each reference on a separate line should begin with a bullet character ""-"" ', FileTable, ID)
+
+ if NoHeaderCommentStartFlag:
PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)
- if IsFoundError2:
+ return
+ if NoHeaderCommentEndFlag:
PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with ""**/""', FileTable, ID)
- if IsFoundError3:
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period "".""', FileTable, ID)
+ return
+ if NoCopyrightFlag:
+ PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment missing the ""Copyright""', FileTable, ID)
+ #Check whether C File header Comment have the License immediately after the ""Copyright"" line.
+ if EccGlobalData.gConfig.HeaderCheckCFileCommentLicenseFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
+ if NoLicenseFlag:
+ PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should have the License immediately after the ""Copyright"" line', FileTable, ID)
def CheckFuncHeaderDoxygenComments(FullFileName):
ErrorMsgList = []
diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini index 357c52ced0..c55276fce7 100644 --- a/BaseTools/Source/Python/Ecc/config.ini +++ b/BaseTools/Source/Python/Ecc/config.ini @@ -97,6 +97,14 @@ HeaderCheckAll = 0 HeaderCheckFile = 1
# Check whether Function header exists
HeaderCheckFunction = 1
+# Check whether Meta data File header Comment End with '##'
+HeaderCheckFileCommentEnd = 0
+# Check whether C File header Comment content start with two spaces
+HeaderCheckCFileCommentStartSpacesNum = 0
+# Check whether C File header Comment's each reference at list should begin with a bullet character '-'
+HeaderCheckCFileCommentReferenceFormat = 0
+# Check whether C File header Comment have the License immediately after the ""Copyright"" line
+HeaderCheckCFileCommentLicenseFormat = 0
#
# C Function Layout Checking
diff --git a/BaseTools/Source/Python/Eot/Parser.py b/BaseTools/Source/Python/Eot/Parser.py index 5ad00cfbb0..d5419d0e06 100644 --- a/BaseTools/Source/Python/Eot/Parser.py +++ b/BaseTools/Source/Python/Eot/Parser.py @@ -22,6 +22,7 @@ from CommonDataClass.DataClass import * from Common.String import CleanString, GetSplitValueList, ReplaceMacro
import EotGlobalData
from Common.Misc import sdict
+from Common.String import GetSplitList
## PreProcess() method
#
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index d3d50b638e..bdb7a77770 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -52,6 +52,8 @@ from Common.Expression import * from Common import GlobalData
from Common.String import ReplaceMacro
+from Common.Misc import tdict
+
import re
import os
@@ -77,10 +79,6 @@ RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<s RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
IncludeFileList = []
-# Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF
-InputMacroDict = {}
-# All Macro values when parsing file, not replace existing Macro
-AllMacroList = []
def GetRealFileLine (File, Line):
@@ -182,7 +180,10 @@ class FileProfile : self.PcdDict = {}
self.InfList = []
-
+ # ECC will use this Dict and List information
+ self.PcdFileLineDict = {}
+ self.InfFileLineList = []
+
self.FdDict = {}
self.FdNameNotSet = False
self.FvDict = {}
@@ -215,14 +216,17 @@ class FdfParser: self.__Token = ""
self.__SkippedChars = ""
+ # Used to section info
+ self.__CurSection = []
+ # Key: [section name, UI name, arch]
+ # Value: {MACRO_NAME : MACRO_VALUE}
+ self.__MacroDict = tdict(True, 3)
+ self.__PcdDict = {}
+
self.__WipeOffArea = []
if GenFdsGlobalVariable.WorkSpaceDir == '':
GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")
- InputMacroDict.update(GlobalData.gPlatformDefines)
- InputMacroDict.update(GlobalData.gGlobalDefines)
- InputMacroDict.update(GlobalData.gCommandLineDefines)
-
## __IsWhiteSpace() method
#
# Whether char at current FileBufferPos is whitespace
@@ -381,30 +385,6 @@ class FdfParser: self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
self.Profile.FileLinesList[-1].append(' ')
- def __ReplaceMacros(self, Str, File, Line):
- MacroEnd = 0
- while Str.find('$(', MacroEnd) >= 0:
- MacroStart = Str.find('$(', MacroEnd)
- if Str.find(')', MacroStart) > 0:
- MacroEnd = Str.find(')', MacroStart)
- Name = Str[MacroStart + 2 : MacroEnd]
- Value = None
- if Name in InputMacroDict:
- Value = InputMacroDict[Name]
-
- else:
- for Profile in AllMacroList:
- if Profile.FileName == File and Profile.MacroName == Name and Profile.DefinedAtLine <= Line:
- Value = Profile.MacroValue
-
- if Value != None:
- Str = Str.replace('$(' + Name + ')', Value)
- MacroEnd = MacroStart + len(Value)
-
- else:
- raise Warning("Macro not complete", self.FileName, self.CurrentLineNumber)
- return Str
-
def __ReplaceFragment(self, StartPos, EndPos, Value = ' '):
if StartPos[0] == EndPos[0]:
Offset = StartPos[1]
@@ -446,7 +426,67 @@ class FdfParser: self.FileName, self.CurrentLineNumber)
MacroName = MacroName[2:-1]
return MacroName, NotFlag
-
+
+ def __SetMacroValue(self, Macro, Value):
+ if not self.__CurSection:
+ return
+
+ MacroDict = {}
+ if not self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]:
+ self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] = MacroDict
+ else:
+ MacroDict = self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]
+ MacroDict[Macro] = Value
+
+ def __GetMacroValue(self, Macro):
+ # Highest priority
+ if Macro in GlobalData.gCommandLineDefines:
+ return GlobalData.gCommandLineDefines[Macro]
+ if Macro in GlobalData.gGlobalDefines:
+ return GlobalData.gGlobalDefines[Macro]
+
+ if self.__CurSection:
+ MacroDict = self.__MacroDict[
+ self.__CurSection[0],
+ self.__CurSection[1],
+ self.__CurSection[2]
+ ]
+ if MacroDict and Macro in MacroDict:
+ return MacroDict[Macro]
+
+ # Lowest priority
+ if Macro in GlobalData.gPlatformDefines:
+ return GlobalData.gPlatformDefines[Macro]
+ return None
+
+ def __SectionHeaderParser(self, Section):
+ # [Defines]
+ # [FD.UiName]: use dummy instead if UI name is optional
+ # [FV.UiName]
+ # [Capsule.UiName]
+ # [Rule]: don't take rule section into account, macro is not allowed in this section
+ # [VTF.arch.UiName, arch]
+ # [OptionRom.DriverName]
+ self.__CurSection = []
+ Section = Section.strip()[1:-1].upper().replace(' ', '').strip('.')
+ ItemList = Section.split('.')
+ Item = ItemList[0]
+ if Item == '' or Item == 'RULE':
+ return
+
+ if Item == 'DEFINES':
+ self.__CurSection = ['COMMON', 'COMMON', 'COMMON']
+ elif Item == 'VTF' and len(ItemList) == 3:
+ UiName = ItemList[2]
+ Pos = UiName.find(',')
+ if Pos != -1:
+ UiName = UiName[:Pos]
+ self.__CurSection = ['VTF', UiName, ItemList[1]]
+ elif len(ItemList) > 1:
+ self.__CurSection = [ItemList[0], ItemList[1], 'COMMON']
+ elif len(ItemList) > 0:
+ self.__CurSection = [ItemList[0], 'DUMMY', 'COMMON']
+
## PreprocessFile() method
#
# Preprocess file contents, replace comments with spaces.
@@ -530,12 +570,17 @@ class FdfParser: raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)
IncFileName = self.__Token
__IncludeMacros = {}
- __IncludeMacros['WORKSPACE'] = InputMacroDict['WORKSPACE']
- __IncludeMacros['ECP_SOURCE'] = InputMacroDict['ECP_SOURCE']
- __IncludeMacros['EFI_SOURCE'] = InputMacroDict['EFI_SOURCE']
- __IncludeMacros['EDK_SOURCE'] = InputMacroDict['EDK_SOURCE']
-
- IncludedFile = NormPath(ReplaceMacro(IncFileName, __IncludeMacros, RaiseError=True))
+ for Macro in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']:
+ MacroVal = self.__GetMacroValue(Macro)
+ if MacroVal:
+ __IncludeMacros[Macro] = MacroVal
+
+ try:
+ IncludedFile = NormPath(ReplaceMacro(IncFileName, __IncludeMacros, RaiseError=True))
+ except:
+ raise Warning("only these system environment variables are permitted to start the path of the included file: "
+ "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)",
+ self.FileName, self.CurrentLineNumber)
#
# First search the include file under the same directory as FDF file
#
@@ -545,7 +590,12 @@ class FdfParser: #
# Then search the include file under the same directory as DSC file
#
- IncludedFile1 = PathClass(IncludedFile, GenFdsGlobalVariable.ActivePlatform.Dir)
+ PlatformDir = ''
+ if GenFdsGlobalVariable.ActivePlatform:
+ PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir
+ elif GlobalData.gActivePlatform:
+ PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir
+ IncludedFile1 = PathClass(IncludedFile, PlatformDir)
ErrorCode = IncludedFile1.Validate()[0]
if ErrorCode != 0:
#
@@ -554,7 +604,7 @@ class FdfParser: IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)
ErrorCode = IncludedFile1.Validate()[0]
if ErrorCode != 0:
- raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os.path.dirname(self.FileName), GenFdsGlobalVariable.ActivePlatform.Dir, GlobalData.gWorkspace),
+ raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os.path.dirname(self.FileName), PlatformDir, GlobalData.gWorkspace),
self.FileName, self.CurrentLineNumber)
IncFileProfile = IncludeFileProfile(IncludedFile1.Path)
@@ -608,9 +658,47 @@ class FdfParser: # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
IfList = []
RegionLayoutLine = 0
+ ReplacedLine = -1
while self.__GetNextToken():
+ # Determine section name and the location dependent macro
+ if self.__GetIfListCurrentItemStat(IfList):
+ if self.__Token.startswith('['):
+ Header = self.__Token
+ if not self.__Token.endswith(']'):
+ self.__SkipToToken(']')
+ Header += self.__SkippedChars
+ if Header.find('$(') != -1:
+ raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)
+ self.__SectionHeaderParser(Header)
+ continue
+ # Replace macros except in RULE section or out of section
+ elif self.__CurSection and ReplacedLine != self.CurrentLineNumber:
+ ReplacedLine = self.CurrentLineNumber
+ self.__UndoToken()
+ CurLine = self.Profile.FileLinesList[ReplacedLine - 1]
+ PreIndex = 0
+ StartPos = CurLine.find('$(', PreIndex)
+ EndPos = CurLine.find(')', StartPos+2)
+ while StartPos != -1 and EndPos != -1:
+ MacroName = CurLine[StartPos+2 : EndPos]
+ MacorValue = self.__GetMacroValue(MacroName)
+ if MacorValue != None:
+ CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)
+ if MacorValue.find('$(') != -1:
+ PreIndex = StartPos
+ else:
+ PreIndex = StartPos + len(MacorValue)
+ else:
+ PreIndex = EndPos + 1
+ StartPos = CurLine.find('$(', PreIndex)
+ EndPos = CurLine.find(')', StartPos+2)
+ self.Profile.FileLinesList[ReplacedLine - 1] = CurLine
+ continue
+
if self.__Token == 'DEFINE':
- if self.__GetIfListCurrentItemStat(IfList):
+ if self.__GetIfListCurrentItemStat(IfList):
+ if not self.__CurSection:
+ raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)
DefineLine = self.CurrentLineNumber - 1
DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
if not self.__GetNextToken():
@@ -619,19 +707,8 @@ class FdfParser: if not self.__IsToken( "="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
- if not self.__GetNextToken():
- raise Warning("expected value", self.FileName, self.CurrentLineNumber)
-
- if self.__GetStringData():
- pass
- Value = self.__Token
- if not Macro in InputMacroDict:
- FileLineTuple = GetRealFileLine(self.FileName, DefineLine + 1)
- MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
- MacProfile.MacroName = Macro
- MacProfile.MacroValue = Value
- AllMacroList.append(MacProfile)
- InputMacroDict[MacProfile.MacroName] = MacProfile.MacroValue
+ Value = self.__GetExpression()
+ self.__SetMacroValue(Macro, Value)
self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
elif self.__Token == 'SET':
PcdPair = self.__GetNextPcdName()
@@ -639,17 +716,10 @@ class FdfParser: if not self.__IsToken( "="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
- if not self.__GetNextToken():
- raise Warning("expected value", self.FileName, self.CurrentLineNumber)
-
- Value = self.__Token
- if Value.startswith("{"):
- # deal with value with {}
- if not self.__SkipToToken( "}"):
- raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
- Value += self.__SkippedChars
+ Value = self.__GetExpression()
+ Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
- InputMacroDict[PcdName] = Value
+ self.__PcdDict[PcdName] = Value
elif self.__Token in ('!ifdef', '!ifndef', '!if'):
IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
IfList.append([IfStartPos, None, None])
@@ -691,6 +761,8 @@ class FdfParser: IfList[-1][2] = True
self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
elif self.__Token == '!endif':
+ if len(IfList) <= 0:
+ raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
if IfList[-1][1]:
self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
else:
@@ -709,21 +781,53 @@ class FdfParser: if not RegionSizeGuid:
RegionLayoutLine = self.CurrentLineNumber + 1
continue
- InputMacroDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
- InputMacroDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
+ self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
+ self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
RegionLayoutLine = self.CurrentLineNumber + 1
if IfList:
raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
self.Rewind()
+ def __CollectMacroPcd(self):
+ MacroDict = {}
+
+ # PCD macro
+ MacroDict.update(self.__PcdDict)
+
+ # Lowest priority
+ MacroDict.update(GlobalData.gPlatformDefines)
+
+ if self.__CurSection:
+ # Defines macro
+ ScopeMacro = self.__MacroDict['COMMON', 'COMMON', 'COMMON']
+ if ScopeMacro:
+ MacroDict.update(ScopeMacro)
+
+ # Section macro
+ ScopeMacro = self.__MacroDict[
+ self.__CurSection[0],
+ self.__CurSection[1],
+ self.__CurSection[2]
+ ]
+ if ScopeMacro:
+ MacroDict.update(ScopeMacro)
+
+ MacroDict.update(GlobalData.gGlobalDefines)
+ MacroDict.update(GlobalData.gCommandLineDefines)
+ # Highest priority
+
+ return MacroDict
+
def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):
FileLineTuple = GetRealFileLine(self.FileName, Line)
+ MacroPcdDict = self.__CollectMacroPcd()
if Op == 'eval':
try:
- return ValueExpression(Expression, InputMacroDict)()
- except SymbolNotFound:
- return False
+ if Value:
+ return ValueExpression(Expression, MacroPcdDict)(True)
+ else:
+ return ValueExpression(Expression, MacroPcdDict)()
except WrnExpression, Excpt:
#
# Catch expression evaluation warning here. We need to report
@@ -738,7 +842,7 @@ class FdfParser: else:
if Expression.startswith('$(') and Expression[-1] == ')':
Expression = Expression[2:-1]
- return Expression in InputMacroDict
+ return Expression in MacroPcdDict
## __IsToken() method
#
@@ -856,7 +960,7 @@ class FdfParser: # Record the token start position, the position of the first non-space char.
StartPos = self.CurrentOffsetWithinLine
StartLine = self.CurrentLineNumber
- while not self.__EndOfLine():
+ while StartLine == self.CurrentLineNumber:
TempChar = self.__CurrentChar()
# Try to find the end char that is not a space and not in seperator tuple.
# That is, when we got a space or any char in the tuple, we got the end of token.
@@ -946,7 +1050,7 @@ class FdfParser: # That is, when we got a space or any char in the tuple, we got the end of token.
if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:
if not self.__UndoOneChar():
- break
+ return
# if we happen to meet a seperator as the first char, we must proceed to get it.
# That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
@@ -1150,12 +1254,6 @@ class FdfParser: while self.__GetDefines():
pass
-
- Index = 0
- while Index < len(self.Profile.FileLinesList):
- FileLineTuple = GetRealFileLine(self.FileName, Index + 1)
- self.Profile.FileLinesList[Index] = self.__ReplaceMacros(self.Profile.FileLinesList[Index], FileLineTuple[0], FileLineTuple[1])
- Index += 1
## ParseFile() method
#
@@ -1239,11 +1337,6 @@ class FdfParser: if not self.__GetNextToken() or self.__Token.startswith('['):
raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
Value = self.__Token
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
- MacProfile.MacroName = Macro
- MacProfile.MacroValue = Value
- AllMacroList.append(MacProfile)
return False
@@ -1279,6 +1372,8 @@ class FdfParser: if FdName == "":
if len (self.Profile.FdDict) == 0:
FdName = GenFdsGlobalVariable.PlatformName
+ if FdName == "" and GlobalData.gActivePlatform:
+ FdName = GlobalData.gActivePlatform.PlatformName
self.Profile.FdNameNotSet = True
else:
raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)
@@ -1373,6 +1468,8 @@ class FdfParser: pcdPair = self.__GetNextPcdName()
Obj.BaseAddressPcd = pcdPair
self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
if not self.__IsKeyword( "Size"):
raise Warning("Size missing", self.FileName, self.CurrentLineNumber)
@@ -1389,6 +1486,8 @@ class FdfParser: pcdPair = self.__GetNextPcdName()
Obj.SizePcd = pcdPair
self.Profile.PcdDict[pcdPair] = Size
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
Obj.Size = long(Size, 0)
if not self.__IsKeyword( "ErasePolarity"):
@@ -1484,6 +1583,8 @@ class FdfParser: PcdPair = self.__GetNextPcdName()
BlockSizePcd = PcdPair
self.Profile.PcdDict[PcdPair] = BlockSize
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
BlockSize = long(BlockSize, 0)
BlockNumber = None
@@ -1567,19 +1668,14 @@ class FdfParser: if not self.__IsToken( "="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
- if not self.__GetNextToken():
- raise Warning("expected value", self.FileName, self.CurrentLineNumber)
-
- Value = self.__Token
- if Value.startswith("{"):
- # deal with value with {}
- if not self.__SkipToToken( "}"):
- raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
- Value += self.__SkippedChars
+ Value = self.__GetExpression()
+ Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
if Obj:
Obj.SetVarDict[PcdPair] = Value
self.Profile.PcdDict[PcdPair] = Value
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
return True
return False
@@ -1615,9 +1711,13 @@ class FdfParser: self.__UndoToken()
RegionObj.PcdOffset = self.__GetNextPcdName()
self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
if self.__IsToken( "|"):
RegionObj.PcdSize = self.__GetNextPcdName()
self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
if not self.__GetNextWord():
return True
@@ -2195,6 +2295,8 @@ class FdfParser: if not ffsInf.InfFileName in self.Profile.InfList:
self.Profile.InfList.append(ffsInf.InfFileName)
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.InfFileLineList.append(FileLineTuple)
if self.__IsToken('|'):
if self.__IsKeyword('RELOCS_STRIPPED'):
@@ -2420,7 +2522,7 @@ class FdfParser: if ErrorCode != 0:
EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
else:
- if not InputMacroDict["OUTPUT_DIRECTORY"] in FfsFileObj.FileName:
+ if not self.__GetMacroValue("OUTPUT_DIRECTORY") in FfsFileObj.FileName:
#do case sensitive check for file path
ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
if ErrorCode != 0:
@@ -3872,6 +3974,8 @@ class FdfParser: if not ffsInf.InfFileName in self.Profile.InfList:
self.Profile.InfList.append(ffsInf.InfFileName)
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.InfFileLineList.append(FileLineTuple)
self.__GetOptRomOverrides (ffsInf)
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py index 0219783b03..8a742d95be 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -278,8 +278,7 @@ def main(): ExtraData="Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!\n", RaiseError=False ) - if Options.debug != None: - EdkLogger.quiet(traceback.format_exc()) + EdkLogger.quiet(traceback.format_exc()) ReturnCode = CODE_ERROR return ReturnCode diff --git a/BaseTools/Source/Python/Table/TableFdf.py b/BaseTools/Source/Python/Table/TableFdf.py index 5fb8cd8232..927b5d1a3b 100644 --- a/BaseTools/Source/Python/Table/TableFdf.py +++ b/BaseTools/Source/Python/Table/TableFdf.py @@ -55,7 +55,8 @@ class TableFdf(Table): Value1 VARCHAR NOT NULL,
Value2 VARCHAR,
Value3 VARCHAR,
- Arch VarCHAR,
+ Scope1 VarCHAR,
+ Scope2 VarCHAR,
BelongsToItem SINGLE NOT NULL,
BelongsToFile SINGLE NOT NULL,
StartLine INTEGER NOT NULL,
@@ -84,11 +85,11 @@ class TableFdf(Table): # @param EndColumn: EndColumn of a Fdf item
# @param Enabled: If this item enabled
#
- def Insert(self, Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled):
+ def Insert(self, Model, Value1, Value2, Value3, Scope1, Scope2, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled):
self.ID = self.ID + 1
- (Value1, Value2, Value3, Arch) = ConvertToSqlString((Value1, Value2, Value3, Arch))
- SqlCommand = """insert into %s values(%s, %s, '%s', '%s', '%s', '%s', %s, %s, %s, %s, %s, %s, %s)""" \
- % (self.Table, self.ID, Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled)
+ (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))
+ SqlCommand = """insert into %s values(%s, %s, '%s', '%s', '%s', '%s', '%s', %s, %s, %s, %s, %s, %s, %s)""" \
+ % (self.Table, self.ID, Model, Value1, Value2, Value3, Scope1, Scope2, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled)
Table.Insert(self, SqlCommand)
return self.ID
@@ -100,7 +101,7 @@ class TableFdf(Table): # @retval: A recordSet of all found records
#
def Query(self, Model):
- SqlCommand = """select ID, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine from %s
+ SqlCommand = """select ID, Value1, Value2, Value3, Scope1, Scope2, BelongsToItem, BelongsToFile, StartLine from %s
where Model = %s
and Enabled > -1""" % (self.Table, Model)
EdkLogger.debug(4, "SqlCommand: %s" % SqlCommand)
diff --git a/BaseTools/Source/Python/Table/TableFile.py b/BaseTools/Source/Python/Table/TableFile.py index 86dddd0f2b..e43802ef25 100644 --- a/BaseTools/Source/Python/Table/TableFile.py +++ b/BaseTools/Source/Python/Table/TableFile.py @@ -89,3 +89,16 @@ class TableFile(Table): TimeStamp = os.stat(FileFullPath)[8]
File = FileClass(-1, Name, Ext, Filepath, FileFullPath, Model, '', [], [], [])
return self.Insert(File.Name, File.ExtName, File.Path, File.FullPath, File.Model, TimeStamp)
+
+ ## Get ID of a given file
+ #
+ # @param FilePath Path of file
+ #
+ # @retval ID ID value of given file in the table
+ #
+ def GetFileId(self, File):
+ QueryScript = "select ID from %s where FullPath = '%s'" % (self.Table, str(File))
+ RecordList = self.Exec(QueryScript)
+ if len(RecordList) == 0:
+ return None
+ return RecordList[0][0]
diff --git a/BaseTools/Source/Python/Trim/Trim.py b/BaseTools/Source/Python/Trim/Trim.py index 34f6284a87..0416ecdcac 100644 --- a/BaseTools/Source/Python/Trim/Trim.py +++ b/BaseTools/Source/Python/Trim/Trim.py @@ -36,16 +36,23 @@ gLineControlDirective = re.compile('^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"') gTypedefPattern = re.compile("^\s*typedef\s+struct(\s+\w+)?\s*[{]*$", re.MULTILINE) ## Regular expression for matching "#pragma pack" gPragmaPattern = re.compile("^\s*#pragma\s+pack", re.MULTILINE) + +# +# The following number pattern match will only match if following criteria is met: +# There is leading non-(alphanumeric or _) character, and no following alphanumeric or _ +# as the pattern is greedily match, so it is ok for the gDecNumberPattern or gHexNumberPattern to grab the maximum match +# ## Regular expression for matching HEX number -gHexNumberPattern = re.compile("(0[xX])([0-9a-fA-F]+)U?") +gHexNumberPattern = re.compile("(?<=[^a-zA-Z0-9_])(0[xX])([0-9a-fA-F]+)(U(?=$|[^a-zA-Z0-9_]))?") ## Regular expression for matching decimal number with 'U' postfix -gDecNumberPattern = re.compile("([0-9]+)U") +gDecNumberPattern = re.compile("(?<=[^a-zA-Z0-9_])([0-9]+)U(?=$|[^a-zA-Z0-9_])") +## Regular expression for matching constant with 'ULL' 'LL' postfix +gLongNumberPattern = re.compile("(?<=[^a-zA-Z0-9_])(0[xX][0-9a-fA-F]+|[0-9]+)U?LL(?=$|[^a-zA-Z0-9_])") + ## Regular expression for matching "Include ()" in asl file gAslIncludePattern = re.compile("^(\s*)[iI]nclude\s*\(\"?([^\"\(\)]+)\"\)", re.MULTILINE) ## Regular expression for matching C style #include "XXX.asl" in asl file gAslCIncludePattern = re.compile(r'^(\s*)#include\s*[<"]\s*([-\\/\w.]+)\s*([>"])', re.MULTILINE) -## Regular expression for matching constant with 'ULL' and 'UL', 'LL', 'L' postfix -gLongNumberPattern = re.compile("(0[xX][0-9a-fA-F]+|[0-9]+)U?LL", re.MULTILINE) ## Patterns used to convert EDK conventions to EDK2 ECP conventions gImportCodePatterns = [ [ diff --git a/BaseTools/Source/Python/UPT/BuildVersion.py b/BaseTools/Source/Python/UPT/BuildVersion.py index 4bb9a8b521..fc3239135c 100644 --- a/BaseTools/Source/Python/UPT/BuildVersion.py +++ b/BaseTools/Source/Python/UPT/BuildVersion.py @@ -1,3 +1,3 @@ #This file is for build version number auto generation
#
-gBUILD_VERSION = "Build 2423"
+gBUILD_VERSION = "Build 2460"
diff --git a/BaseTools/Source/Python/UPT/Core/DependencyRules.py b/BaseTools/Source/Python/UPT/Core/DependencyRules.py index ac656bb02a..752d8e8f41 100644 --- a/BaseTools/Source/Python/UPT/Core/DependencyRules.py +++ b/BaseTools/Source/Python/UPT/Core/DependencyRules.py @@ -55,12 +55,12 @@ class DependencyRules(object): # @param Guid: Guid of a module
# @param Version: Version of a module
#
- def CheckModuleExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):
+ def CheckModuleExists(self, Guid, Version, Name, Path, ReturnCode=DEPEX_CHECK_SUCCESS):
if ReturnCode:
pass
Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST)
- ModuleList = self.IpiDb.GetModInPackage(Guid, Version)
- ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version))
+ ModuleList = self.IpiDb.GetModInPackage(Guid, Version, Name, Path)
+ ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version, Name, Path))
Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST_FINISH)
if len(ModuleList) > 0:
return True
diff --git a/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py b/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py index 0387237951..8ac8d4ed52 100644 --- a/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py +++ b/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py @@ -95,7 +95,7 @@ class DistributionPackageClass(object): #
self.PackageSurfaceArea = Sdict()
#
- # {(Guid, Version, Path) : ModuleObj}
+ # {(Guid, Version, Name, Path) : ModuleObj}
#
self.ModuleSurfaceArea = Sdict()
self.Tools = MiscFileObject()
@@ -149,6 +149,7 @@ class DistributionPackageClass(object): ModuleDict = PackageObj.GetModuleDict()
ModuleDict[(ModuleObj.GetGuid(), \
ModuleObj.GetVersion(), \
+ ModuleObj.GetName(), \
ModuleObj.GetCombinePath())] = ModuleObj
PackageObj.SetModuleDict(ModuleDict)
except FatalError, ErrCode:
@@ -172,10 +173,11 @@ class DistributionPackageClass(object): try:
ModuleObj = InfPomAlignment(ModuleFileFullPath,
WorkspaceDir)
- self.ModuleSurfaceArea[(ModuleObj.GetGuid(), \
- ModuleObj.GetVersion(), \
- ModuleObj.GetCombinePath())] = \
- ModuleObj
+ ModuleKey = (ModuleObj.GetGuid(),
+ ModuleObj.GetVersion(),
+ ModuleObj.GetName(),
+ ModuleObj.GetCombinePath())
+ self.ModuleSurfaceArea[ModuleKey] = ModuleObj
except FatalError, ErrCode:
if ErrCode.message == EDK1_INF_ERROR:
Logger.Error("UPT",
@@ -207,16 +209,16 @@ class DistributionPackageClass(object): Module = None
ModuleDict = Package.GetModuleDict()
- for Guid, Version, Path in ModuleDict:
- Module = ModuleDict[Guid, Version, Path]
+ for Guid, Version, Name, Path in ModuleDict:
+ Module = ModuleDict[Guid, Version, Name, Path]
ModulePath = Module.GetModulePath()
FullPath = Module.GetFullPath()
PkgRelPath = os.path.normpath(os.path.join(PackagePath, ModulePath))
MetaDataFileList.append(Path)
self.FileList += GetNonMetaDataFiles(os.path.dirname(FullPath), ['CVS', '.svn'], False, PkgRelPath)
- for Guid, Version, Path in self.ModuleSurfaceArea:
- Module = self.ModuleSurfaceArea[Guid, Version, Path]
+ for Guid, Version, Name, Path in self.ModuleSurfaceArea:
+ Module = self.ModuleSurfaceArea[Guid, Version, Name, Path]
ModulePath = Module.GetModulePath()
FullPath = Module.GetFullPath()
MetaDataFileList.append(Path)
diff --git a/BaseTools/Source/Python/UPT/Core/IpiDb.py b/BaseTools/Source/Python/UPT/Core/IpiDb.py index 38f872c2ad..e45acb7d48 100644 --- a/BaseTools/Source/Python/UPT/Core/IpiDb.py +++ b/BaseTools/Source/Python/UPT/Core/IpiDb.py @@ -26,6 +26,7 @@ import time import Logger.Log as Logger
from Logger import StringTable as ST
from Logger.ToolError import UPT_ALREADY_RUNNING_ERROR
+from Logger.ToolError import UPT_DB_UPDATE_ERROR
## IpiDb
#
@@ -118,11 +119,12 @@ class IpiDatabase(object): create table IF NOT EXISTS %s (
ModuleGuid TEXT NOT NULL,
ModuleVersion TEXT NOT NULL,
+ ModuleName TEXT NOT NULL,
InstallTime REAL NOT NULL,
PackageGuid TEXT,
PackageVersion TEXT,
InstallPath TEXT NOT NULL,
- PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath)
+ PRIMARY KEY (ModuleGuid, ModuleVersion, ModuleName, InstallPath)
)""" % self.ModInPkgTable
self.Cur.execute(SqlCommand)
@@ -130,11 +132,12 @@ class IpiDatabase(object): create table IF NOT EXISTS %s (
ModuleGuid TEXT NOT NULL,
ModuleVersion TEXT NOT NULL,
+ ModuleName TEXT NOT NULL,
InstallTime REAL NOT NULL,
DpGuid TEXT,
DpVersion TEXT,
InstallPath TEXT NOT NULL,
- PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath)
+ PRIMARY KEY (ModuleGuid, ModuleVersion, ModuleName, InstallPath)
)""" % self.StandaloneModTable
self.Cur.execute(SqlCommand)
@@ -142,6 +145,7 @@ class IpiDatabase(object): create table IF NOT EXISTS %s (
ModuleGuid TEXT NOT NULL,
ModuleVersion TEXT NOT NULL,
+ ModuleName TEXT NOT NULL,
InstallPath TEXT NOT NULL,
DepexGuid TEXT,
DepexVersion TEXT
@@ -160,64 +164,72 @@ class IpiDatabase(object): # @param RePackage: A RePackage
#
def AddDPObject(self, DpObj, NewDpPkgFileName, DpPkgFileName, RePackage):
-
- for PkgKey in DpObj.PackageSurfaceArea.keys():
- PkgGuid = PkgKey[0]
- PkgVersion = PkgKey[1]
- PkgInstallPath = PkgKey[2]
- self._AddPackage(PkgGuid, PkgVersion, DpObj.Header.GetGuid(), \
- DpObj.Header.GetVersion(), PkgInstallPath)
- PkgObj = DpObj.PackageSurfaceArea[PkgKey]
- for ModKey in PkgObj.GetModuleDict().keys():
+ try:
+ for PkgKey in DpObj.PackageSurfaceArea.keys():
+ PkgGuid = PkgKey[0]
+ PkgVersion = PkgKey[1]
+ PkgInstallPath = PkgKey[2]
+ self._AddPackage(PkgGuid, PkgVersion, DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), PkgInstallPath)
+ PkgObj = DpObj.PackageSurfaceArea[PkgKey]
+ for ModKey in PkgObj.GetModuleDict().keys():
+ ModGuid = ModKey[0]
+ ModVersion = ModKey[1]
+ ModName = ModKey[2]
+ ModInstallPath = ModKey[3]
+ ModInstallPath = \
+ os.path.normpath(os.path.join(PkgInstallPath, ModInstallPath))
+ self._AddModuleInPackage(ModGuid, ModVersion, ModName, PkgGuid, \
+ PkgVersion, ModInstallPath)
+ ModObj = PkgObj.GetModuleDict()[ModKey]
+ for Dep in ModObj.GetPackageDependencyList():
+ DepexGuid = Dep.GetGuid()
+ DepexVersion = Dep.GetVersion()
+ self._AddModuleDepex(ModGuid, ModVersion, ModName, ModInstallPath, \
+ DepexGuid, DepexVersion)
+ for (FilePath, Md5Sum) in PkgObj.FileList:
+ self._AddDpFilePathList(DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), FilePath, \
+ Md5Sum)
+
+ for ModKey in DpObj.ModuleSurfaceArea.keys():
ModGuid = ModKey[0]
ModVersion = ModKey[1]
- ModInstallPath = ModKey[2]
- ModInstallPath = \
- os.path.normpath(os.path.join(PkgInstallPath, ModInstallPath))
- self._AddModuleInPackage(ModGuid, ModVersion, PkgGuid, \
- PkgVersion, ModInstallPath)
- ModObj = PkgObj.GetModuleDict()[ModKey]
+ ModName = ModKey[2]
+ ModInstallPath = ModKey[3]
+ self._AddStandaloneModule(ModGuid, ModVersion, ModName, \
+ DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), \
+ ModInstallPath)
+ ModObj = DpObj.ModuleSurfaceArea[ModKey]
for Dep in ModObj.GetPackageDependencyList():
DepexGuid = Dep.GetGuid()
DepexVersion = Dep.GetVersion()
- self._AddModuleDepex(ModGuid, ModVersion, ModInstallPath, \
+ self._AddModuleDepex(ModGuid, ModVersion, ModName, ModInstallPath, \
DepexGuid, DepexVersion)
- for (FilePath, Md5Sum) in PkgObj.FileList:
- self._AddDpFilePathList(DpObj.Header.GetGuid(), \
- DpObj.Header.GetVersion(), FilePath, \
- Md5Sum)
-
- for ModKey in DpObj.ModuleSurfaceArea.keys():
- ModGuid = ModKey[0]
- ModVersion = ModKey[1]
- ModInstallPath = ModKey[2]
- self._AddStandaloneModule(ModGuid, ModVersion, \
- DpObj.Header.GetGuid(), \
- DpObj.Header.GetVersion(), \
- ModInstallPath)
- ModObj = DpObj.ModuleSurfaceArea[ModKey]
- for Dep in ModObj.GetPackageDependencyList():
- DepexGuid = Dep.GetGuid()
- DepexVersion = Dep.GetVersion()
- self._AddModuleDepex(ModGuid, ModVersion, ModInstallPath, \
- DepexGuid, DepexVersion)
- for (Path, Md5Sum) in ModObj.FileList:
+ for (Path, Md5Sum) in ModObj.FileList:
+ self._AddDpFilePathList(DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), \
+ Path, Md5Sum)
+
+ #
+ # add tool/misc files
+ #
+ for (Path, Md5Sum) in DpObj.FileList:
self._AddDpFilePathList(DpObj.Header.GetGuid(), \
- DpObj.Header.GetVersion(), \
- Path, Md5Sum)
-
- #
- # add tool/misc files
- #
- for (Path, Md5Sum) in DpObj.FileList:
- self._AddDpFilePathList(DpObj.Header.GetGuid(), \
- DpObj.Header.GetVersion(), Path, Md5Sum)
-
- self._AddDp(DpObj.Header.GetGuid(), DpObj.Header.GetVersion(), \
- NewDpPkgFileName, DpPkgFileName, RePackage)
+ DpObj.Header.GetVersion(), Path, Md5Sum)
+
+ self._AddDp(DpObj.Header.GetGuid(), DpObj.Header.GetVersion(), \
+ NewDpPkgFileName, DpPkgFileName, RePackage)
+
+ self.Conn.commit()
+ except sqlite3.IntegrityError, DetailMsg:
+ Logger.Error("UPT",
+ UPT_DB_UPDATE_ERROR,
+ ST.ERR_UPT_DB_UPDATE_ERROR,
+ ExtraData = DetailMsg
+ )
- self.Conn.commit()
-
## Add a distribution install information
#
# @param Guid Guid of the distribution package
@@ -290,12 +302,14 @@ class IpiDatabase(object): ## Add a module that from a package install information
#
- # @param Guid: A package guid
- # @param Version: A package version
- # @param PkgGuid: A package guid
- # @param PkgFileName: A package File Name
+ # @param Guid: Module Guid
+ # @param Version: Module version
+ # @param Name: Module Name
+ # @param PkgGuid: Package Guid
+ # @param PkgVersion: Package version
+ # @param Path: Package relative path that module installs
#
- def _AddModuleInPackage(self, Guid, Version, PkgGuid=None, \
+ def _AddModuleInPackage(self, Guid, Version, Name, PkgGuid=None, \
PkgVersion=None, Path=''):
if Version == None or len(Version.strip()) == 0:
@@ -312,8 +326,8 @@ class IpiDatabase(object): #
CurrentTime = time.time()
SqlCommand = \
- """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % \
- (self.ModInPkgTable, Guid, Version, CurrentTime, PkgGuid, PkgVersion, \
+ """insert into %s values('%s', '%s', '%s', %s, '%s', '%s', '%s')""" % \
+ (self.ModInPkgTable, Guid, Version, Name, CurrentTime, PkgGuid, PkgVersion, \
Path)
self.Cur.execute(SqlCommand)
@@ -321,11 +335,12 @@ class IpiDatabase(object): #
# @param Guid: a module Guid
# @param Version: a module Version
+ # @param Name: a module name
# @param DpGuid: a DpGuid
# @param DpVersion: a DpVersion
# @param Path: path
#
- def _AddStandaloneModule(self, Guid, Version, DpGuid=None, \
+ def _AddStandaloneModule(self, Guid, Version, Name, DpGuid=None, \
DpVersion=None, Path=''):
if Version == None or len(Version.strip()) == 0:
@@ -342,8 +357,8 @@ class IpiDatabase(object): #
CurrentTime = time.time()
SqlCommand = \
- """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % \
- (self.StandaloneModTable, Guid, Version, CurrentTime, DpGuid, \
+ """insert into %s values('%s', '%s', '%s', %s, '%s', '%s', '%s')""" % \
+ (self.StandaloneModTable, Guid, Version, Name, CurrentTime, DpGuid, \
DpVersion, Path)
self.Cur.execute(SqlCommand)
@@ -351,10 +366,11 @@ class IpiDatabase(object): #
# @param Guid: a module Guid
# @param Version: a module Version
+ # @param Name: a module name
# @param DepexGuid: a module DepexGuid
# @param DepexVersion: a module DepexVersion
#
- def _AddModuleDepex(self, Guid, Version, Path, DepexGuid=None, \
+ def _AddModuleDepex(self, Guid, Version, Name, Path, DepexGuid=None, \
DepexVersion=None):
if DepexGuid == None or len(DepexGuid.strip()) == 0:
@@ -366,8 +382,8 @@ class IpiDatabase(object): #
# Add module depex information to DB.
#
- SqlCommand = """insert into %s values('%s', '%s', '%s', '%s', '%s')"""\
- % (self.ModDepexTable, Guid, Version, Path, DepexGuid, DepexVersion)
+ SqlCommand = """insert into %s values('%s', '%s', '%s', '%s', '%s', '%s')"""\
+ % (self.ModDepexTable, Guid, Version, Name, Path, DepexGuid, DepexVersion)
self.Cur.execute(SqlCommand)
## Remove a distribution install information, if no version specified,
@@ -389,10 +405,13 @@ class IpiDatabase(object): and ModDepexInfo.ModuleVersion in
(select ModuleVersion from StandaloneModInfo as B
where B.DpGuid = '%s' and B.DpVersion = '%s')
+ and ModDepexInfo.ModuleName in
+ (select ModuleName from StandaloneModInfo as B
+ where B.DpGuid = '%s' and B.DpVersion = '%s')
and ModDepexInfo.InstallPath in
(select InstallPath from StandaloneModInfo as B
where B.DpGuid = '%s' and B.DpVersion = '%s') """ % \
- (DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion)
+ (DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion)
self.Cur.execute(SqlCommand)
#
@@ -409,11 +428,15 @@ class IpiDatabase(object): (select ModuleVersion from ModInPkgInfo
where ModInPkgInfo.PackageGuid ='%s' and
ModInPkgInfo.PackageVersion = '%s')
+ and ModDepexInfo.ModuleName in
+ (select ModuleName from ModInPkgInfo
+ where ModInPkgInfo.PackageGuid ='%s' and
+ ModInPkgInfo.PackageVersion = '%s')
and ModDepexInfo.InstallPath in
(select InstallPath from ModInPkgInfo where
ModInPkgInfo.PackageGuid ='%s'
and ModInPkgInfo.PackageVersion = '%s')""" \
- % (Pkg[0], Pkg[1],Pkg[0], Pkg[1],Pkg[0], Pkg[1])
+ % (Pkg[0], Pkg[1], Pkg[0], Pkg[1], Pkg[0], Pkg[1],Pkg[0], Pkg[1])
self.Cur.execute(SqlCommand)
#
@@ -627,23 +650,21 @@ class IpiDatabase(object): # @param Guid: A module guid
# @param Version: A module version
#
- def GetModInPackage(self, Guid, Version, PkgGuid='', PkgVersion=''):
-
+ def GetModInPackage(self, Guid, Version, Name, Path, PkgGuid='', PkgVersion=''):
+ (ModuleGuid, ModuleVersion, ModuleName, InstallPath) = (Guid, Version, Name, Path)
if PkgVersion == '' or PkgGuid == '':
-
- (ModuleGuid, ModuleVersion) = (Guid, Version)
SqlCommand = """select * from %s where ModuleGuid ='%s' and
- ModuleVersion = '%s'""" % (self.ModInPkgTable, ModuleGuid, \
- ModuleVersion)
+ ModuleVersion = '%s' and InstallPath = '%s'
+ and ModuleName = '%s'""" % (self.ModInPkgTable, ModuleGuid, \
+ ModuleVersion, InstallPath, ModuleName)
self.Cur.execute(SqlCommand)
-
else:
- (ModuleGuid, ModuleVersion) = (Guid, Version)
SqlCommand = """select * from %s where ModuleGuid ='%s' and
- ModuleVersion = '%s' and PackageGuid ='%s'
+ ModuleVersion = '%s' and InstallPath = '%s'
+ and ModuleName = '%s' and PackageGuid ='%s'
and PackageVersion = '%s'
""" % (self.ModInPkgTable, ModuleGuid, \
- ModuleVersion, PkgGuid, PkgVersion)
+ ModuleVersion, InstallPath, ModuleName, PkgGuid, PkgVersion)
self.Cur.execute(SqlCommand)
ModList = []
@@ -662,21 +683,20 @@ class IpiDatabase(object): # @param Guid: A module guid
# @param Version: A module version
#
- def GetStandaloneModule(self, Guid, Version, DpGuid='', DpVersion=''):
-
+ def GetStandaloneModule(self, Guid, Version, Name, Path, DpGuid='', DpVersion=''):
+ (ModuleGuid, ModuleVersion, ModuleName, InstallPath) = (Guid, Version, Name, Path)
if DpGuid == '':
- (ModuleGuid, ModuleVersion) = (Guid, Version)
SqlCommand = """select * from %s where ModuleGuid ='%s' and
- ModuleVersion = '%s'""" % (self.StandaloneModTable, ModuleGuid, \
- ModuleVersion)
+ ModuleVersion = '%s' and InstallPath = '%s'
+ and ModuleName = '%s'""" % (self.StandaloneModTable, ModuleGuid, \
+ ModuleVersion, InstallPath, ModuleName)
self.Cur.execute(SqlCommand)
else:
- (ModuleGuid, ModuleVersion) = (Guid, Version)
SqlCommand = """select * from %s where ModuleGuid ='%s' and
- ModuleVersion = '%s' and DpGuid ='%s' and DpVersion = '%s'
+ ModuleVersion = '%s' and InstallPath = '%s' and ModuleName = '%s' and DpGuid ='%s' and DpVersion = '%s'
""" % (self.StandaloneModTable, ModuleGuid, \
- ModuleVersion, DpGuid, DpVersion)
+ ModuleVersion, ModuleName, InstallPath, DpGuid, DpVersion)
self.Cur.execute(SqlCommand)
ModList = []
diff --git a/BaseTools/Source/Python/UPT/InstallPkg.py b/BaseTools/Source/Python/UPT/InstallPkg.py index c258222d6d..1c75dad80b 100644 --- a/BaseTools/Source/Python/UPT/InstallPkg.py +++ b/BaseTools/Source/Python/UPT/InstallPkg.py @@ -265,11 +265,11 @@ def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList): #
Module = None
NewDict = Sdict()
- for Guid, Version, Path in DistPkg.ModuleSurfaceArea:
+ for Guid, Version, Name, Path in DistPkg.ModuleSurfaceArea:
ModulePath = Path
- Module = DistPkg.ModuleSurfaceArea[Guid, Version, Path]
+ Module = DistPkg.ModuleSurfaceArea[Guid, Version, Name, Path]
Logger.Info(ST.MSG_INSTALL_MODULE % Module.GetName())
- if Dep.CheckModuleExists(Guid, Version):
+ if Dep.CheckModuleExists(Guid, Version, Name, Path):
Logger.Quiet(ST.WRN_MODULE_EXISTED %Path)
#
# here check for the multiple inf share the same module path cases:
@@ -291,7 +291,7 @@ def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList): #
Module.SetModulePath(Module.GetModulePath().replace(Path, NewModulePath, 1))
- NewDict[Guid, Version, Module.GetModulePath()] = Module
+ NewDict[Guid, Version, Name, Module.GetModulePath()] = Module
#
# generate all inf for modules
@@ -737,8 +737,8 @@ def InstallPackageContent(FromPath, ToPath, Package, ContentZipFile, Dep, #
Module = None
ModuleDict = Package.GetModuleDict()
- for ModuleGuid, ModuleVersion, ModulePath in ModuleDict:
- Module = ModuleDict[ModuleGuid, ModuleVersion, ModulePath]
+ for ModuleGuid, ModuleVersion, ModuleName, ModulePath in ModuleDict:
+ Module = ModuleDict[ModuleGuid, ModuleVersion, ModuleName, ModulePath]
InstallModuleContent(FromPath, ToPath, ModulePath, Module,
ContentZipFile, WorkspaceDir, ModuleList, Package, ReadOnly)
diff --git a/BaseTools/Source/Python/UPT/Library/Misc.py b/BaseTools/Source/Python/UPT/Library/Misc.py index b67cd102d1..889b777d19 100644 --- a/BaseTools/Source/Python/UPT/Library/Misc.py +++ b/BaseTools/Source/Python/UPT/Library/Misc.py @@ -875,7 +875,7 @@ def ProcessEdkComment(LineList): for Index in xrange(StartPos, EndPos+1): LineList[Index] = '' FindEdkBlockComment = False - elif Line.find("//") != -1: + elif Line.find("//") != -1 and not Line.startswith("#"): # # handling cpp style comment # diff --git a/BaseTools/Source/Python/UPT/Logger/StringTable.py b/BaseTools/Source/Python/UPT/Logger/StringTable.py index 063ca52d2b..8a94d71046 100644 --- a/BaseTools/Source/Python/UPT/Logger/StringTable.py +++ b/BaseTools/Source/Python/UPT/Logger/StringTable.py @@ -524,6 +524,7 @@ ERR_UNKNOWN_ERROR = _("Unknown error") ERR_UPT_ALREADY_INSTALLED_ERROR = _("Already installed")
ERR_UPT_ENVIRON_MISSING_ERROR = _("Environ missing")
ERR_UPT_REPKG_ERROR = _("File not allowed for RePackage")
+ERR_UPT_DB_UPDATE_ERROR = _("Update database did not complete successfully")
ERR_UPT_INI_PARSE_ERROR = _("INI file parse error")
ERR_COPYRIGHT_MISSING = \
_("Header comment section must have copyright information")
diff --git a/BaseTools/Source/Python/UPT/Logger/ToolError.py b/BaseTools/Source/Python/UPT/Logger/ToolError.py index 69600b2c01..906d03337c 100644 --- a/BaseTools/Source/Python/UPT/Logger/ToolError.py +++ b/BaseTools/Source/Python/UPT/Logger/ToolError.py @@ -97,6 +97,7 @@ UPT_ENVIRON_MISSING_ERROR = 0xD001 UPT_REPKG_ERROR = 0xD002 UPT_ALREADY_RUNNING_ERROR = 0xD003 UPT_MUL_DEC_ERROR = 0xD004 +UPT_DB_UPDATE_ERROR = 0xD005 UPT_INI_PARSE_ERROR = 0xE000 ## Error message of each error code diff --git a/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py b/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py index f340805f32..85062ac883 100644 --- a/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py +++ b/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py @@ -273,7 +273,8 @@ class PackageSurfaceAreaXml(object): for SubItem in XmlList(Item, '/PackageSurfaceArea/Modules/ModuleSurfaceArea'):
Tmp = ModuleSurfaceAreaXml()
Module = Tmp.FromXml(SubItem, 'ModuleSurfaceArea')
- Package.ModuleDict[(Module.GetGuid(), Module.GetVersion(), Module.GetModulePath())] = Module
+ ModuleDictKey = (Module.GetGuid(), Module.GetVersion(), Module.GetName(), Module.GetModulePath())
+ Package.ModuleDict[ModuleDictKey] = Module
#
# MiscellaneousFile
#
diff --git a/BaseTools/Source/Python/UPT/Xml/XmlParser.py b/BaseTools/Source/Python/UPT/Xml/XmlParser.py index adfeca81a0..5a2f0dc705 100644 --- a/BaseTools/Source/Python/UPT/Xml/XmlParser.py +++ b/BaseTools/Source/Python/UPT/Xml/XmlParser.py @@ -180,7 +180,9 @@ class DistributionPackageXml(object): for Item in XmlList(self.Pkg, '/DistributionPackage/ModuleSurfaceArea'):
Msa = ModuleSurfaceAreaXml()
Module = Msa.FromXml(Item, 'ModuleSurfaceArea', True)
- self.DistP.ModuleSurfaceArea[(Module.GetGuid(), Module.GetVersion(), Module.GetModulePath())] = Module
+ ModuleKey = (Module.GetGuid(), Module.GetVersion(), Module.GetName(), Module.GetModulePath())
+ self.DistP.ModuleSurfaceArea[ModuleKey] = Module
+
#
# Parse Tools
#
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py index d907b11ba1..e26b558de0 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -59,17 +59,29 @@ def ParseMacro(Parser): 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) - self._ItemType = self.DataType[Type] + 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 self._ItemType == MODEL_META_DATA_DEFINE: - if self._SectionType == MODEL_META_DATA_HEADER: - self._FileLocalMacros[Name] = Value + if Type == TAB_DSC_DEFINES_DEFINE: + # + # First judge whether this DEFINE is in conditional directive statements or not. + # + if type(self) == DscParser and self._InDirective > -1: + pass else: - SectionDictKey = self._SectionType, self._Scope[0][0], self._Scope[0][1] - if SectionDictKey not in self._SectionsMacroDict: - self._SectionsMacroDict[SectionDictKey] = {} - SectionLocalMacros = self._SectionsMacroDict[SectionDictKey] - SectionLocalMacros[Name] = Value + if type(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 type(self) != DscParser: EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used in .dsc file", @@ -310,6 +322,7 @@ class MetaFileParser(object): 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] # Sometimes, we need to make differences between EDK and EDK2 modules if Name == 'INF_VERSION': @@ -319,7 +332,6 @@ class MetaFileParser(object): EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number", ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) - Value = ReplaceMacro(Value, self._Macros) if type(self) == InfParser and self._Version < 0x00010005: # EDK module allows using defines as macros self._FileLocalMacros[Name] = Value @@ -354,15 +366,59 @@ class MetaFileParser(object): Macros.update(self._GetApplicableSectionMacro()) return Macros + ## Construct section Macro dict + def _ConstructSectionMacroDict(self, Name, Value): + ScopeKey = [(Scope[0], Scope[1]) for Scope in self._Scope] + ScopeKey = tuple(ScopeKey) + SectionDictKey = self._SectionType, ScopeKey + # + # DecParser SectionType is a list, will contain more than one item only in Pcd Section + # As Pcd section macro usage is not alllowed, so here it is safe + # + if type(self) == DecParser: + SectionDictKey = self._SectionType[0], ScopeKey + if SectionDictKey not in self._SectionsMacroDict: + self._SectionsMacroDict[SectionDictKey] = {} + SectionLocalMacros = self._SectionsMacroDict[SectionDictKey] + SectionLocalMacros[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 = {} - for SectionType, Scope1, Scope2 in self._SectionsMacroDict: - if (SectionType == self._SectionType) and (Scope1 == self._Scope[0][0] or Scope1 == "COMMON") and (Scope2 == self._Scope[0][1] or Scope2 == "COMMON"): - Macros.update(self._SectionsMacroDict[(SectionType, Scope1, Scope2)]) + ComComMacroDict = {} + ComSpeMacroDict = {} + SpeSpeMacroDict = {} + + ActiveSectionType = self._SectionType + if type(self) == DecParser: + ActiveSectionType = self._SectionType[0] + + for (SectionType, Scope) in self._SectionsMacroDict: + if SectionType != ActiveSectionType: + continue + + for ActiveScope in self._Scope: + Scope0, Scope1 = ActiveScope[0], ActiveScope[1] + if(Scope0, Scope1) not in Scope: + break + else: + SpeSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)]) + + for ActiveScope in self._Scope: + Scope0, Scope1 = ActiveScope[0], ActiveScope[1] + if(Scope0, Scope1) not in Scope and (Scope0, "COMMON") not in Scope and ("COMMON", Scope1) not in Scope: + break + else: + ComSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)]) + + if ("COMMON", "COMMON") in Scope: + ComComMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)]) + + Macros.update(ComComMacroDict) + Macros.update(ComSpeMacroDict) + Macros.update(SpeSpeMacroDict) return Macros @@ -499,7 +555,8 @@ class InfParser(MetaFileParser): self._ValueList = ['','',''] # parse current line, result will be put in self._ValueList self._SectionParser[self._SectionType](self) - if self._ValueList == None: + if self._ValueList == None or self._ItemType == MODEL_META_DATA_DEFINE: + self._ItemType = -1 continue # # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1, @@ -733,7 +790,12 @@ class DscParser(MetaFileParser): self._DirectiveStack = [] self._DirectiveEvalStack = [] self._Enabled = 1 - + + # + # Specify whether current line is in uncertain condition + # + self._InDirective = -1 + # Final valid replacable symbols self._Symbols = {} # @@ -838,6 +900,13 @@ class DscParser(MetaFileParser): 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, @@ -923,6 +992,7 @@ class DscParser(MetaFileParser): self._ValueList[0:len(TokenList)] = TokenList ## Parse Edk style of library modules + @ParseMacro def _LibraryInstanceParser(self): self._ValueList[0] = self._CurrentLine @@ -1146,27 +1216,13 @@ class DscParser(MetaFileParser): Records = self._RawTable.Query(MODEL_PCD_FEATURE_FLAG, BelongsToItem=-1.0) for TokenSpaceGuid,PcdName,Value,Dummy2,Dummy3,ID,Line in Records: Value, DatumType, MaxDatumSize = AnalyzePcdData(Value) - # Only use PCD whose value is straitforward (no macro and PCD) - if self.SymbolPattern.findall(Value): - continue Name = TokenSpaceGuid + '.' + PcdName - # Don't use PCD with different values. - if Name in self._Symbols and self._Symbols[Name] != Value: - self._Symbols.pop(Name) - continue self._Symbols[Name] = Value Records = self._RawTable.Query(MODEL_PCD_FIXED_AT_BUILD, BelongsToItem=-1.0) for TokenSpaceGuid,PcdName,Value,Dummy2,Dummy3,ID,Line in Records: Value, DatumType, MaxDatumSize = AnalyzePcdData(Value) - # Only use PCD whose value is straitforward (no macro and PCD) - if self.SymbolPattern.findall(Value): - continue - Name = TokenSpaceGuid+'.'+PcdName - # Don't use PCD with different values. - if Name in self._Symbols and self._Symbols[Name] != Value: - self._Symbols.pop(Name) - continue + Name = TokenSpaceGuid + '.' + PcdName self._Symbols[Name] = Value def __ProcessDefine(self): @@ -1179,11 +1235,7 @@ class DscParser(MetaFileParser): if self._SectionType == MODEL_META_DATA_HEADER: self._FileLocalMacros[Name] = Value else: - SectionDictKey = self._SectionType, self._Scope[0][0], self._Scope[0][1] - if SectionDictKey not in self._SectionsMacroDict: - self._SectionsMacroDict[SectionDictKey] = {} - SectionLocalMacros = self._SectionsMacroDict[SectionDictKey] - SectionLocalMacros[Name] = Value + self._ConstructSectionMacroDict(Name, Value) elif self._ItemType == MODEL_META_DATA_GLOBAL_DEFINE: GlobalData.gEdkGlobal[Name] = Value @@ -1234,8 +1286,9 @@ class DscParser(MetaFileParser): self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1] self._DirectiveEvalStack.append(bool(Result)) elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE: - self._DirectiveStack[-1] = self._ItemType + 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: @@ -1243,7 +1296,6 @@ class DscParser(MetaFileParser): Directive = self._DirectiveStack.pop() if Directive in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF, MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF, - MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE, MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]: break elif self._ItemType == MODEL_META_DATA_INCLUDE: @@ -1324,13 +1376,43 @@ class DscParser(MetaFileParser): self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros, RaiseError=True) def __ProcessPcd(self): + PcdValue = None ValueList = GetSplitValueList(self._ValueList[2]) + # + # PCD value can be an expression + # if len(ValueList) > 1 and ValueList[1] == 'VOID*': - PcdValue = ValueList[0] - ValueList[0] = ReplaceMacro(PcdValue, self._Macros) + PcdValue = ValueList[0] + try: + ValueList[0] = ValueExpression(PcdValue, self._Macros)(True) + except WrnExpression, Value: + ValueList[0] = Value.result else: - PcdValue = ValueList[-1] - ValueList[-1] = ReplaceMacro(PcdValue, self._Macros) + # + # Int*/Boolean VPD PCD + # TokenSpace | PcdCName | Offset | [Value] + # + # VOID* VPD PCD + # TokenSpace | PcdCName | Offset | [Size] | [Value] + # + if self._ItemType == MODEL_PCD_DYNAMIC_VPD: + if len(ValueList) >= 4: + PcdValue = ValueList[-1] + else: + PcdValue = ValueList[-1] + # + # For the VPD PCD, there may not have PcdValue data in DSC file + # + if PcdValue: + try: + ValueList[-1] = ValueExpression(PcdValue, self._Macros)(True) + except WrnExpression, Value: + ValueList[-1] = Value.result + + if ValueList[-1] == 'True': + ValueList[-1] = '1' + if ValueList[-1] == 'False': + ValueList[-1] = '0' self._ValueList[2] = '|'.join(ValueList) @@ -1380,6 +1462,7 @@ 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, @@ -1441,7 +1524,8 @@ class DecParser(MetaFileParser): # section content self._ValueList = ['','',''] self._SectionParser[self._SectionType[0]](self) - if self._ValueList == None: + if self._ValueList == None or self._ItemType == MODEL_META_DATA_DEFINE: + self._ItemType = -1 self._Comments = [] continue @@ -1482,6 +1566,7 @@ class DecParser(MetaFileParser): self._Comments = [] self._Done() + ## Section header parser # # The section header is always in following format: diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py index 71e98a94be..a8452a9f84 100644 --- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py +++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py @@ -429,7 +429,7 @@ class DscBuildData(PlatformBuildClassObject): File=self.MetaFile, Line=Record[-1])
self._SkuIds[Record[1]] = Record[0]
if 'DEFAULT' not in self._SkuIds:
- self._SkuIds['DEFAULT'] = 0
+ self._SkuIds['DEFAULT'] = '0'
return self._SkuIds
## Retrieve [Components] section information
@@ -1343,10 +1343,10 @@ class InfBuildData(ModuleBuildClassObject): def _GetMacros(self):
if self.__Macros == None:
self.__Macros = {}
- # EDK_GLOBAL defined macros can be applied to EDK modoule
+ # EDK_GLOBAL defined macros can be applied to EDK module
if self.AutoGenVersion < 0x00010005:
self.__Macros.update(GlobalData.gEdkGlobal)
- self.__Macros.update(GlobalData.gGlobalDefines)
+ self.__Macros.update(GlobalData.gGlobalDefines)
return self.__Macros
## Get architecture
@@ -1760,8 +1760,6 @@ class InfBuildData(ModuleBuildClassObject): self._Sources = []
RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
Macros = self._Macros
- Macros["EDK_SOURCE"] = GlobalData.gEcpSource
- Macros['PROCESSOR'] = self._Arch
for Record in RecordList:
LineNo = Record[-1]
ToolChainFamily = Record[1]
@@ -1769,6 +1767,8 @@ class InfBuildData(ModuleBuildClassObject): ToolCode = Record[3]
FeatureFlag = Record[4]
if self.AutoGenVersion < 0x00010005:
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
# old module source files (Edk)
File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,
'', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index 0319103138..4abf611a0e 100644 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -750,7 +750,7 @@ class Build(): EdkLogger.info('%-16s = %s' % ("Build target", ' '.join(self.BuildTargetList)))
EdkLogger.info('%-16s = %s' % ("Toolchain", ' '.join(self.ToolChainList)))
- #EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.PlatformFile))
+ EdkLogger.info('\n%-16s = %s' % ("Active Platform", self.PlatformFile))
if self.ModuleFile:
EdkLogger.info('%-16s = %s' % ("Active Module", self.ModuleFile))
@@ -1856,8 +1856,7 @@ def Main(): ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
RaiseError=False
)
- if Option != None and Option.debug != None:
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
ReturnCode = CODE_ERROR
finally:
Utils.Progressor.Abort()
|