X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FGenFds%2FFdfParser.py;h=ffc54abc847f80d9742d3958e20584f38cbc22ed;hp=4f555e32bbaea27de65ee3f9cfc9899a73db24e2;hb=a3251d844695f90711bfe094f12755fd01742369;hpb=79b74a03e018ecbf03d8d50e6f20301e249c1ba5
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 4f555e32bb..ffc54abc84 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -1,7 +1,7 @@
## @file
# parse FDF file
#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -15,6 +15,8 @@
##
# Import Modules
#
+import re
+
import Fd
import Region
import Fv
@@ -45,10 +47,16 @@ from Common.BuildToolError import *
from Common import EdkLogger
from Common.Misc import PathClass
from Common.String import NormPath
+import Common.GlobalData as GlobalData
+from Common.Expression import *
from Common import GlobalData
+from Common.String import ReplaceMacro
+
+from Common.Misc import tdict
import re
-import os
+import Common.LongFilePathOs as os
+from Common.LongFilePathSupport import OpenLongFilePath as open
##define T_CHAR_SPACE ' '
##define T_CHAR_NULL '\0'
@@ -68,11 +76,12 @@ T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_
SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
+RegionSizePattern = re.compile("\s*(?P(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P(?:0x|0X)?[a-fA-F0-9]+)\s*")
+RegionSizeGuidPattern = re.compile("\s*(?P\w+\.\w+)\s*\|\s*(?P\w+\.\w+)\s*")
+RegionOffsetPcdPattern = re.compile("\s*(?P\w+\.\w+)\s*$")
+ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P\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):
@@ -174,7 +183,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 = {}
@@ -182,6 +194,7 @@ class FileProfile :
self.VtfList = []
self.RuleDict = {}
self.OptRomDict = {}
+ self.FmpPayloadDict = {}
## The syntax parser for FDF
#
@@ -206,6 +219,14 @@ class FdfParser:
self.CurrentFvName = None
self.__Token = ""
self.__SkippedChars = ""
+ GlobalData.gFdfParser = self
+
+ # 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 == '':
@@ -317,10 +338,10 @@ class FdfParser:
#
def __GetOneChar(self):
if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
- self.CurrentLineNumber += 1
- self.CurrentOffsetWithinLine = 0
+ self.CurrentLineNumber += 1
+ self.CurrentOffsetWithinLine = 0
else:
- self.CurrentOffsetWithinLine += 1
+ self.CurrentOffsetWithinLine += 1
## __CurrentChar() method
#
@@ -369,30 +390,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]
@@ -434,7 +431,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.
@@ -517,25 +574,45 @@ class FdfParser:
if not self.__GetNextToken():
raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)
IncFileName = self.__Token
- if not os.path.isabs(IncFileName):
- if IncFileName.startswith('$(WORKSPACE)'):
- Str = IncFileName.replace('$(WORKSPACE)', os.environ.get('WORKSPACE'))
- if os.path.exists(Str):
- if not os.path.isabs(Str):
- Str = os.path.abspath(Str)
- IncFileName = Str
- else:
- # file is in the same dir with FDF file
- FullFdf = self.FileName
- if not os.path.isabs(self.FileName):
- FullFdf = os.path.join(os.environ.get('WORKSPACE'), self.FileName)
-
- IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName)
-
- if not os.path.exists(os.path.normpath(IncFileName)):
- raise Warning("Include file not exists", self.FileName, self.CurrentLineNumber)
+ __IncludeMacros = {}
+ 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
+ #
+ IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))
+ ErrorCode = IncludedFile1.Validate()[0]
+ if ErrorCode != 0:
+ #
+ # Then search the include file under the same directory as DSC file
+ #
+ 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:
+ #
+ # Also search file under the WORKSPACE directory
+ #
+ 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), PlatformDir, GlobalData.gWorkspace),
+ self.FileName, self.CurrentLineNumber)
- IncFileProfile = IncludeFileProfile(os.path.normpath(IncFileName))
+ IncFileProfile = IncludeFileProfile(IncludedFile1.Path)
CurrentLine = self.CurrentLineNumber
CurrentOffset = self.CurrentOffsetWithinLine
@@ -564,7 +641,7 @@ class FdfParser:
self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
self.Rewind()
-
+
def __GetIfListCurrentItemStat(self, IfList):
if len(IfList) == 0:
return True
@@ -574,8 +651,7 @@ class FdfParser:
return False
return True
-
-
+
## PreprocessConditionalStatement() method
#
# Preprocess conditional statement.
@@ -586,9 +662,48 @@ class FdfParser:
def PreprocessConditionalStatement(self):
# 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 and self.__Token not in ['!ifdef', '!ifndef', '!if', '!elseif']:
+ 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 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():
@@ -597,72 +712,52 @@ 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)
+ Value = self.__GetExpression()
+ self.__SetMacroValue(Macro, Value)
self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
+ elif self.__Token == 'SET':
+ if not self.__GetIfListCurrentItemStat(IfList):
+ continue
+ SetLine = self.CurrentLineNumber - 1
+ SetOffset = self.CurrentOffsetWithinLine - len('SET')
+ PcdPair = self.__GetNextPcdName()
+ PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ Value = self.__GetExpression()
+ Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
+
+ self.__PcdDict[PcdName] = Value
+ self.Profile.PcdDict[PcdPair] = Value
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
+
+ self.__WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
elif self.__Token in ('!ifdef', '!ifndef', '!if'):
IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
IfList.append([IfStartPos, None, None])
+
CondLabel = self.__Token
+ Expression = self.__GetExpression()
- MacroName, NotFlag = self.__GetMacroName()
- NotDefineFlag = False
- if CondLabel == '!ifndef':
- NotDefineFlag = True
- if CondLabel == '!ifdef' or CondLabel == '!ifndef':
- if NotFlag:
- raise Warning("'NOT' operation not allowed for Macro name", self.FileName, self.CurrentLineNumber)
-
if CondLabel == '!if':
-
- if not self.__GetNextOp():
- raise Warning("expected !endif", self.FileName, self.CurrentLineNumber)
-
- if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
- Op = self.__Token
- if not self.__GetNextToken():
- raise Warning("expected value", self.FileName, self.CurrentLineNumber)
- if self.__GetStringData():
- pass
- MacroValue = self.__Token
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
- if NotFlag:
- ConditionSatisfied = not ConditionSatisfied
- BranchDetermined = ConditionSatisfied
- else:
- self.CurrentOffsetWithinLine -= len(self.__Token)
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
- if NotFlag:
- ConditionSatisfied = not ConditionSatisfied
- BranchDetermined = ConditionSatisfied
- IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
- if ConditionSatisfied:
- self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
-
+ ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
else:
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1)
- if NotDefineFlag:
+ ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
+ if CondLabel == '!ifndef':
ConditionSatisfied = not ConditionSatisfied
- BranchDetermined = ConditionSatisfied
- IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
- if ConditionSatisfied:
- self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
+ BranchDetermined = ConditionSatisfied
+ IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
+ if ConditionSatisfied:
+ self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
elif self.__Token in ('!elseif', '!else'):
ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
if len(IfList) <= 0:
raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
+
if IfList[-1][1]:
IfList[-1] = [ElseStartPos, False, True]
self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
@@ -670,27 +765,8 @@ class FdfParser:
self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
if self.__Token == '!elseif':
- MacroName, NotFlag = self.__GetMacroName()
- if not self.__GetNextOp():
- raise Warning("expected !endif", self.FileName, self.CurrentLineNumber)
-
- if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
- Op = self.__Token
- if not self.__GetNextToken():
- raise Warning("expected value", self.FileName, self.CurrentLineNumber)
- if self.__GetStringData():
- pass
- MacroValue = self.__Token
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
- if NotFlag:
- ConditionSatisfied = not ConditionSatisfied
-
- else:
- self.CurrentOffsetWithinLine -= len(self.__Token)
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
- if NotFlag:
- ConditionSatisfied = not ConditionSatisfied
-
+ Expression = self.__GetExpression()
+ ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
if IfList[-1][1]:
@@ -699,115 +775,107 @@ class FdfParser:
else:
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:
self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
IfList.pop()
+ elif not IfList: # Don't use PCDs inside conditional directive
+ if self.CurrentLineNumber <= RegionLayoutLine:
+ # Don't try the same line twice
+ continue
+ SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
+ if SetPcd:
+ self.__PcdDict[SetPcd.group('name')] = SetPcd.group('value')
+ RegionLayoutLine = self.CurrentLineNumber
+ continue
+ RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
+ if not RegionSize:
+ RegionLayoutLine = self.CurrentLineNumber
+ continue
+ RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])
+ if not RegionSizeGuid:
+ RegionLayoutLine = self.CurrentLineNumber + 1
+ continue
+ self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
+ self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
+ RegionLayoutLine = self.CurrentLineNumber + 1
-
- if len(IfList) > 0:
+ if IfList:
raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
self.Rewind()
- def __EvaluateConditional(self, Name, Line, Op = None, Value = None):
+ def __CollectMacroPcd(self):
+ MacroDict = {}
+ # PCD macro
+ MacroDict.update(GlobalData.gPlatformPcds)
+ 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)
- if Name in InputMacroDict:
- MacroValue = InputMacroDict[Name]
- if Op == None:
- if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE':
- return False
- return True
- elif Op == '!=':
- if Value != MacroValue:
- return True
- else:
- return False
- elif Op == '==':
- if Value == MacroValue:
- return True
- else:
- return False
- else:
- if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())):
- InputVal = long(Value, 0)
- MacroVal = long(MacroValue, 0)
- if Op == '>':
- if MacroVal > InputVal:
- return True
- else:
- return False
- elif Op == '>=':
- if MacroVal >= InputVal:
- return True
- else:
- return False
- elif Op == '<':
- if MacroVal < InputVal:
- return True
- else:
- return False
- elif Op == '<=':
- if MacroVal <= InputVal:
- return True
- else:
- return False
- else:
- return False
+ MacroPcdDict = self.__CollectMacroPcd()
+ if Op == 'eval':
+ try:
+ if Value:
+ return ValueExpression(Expression, MacroPcdDict)(True)
else:
- raise Warning("Value %s is not a number", self.FileName, Line)
-
- for Profile in AllMacroList:
- if Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]:
- if Op == None:
- if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE':
- return False
- return True
- elif Op == '!=':
- if Value != Profile.MacroValue:
- return True
- else:
- return False
- elif Op == '==':
- if Value == Profile.MacroValue:
- return True
+ return ValueExpression(Expression, MacroPcdDict)()
+ 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.FileName, ExtraData=self.__CurrentLine(),
+ Line=Line)
+ return Excpt.result
+ except Exception, Excpt:
+ if hasattr(Excpt, 'Pcd'):
+ if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
+ Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]
+ raise Warning("Cannot use this PCD (%s) in an expression as"
+ " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
+ " of the DSC file (%s), and it is currently defined in this section:"
+ " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),
+ *FileLineTuple)
else:
- return False
+ raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),
+ *FileLineTuple)
else:
- if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())):
- InputVal = long(Value, 0)
- MacroVal = long(Profile.MacroValue, 0)
- if Op == '>':
- if MacroVal > InputVal:
- return True
- else:
- return False
- elif Op == '>=':
- if MacroVal >= InputVal:
- return True
- else:
- return False
- elif Op == '<':
- if MacroVal < InputVal:
- return True
- else:
- return False
- elif Op == '<=':
- if MacroVal <= InputVal:
- return True
- else:
- return False
- else:
- return False
- else:
- raise Warning("Value %s is not a number", self.FileName, Line)
-
- return False
+ raise Warning(str(Excpt), *FileLineTuple)
+ else:
+ if Expression.startswith('$(') and Expression[-1] == ')':
+ Expression = Expression[2:-1]
+ return Expression in MacroPcdDict
## __IsToken() method
#
@@ -866,6 +934,16 @@ class FdfParser:
return True
return False
+ def __GetExpression(self):
+ Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
+ Index = len(Line) - 1
+ while Line[Index] in ['\r', '\n']:
+ Index -= 1
+ ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]
+ self.CurrentOffsetWithinLine += len(ExpressionString)
+ ExpressionString = ExpressionString.strip()
+ return ExpressionString
+
## __GetNextWord() method
#
# Get next C name from file lines
@@ -915,7 +993,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.
@@ -1005,7 +1083,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:
@@ -1188,6 +1266,28 @@ class FdfParser:
def SetFileBufferPos(self, Pos):
(self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos
+ ## Preprocess() method
+ #
+ # Preprocess comment, conditional directive, include directive, replace macro.
+ # Exception will be raised if syntax error found
+ #
+ # @param self The object pointer
+ #
+ def Preprocess(self):
+ self.__StringToList()
+ self.PreprocessFile()
+ self.PreprocessIncludeFile()
+ self.__StringToList()
+ self.PreprocessFile()
+ self.PreprocessConditionalStatement()
+ self.__StringToList()
+ for Pos in self.__WipeOffArea:
+ self.__ReplaceFragment(Pos[0], Pos[1])
+ self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
+
+ while self.__GetDefines():
+ pass
+
## ParseFile() method
#
# Parse the file profile buffer to extract fd, fv ... information
@@ -1198,32 +1298,16 @@ class FdfParser:
def ParseFile(self):
try:
- self.__StringToList()
- self.PreprocessFile()
- self.PreprocessIncludeFile()
- self.__StringToList()
- self.PreprocessFile()
- self.PreprocessConditionalStatement()
- self.__StringToList()
- for Pos in self.__WipeOffArea:
- self.__ReplaceFragment(Pos[0], Pos[1])
- self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
-
- 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
-
+ self.Preprocess()
while self.__GetFd():
pass
while self.__GetFv():
pass
+ while self.__GetFmp():
+ pass
+
while self.__GetCapsule():
pass
@@ -1289,11 +1373,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
@@ -1312,7 +1391,7 @@ class FdfParser:
S = self.__Token.upper()
if S.startswith("[") and not S.startswith("[FD."):
- if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
+ if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
self.__UndoToken()
@@ -1329,6 +1408,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)
@@ -1351,7 +1432,15 @@ class FdfParser:
if not Status:
raise Warning("FD name error", self.FileName, self.CurrentLineNumber)
- self.__GetTokenStatements(FdObj)
+ while self.__GetTokenStatements(FdObj):
+ pass
+ for Attr in ("BaseAddress", "Size", "ErasePolarity"):
+ if getattr(FdObj, Attr) == None:
+ self.__GetNextToken()
+ raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)
+
+ if not FdObj.BlockSizeList:
+ FdObj.BlockSizeList.append((1, FdObj.Size, None))
self.__GetDefineStatements(FdObj)
@@ -1408,54 +1497,54 @@ class FdfParser:
# @param Obj for whom token statement is got
#
def __GetTokenStatements(self, Obj):
- if not self.__IsKeyword( "BaseAddress"):
- raise Warning("BaseAddress missing", self.FileName, self.CurrentLineNumber)
-
- if not self.__IsToken( "="):
- raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-
- if not self.__GetNextHexNumber():
- raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
-
- Obj.BaseAddress = self.__Token
-
- if self.__IsToken( "|"):
- pcdPair = self.__GetNextPcdName()
- Obj.BaseAddressPcd = pcdPair
- self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
-
- if not self.__IsKeyword( "Size"):
- raise Warning("Size missing", self.FileName, self.CurrentLineNumber)
-
- if not self.__IsToken( "="):
- raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-
- if not self.__GetNextHexNumber():
- raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
-
-
- Size = self.__Token
- if self.__IsToken( "|"):
- pcdPair = self.__GetNextPcdName()
- Obj.SizePcd = pcdPair
- self.Profile.PcdDict[pcdPair] = Size
- Obj.Size = long(Size, 0)
-
- if not self.__IsKeyword( "ErasePolarity"):
- raise Warning("ErasePolarity missing", self.FileName, self.CurrentLineNumber)
-
- if not self.__IsToken( "="):
- raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+ if self.__IsKeyword( "BaseAddress"):
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextHexNumber():
+ raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
+
+ Obj.BaseAddress = self.__Token
+
+ if self.__IsToken( "|"):
+ pcdPair = self.__GetNextPcdName()
+ Obj.BaseAddressPcd = pcdPair
+ self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
+ return True
- if not self.__GetNextToken():
- raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
+ if self.__IsKeyword( "Size"):
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextHexNumber():
+ raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
- if self.__Token != "1" and self.__Token != "0":
- raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
+ Size = self.__Token
+ if self.__IsToken( "|"):
+ 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)
+ return True
- Obj.ErasePolarity = self.__Token
+ if self.__IsKeyword( "ErasePolarity"):
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextToken():
+ raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
+
+ if self.__Token != "1" and self.__Token != "0":
+ raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
+
+ Obj.ErasePolarity = self.__Token
+ return True
- self.__GetBlockStatements(Obj)
+ return self.__GetBlockStatements(Obj)
## __GetAddressStatements() method
#
@@ -1496,18 +1585,14 @@ class FdfParser:
# @param Obj for whom block statement is got
#
def __GetBlockStatements(self, Obj):
-
- if not self.__GetBlockStatement(Obj):
- #set default block size is 1
- Obj.BlockSizeList.append((1, Obj.Size, None))
- return
-
+ IsBlock = False
while self.__GetBlockStatement(Obj):
- pass
+ IsBlock = True
- for Item in Obj.BlockSizeList:
+ Item = Obj.BlockSizeList[-1]
if Item[0] == None or Item[1] == None:
raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)
+ return IsBlock
## __GetBlockStatement() method
#
@@ -1534,6 +1619,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
@@ -1617,23 +1704,49 @@ 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
+ ## __CalcRegionExpr(self)
+ #
+ # Calculate expression for offset or size of a region
+ #
+ # @return: None if invalid expression
+ # Calculated number if successfully
+ #
+ def __CalcRegionExpr(self):
+ StartPos = self.GetFileBufferPos()
+ Expr = ''
+ PairCount = 0
+ while not self.__EndOfFile():
+ CurCh = self.__CurrentChar()
+ if CurCh == '(':
+ PairCount += 1
+ elif CurCh == ')':
+ PairCount -= 1
+
+ if CurCh in '|\r\n' and PairCount == 0:
+ break
+ Expr += CurCh
+ self.__GetOneChar()
+ try:
+ return long(
+ ValueExpression(Expr,
+ self.__CollectMacroPcd()
+ )(True),0)
+ except Exception:
+ self.SetFileBufferPos(StartPos)
+ return None
+
## __GetRegionLayout() method
#
# Get region layout for FD
@@ -1644,30 +1757,46 @@ class FdfParser:
# @retval False Not able to find
#
def __GetRegionLayout(self, Fd):
- if not self.__GetNextHexNumber():
+ Offset = self.__CalcRegionExpr()
+ if Offset == None:
return False
RegionObj = Region.Region()
- RegionObj.Offset = long(self.__Token, 0)
+ RegionObj.Offset = Offset
Fd.RegionList.append(RegionObj)
if not self.__IsToken( "|"):
raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)
- if not self.__GetNextHexNumber():
+ Size = self.__CalcRegionExpr()
+ if Size == None:
raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)
- RegionObj.Size = long(self.__Token, 0)
+ RegionObj.Size = Size
if not self.__GetNextWord():
return True
if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):
+ #
+ # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
+ # Or it might be next region's offset described by an expression which starts with a PCD.
+ # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
+ #
self.__UndoToken()
- RegionObj.PcdOffset = self.__GetNextPcdName()
- self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
- if self.__IsToken( "|"):
- RegionObj.PcdSize = self.__GetNextPcdName()
- self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
+ IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or
+ RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))
+ if IsRegionPcd:
+ RegionObj.PcdOffset = self.__GetNextPcdName()
+ self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
+ self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset
+ 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
+ self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
if not self.__GetNextWord():
return True
@@ -1694,6 +1823,9 @@ class FdfParser:
self.__UndoToken()
self.__GetRegionDataType( RegionObj)
else:
+ self.__UndoToken()
+ if self.__GetRegionLayout(Fd):
+ return True
raise Warning("A valid region type was not found. "
"Valid types are [SET, FV, CAPSULE, FILE, DATA]. This error occurred",
self.FileName, self.CurrentLineNumber)
@@ -1896,7 +2028,7 @@ class FdfParser:
S = self.__Token.upper()
if S.startswith("[") and not S.startswith("[FV."):
- if not S.startswith("[CAPSULE.") \
+ if not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
self.__UndoToken()
@@ -1927,27 +2059,16 @@ class FdfParser:
self.__GetAddressStatements(FvObj)
- while self.__GetBlockStatement(FvObj):
- pass
-
- self.__GetSetStatements(FvObj)
-
- self.__GetFvBaseAddress(FvObj)
-
- self.__GetFvForceRebase(FvObj)
-
- self.__GetFvAlignment(FvObj)
-
- self.__GetFvAttributes(FvObj)
-
- self.__GetFvNameGuid(FvObj)
-
FvObj.FvExtEntryTypeValue = []
FvObj.FvExtEntryType = []
FvObj.FvExtEntryData = []
while True:
- isFvExtEntry = self.__GetFvExtEntryStatement(FvObj)
- if not isFvExtEntry:
+ self.__GetSetStatements(FvObj)
+
+ if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or
+ self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or
+ self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or
+ self.__GetFvExtEntryStatement(FvObj)):
break
self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
@@ -2014,8 +2135,8 @@ class FdfParser:
if not IsValidBaseAddrValue.match(self.__Token.upper()):
raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
Obj.FvBaseAddress = self.__Token
- return True
-
+ return True
+
## __GetFvForceRebase() method
#
# Get FvForceRebase for FV
@@ -2047,7 +2168,8 @@ class FdfParser:
Obj.FvForceRebase = None
return True
-
+
+
## __GetFvAttributes() method
#
# Get attributes for FV
@@ -2057,17 +2179,18 @@ class FdfParser:
# @retval None
#
def __GetFvAttributes(self, FvObj):
-
+ IsWordToken = False
while self.__GetNextWord():
+ IsWordToken = True
name = self.__Token
if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
"STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
"WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
"READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
"READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
- "WRITE_POLICY_RELIABLE"):
+ "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):
self.__UndoToken()
- return
+ return False
if not self.__IsToken( "="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
@@ -2077,7 +2200,7 @@ class FdfParser:
FvObj.FvAttributeDict[name] = self.__Token
- return
+ return IsWordToken
## __GetFvNameGuid() method
#
@@ -2090,7 +2213,7 @@ class FdfParser:
def __GetFvNameGuid(self, FvObj):
if not self.__IsKeyword( "FvNameGuid"):
- return
+ return False
if not self.__IsToken( "="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
@@ -2100,7 +2223,7 @@ class FdfParser:
FvObj.FvNameGuid = self.__Token
- return
+ return True
def __GetFvExtEntryStatement(self, FvObj):
@@ -2236,6 +2359,13 @@ class FdfParser:
if not self.__GetNextToken():
raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
ffsInf.InfFileName = self.__Token
+
+ ffsInf.CurrentLineNum = self.CurrentLineNumber
+ ffsInf.CurrentLineContent = self.__CurrentLine()
+
+ #Replace $(SAPCE) with real space
+ ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')
+
if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
#do case sensitive check for file path
ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
@@ -2244,6 +2374,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'):
@@ -2253,9 +2385,6 @@ class FdfParser:
else:
raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
- ffsInf.CurrentLineNum = self.CurrentLineNumber
- ffsInf.CurrentLineContent = self.__CurrentLine()
-
if ForCapsule:
capsuleFfs = CapsuleData.CapsuleFfs()
capsuleFfs.Ffs = ffsInf
@@ -2272,6 +2401,12 @@ class FdfParser:
# @param FfsInfObj for whom option is got
#
def __GetInfOptions(self, FfsInfObj):
+ if self.__IsKeyword("FILE_GUID"):
+ if not self.__IsToken("="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+ if not self.__GetNextGuid():
+ raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)
+ FfsInfObj.OverrideGuid = self.__Token
if self.__IsKeyword( "RuleOverride"):
if not self.__IsToken( "="):
@@ -2307,8 +2442,8 @@ class FdfParser:
if self.__GetNextToken():
- p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
- if p.match(self.__Token):
+ p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
+ if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):
FfsInfObj.KeyStringList.append(self.__Token)
if not self.__IsToken(","):
return
@@ -2366,9 +2501,6 @@ class FdfParser:
FfsFileObj.NameGuid = self.__Token
- FfsFileObj.CurrentLineNum = self.CurrentLineNumber
- FfsFileObj.CurrentLineContent = self.__CurrentLine()
-
self.__GetFilePart( FfsFileObj, MacroDict.copy())
if ForCapsule:
@@ -2425,16 +2557,16 @@ class FdfParser:
self.__GetFileOpts( FfsFileObj)
if not self.__IsToken("{"):
-# if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
-# if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
-# if self.__Token == 'RELOCS_STRIPPED':
-# FfsFileObj.KeepReloc = False
-# else:
-# FfsFileObj.KeepReloc = True
-# else:
-# raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
-#
-# if not self.__IsToken("{"):
+ if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
+ if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
+ if self.__Token == 'RELOCS_STRIPPED':
+ FfsFileObj.KeepReloc = False
+ else:
+ FfsFileObj.KeepReloc = True
+ else:
+ raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
+
+ if not self.__IsToken("{"):
raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
if not self.__GetNextToken():
@@ -2458,22 +2590,10 @@ class FdfParser:
self.__UndoToken()
self.__GetSectionData( FfsFileObj, MacroDict)
else:
- FfsFileObj.FileName = self.__Token
- if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
- #
- # For file in OUTPUT_DIRECTORY will not check whether it exist or not at AutoGen phase.
- #
- if not GlobalData.gAutoGenPhase:
- #do case sensitive check for file path
- ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
- else:
- if not InputMacroDict["OUTPUT_DIRECTORY"] in FfsFileObj.FileName:
- #do case sensitive check for file path
- ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
+ FfsFileObj.CurrentLineNum = self.CurrentLineNumber
+ FfsFileObj.CurrentLineContent = self.__CurrentLine()
+ FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')
+ self.__VerifyFile(FfsFileObj.FileName)
if not self.__IsToken( "}"):
raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
@@ -2719,11 +2839,7 @@ class FdfParser:
if not self.__GetNextToken():
raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)
DataSectionObj.SectFileName = self.__Token
- if DataSectionObj.SectFileName.replace('$(WORKSPACE)', '').find('$') == -1:
- #do case sensitive check for file path
- ErrorCode, ErrorInfo = PathClass(NormPath(DataSectionObj.SectFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
+ self.__VerifyFile(DataSectionObj.SectFileName)
else:
if not self.__GetCglSection(DataSectionObj):
return False
@@ -2732,6 +2848,21 @@ class FdfParser:
return True
+ ## __VerifyFile
+ #
+ # Check if file exists or not:
+ # If current phase if GenFds, the file must exist;
+ # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
+ # @param FileName: File path to be verified.
+ #
+ def __VerifyFile(self, FileName):
+ if FileName.replace('$(WORKSPACE)', '').find('$') != -1:
+ return
+ if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName:
+ ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
+ if ErrorCode != 0:
+ EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
+
## __GetCglSection() method
#
# Get compressed or GUIDed section for Obj
@@ -2786,6 +2917,7 @@ class FdfParser:
GuidSectionObj.SectionType = "GUIDED"
GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
+ GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
# Recursive sections...
while True:
IsLeafSection = self.__GetLeafSection(GuidSectionObj)
@@ -2813,23 +2945,26 @@ class FdfParser:
AttribDict = {}
AttribDict["PROCESSING_REQUIRED"] = "NONE"
AttribDict["AUTH_STATUS_VALID"] = "NONE"
- if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
+ AttribDict["EXTRA_HEADER_SIZE"] = -1
+ while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \
+ or self.__IsKeyword("EXTRA_HEADER_SIZE"):
AttribKey = self.__Token
if not self.__IsToken("="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
- if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
- raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
- AttribDict[AttribKey] = self.__Token
-
- if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
- AttribKey = self.__Token
-
- if not self.__IsToken("="):
- raise Warning("expected '='")
-
- if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
+ if not self.__GetNextToken():
+ raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)
+ elif AttribKey == "EXTRA_HEADER_SIZE":
+ Base = 10
+ if self.__Token[0:2].upper() == "0X":
+ Base = 16
+ try:
+ AttribDict[AttribKey] = int(self.__Token, Base)
+ continue
+ except ValueError:
+ raise Warning("expected Number", self.FileName, self.CurrentLineNumber)
+ elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
AttribDict[AttribKey] = self.__Token
@@ -2865,6 +3000,67 @@ class FdfParser:
else:
return True
+ def __GetFmp(self):
+ if not self.__GetNextToken():
+ return False
+ S = self.__Token.upper()
+ if not S.startswith("[FMPPAYLOAD."):
+ if not S.startswith("[CAPSULE.") and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
+ raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [FmpPayload.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
+ self.__UndoToken()
+ return False
+
+ self.__UndoToken()
+ self.__SkipToToken("[FMPPAYLOAD.", True)
+ FmpUiName = self.__GetUiName().upper()
+ if FmpUiName in self.Profile.FmpPayloadDict:
+ raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)
+
+ FmpData = CapsuleData.CapsulePayload()
+ FmpData.UiName = FmpUiName
+
+ if not self.__IsToken( "]"):
+ raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextToken():
+ raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)
+ FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']
+ while self.__Token in FmpKeyList:
+ Name = self.__Token
+ FmpKeyList.remove(Name)
+ if not self.__IsToken("="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+ if Name == 'IMAGE_TYPE_ID':
+ if not self.__GetNextGuid():
+ raise Warning("expected GUID value for IMAGE_TYPE_ID", self.FileName, self.CurrentLineNumber)
+ FmpData.ImageTypeId = self.__Token
+ else:
+ if not self.__GetNextToken():
+ raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)
+ Value = self.__Token
+ if Name == 'IMAGE_HEADER_INIT_VERSION':
+ FmpData.Version = Value
+ elif Name == 'IMAGE_INDEX':
+ FmpData.ImageIndex = Value
+ elif Name == 'HARDWARE_INSTANCE':
+ FmpData.HardwareInstance = Value
+ if not self.__GetNextToken():
+ break
+ else:
+ self.__UndoToken()
+
+ if FmpKeyList:
+ raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)
+ ImageFile = self.__ParseRawFileStatement()
+ if not ImageFile:
+ raise Warning("Missing image file in FMP payload section", self.FileName, self.CurrentLineNumber)
+ FmpData.ImageFile = ImageFile
+ VendorCodeFile = self.__ParseRawFileStatement()
+ if VendorCodeFile:
+ FmpData.VendorCodeFile = VendorCodeFile
+ self.Profile.FmpPayloadDict[FmpUiName] = FmpData
+ return True
+
## __GetCapsule() method
#
# Get capsule section contents and store its data into capsule list of self.Profile
@@ -2939,7 +3135,7 @@ class FdfParser:
def __GetCapsuleTokens(self, Obj):
if not self.__GetNextToken():
return False
- while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS"):
+ while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):
Name = self.__Token.strip()
if not self.__IsToken("="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
@@ -2956,6 +3152,17 @@ class FdfParser:
if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
Value += self.__Token.strip()
+ elif Name == 'OEM_CAPSULE_FLAGS':
+ Value = self.__Token.strip()
+ if not Value.upper().startswith('0X'):
+ raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
+ try:
+ Value = int(Value, 0)
+ except ValueError:
+ raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
+ if not 0x0000 <= Value <= 0xFFFF:
+ raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
+ Value = self.__Token.strip()
else:
Value = self.__Token.strip()
Obj.TokensDict[Name] = Value
@@ -2978,7 +3185,9 @@ class FdfParser:
IsFv = self.__GetFvStatement(Obj)
IsFd = self.__GetFdStatement(Obj)
IsAnyFile = self.__GetAnyFileStatement(Obj)
- if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile):
+ IsAfile = self.__GetAfileStatement(Obj)
+ IsFmp = self.__GetFmpStatement(Obj)
+ if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):
break
## __GetFvStatement() method
@@ -3001,6 +3210,9 @@ class FdfParser:
if not self.__GetNextToken():
raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
+ if self.__Token.upper() not in self.Profile.FvDict.keys():
+ raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)
+
CapsuleFv = CapsuleData.CapsuleFv()
CapsuleFv.FvName = self.__Token
CapsuleObj.CapsuleDataList.append(CapsuleFv)
@@ -3026,28 +3238,40 @@ class FdfParser:
if not self.__GetNextToken():
raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
+ if self.__Token.upper() not in self.Profile.FdDict.keys():
+ raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)
+
CapsuleFd = CapsuleData.CapsuleFd()
CapsuleFd.FdName = self.__Token
CapsuleObj.CapsuleDataList.append(CapsuleFd)
return True
- ## __GetAnyFileStatement() method
- #
- # Get AnyFile for capsule
- #
- # @param self The object pointer
- # @param CapsuleObj for whom AnyFile is got
- # @retval True Successfully find a Anyfile statement
- # @retval False Not able to find a AnyFile statement
- #
- def __GetAnyFileStatement(self, CapsuleObj):
+ def __GetFmpStatement(self, CapsuleObj):
+ if not self.__IsKeyword("FMP"):
+ return False
- if not self.__IsKeyword("FILE"):
+ if not self.__IsKeyword("PAYLOAD"):
+ self.__UndoToken()
return False
+ if not self.__IsToken("="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextToken():
+ raise Warning("expected payload name after FMP PAYLOAD =", self.FileName, self.CurrentLineNumber)
+ Payload = self.__Token.upper()
+ if Payload not in self.Profile.FmpPayloadDict:
+ raise Warning("This FMP Payload does not exist: %s" % self.__Token, self.FileName, self.CurrentLineNumber)
+ CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])
+ return True
+
+ def __ParseRawFileStatement(self):
+ if not self.__IsKeyword("FILE"):
+ return None
+
if not self.__IsKeyword("DATA"):
self.__UndoToken()
- return False
+ return None
if not self.__IsToken("="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
@@ -3059,11 +3283,67 @@ class FdfParser:
AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName)
if not os.path.exists(AnyFileName):
raise Warning("File %s not exists"%AnyFileName, self.FileName, self.CurrentLineNumber)
+ return AnyFileName
+
+ ## __GetAnyFileStatement() method
+ #
+ # Get AnyFile for capsule
+ #
+ # @param self The object pointer
+ # @param CapsuleObj for whom AnyFile is got
+ # @retval True Successfully find a Anyfile statement
+ # @retval False Not able to find a AnyFile statement
+ #
+ def __GetAnyFileStatement(self, CapsuleObj):
+ AnyFileName = self.__ParseRawFileStatement()
+ if not AnyFileName:
+ return False
CapsuleAnyFile = CapsuleData.CapsuleAnyFile()
CapsuleAnyFile.FileName = AnyFileName
CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)
return True
+
+ ## __GetAfileStatement() method
+ #
+ # Get Afile for capsule
+ #
+ # @param self The object pointer
+ # @param CapsuleObj for whom Afile is got
+ # @retval True Successfully find a Afile statement
+ # @retval False Not able to find a Afile statement
+ #
+ def __GetAfileStatement(self, CapsuleObj):
+
+ if not self.__IsKeyword("APPEND"):
+ return False
+
+ if not self.__IsToken("="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextToken():
+ raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)
+
+ AfileName = self.__Token
+ AfileBaseName = os.path.basename(AfileName)
+
+ if os.path.splitext(AfileBaseName)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:
+ raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \
+ self.FileName, self.CurrentLineNumber)
+
+ if not os.path.isabs(AfileName):
+ AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)
+ self.__VerifyFile(AfileName)
+ else:
+ if not os.path.exists(AfileName):
+ raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)
+ else:
+ pass
+
+ CapsuleAfile = CapsuleData.CapsuleAfile()
+ CapsuleAfile.FileName = AfileName
+ CapsuleObj.CapsuleDataList.append(CapsuleAfile)
+ return True
## __GetRule() method
#
@@ -3095,7 +3375,7 @@ class FdfParser:
raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
Arch = self.__SkippedChars.rstrip(".")
- if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "COMMON"):
+ if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
ModuleType = self.__GetModuleType()
@@ -3625,6 +3905,7 @@ class FdfParser:
GuidSectionObj.SectionType = "GUIDED"
GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
+ GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
# Efi sections...
while True:
@@ -3672,7 +3953,7 @@ class FdfParser:
raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
Arch = self.__SkippedChars.rstrip(".").upper()
- if Arch not in ("IA32", "X64", "IPF", "ARM"):
+ if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
if not self.__GetNextWord():
@@ -3686,7 +3967,7 @@ class FdfParser:
if self.__IsToken(","):
if not self.__GetNextWord():
raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)
- if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM"):
+ if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
VtfObj.ArchList = self.__Token.upper()
@@ -3914,6 +4195,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)