Sync BaseTool trunk (version r2460) into EDKII BaseTools. The change mainly includes:

1. Support use expression as DSC file PCD value.
  2. Update FDF parser to fix bug to get complete macro value.
  3. Fix bug to replace SET statement macro and evaluate SET statement PCD value in FDF file.
  4. Fix a bug for MACRO defined in conditional block cannot be processed correctly

Signed-off-by: lgao4
Reviewed-by: gikidy


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12827 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lgao4
2011-12-07 06:19:28 +00:00
parent b7891584a5
commit d0acc87a41
68 changed files with 3541 additions and 427 deletions

View File

@ -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:

View File

@ -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)