## @file
# parse FDF file
#
#  Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
#  Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
#
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#

##
# Import Modules
#
from __future__ import print_function
from __future__ import absolute_import
from re import compile, DOTALL
from string import hexdigits
from uuid import UUID

from Common.BuildToolError import *
from Common import EdkLogger
from Common.Misc import PathClass, tdict, ProcessDuplicatedInf, GuidStructureStringToGuidString
from Common.StringUtils import NormPath, ReplaceMacro
from Common import GlobalData
from Common.Expression import *
from Common.DataType import *
from Common.MultipleWorkspace import MultipleWorkspace as mws
import Common.LongFilePathOs as os
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.RangeExpression import RangeExpression
from collections import OrderedDict

from .Fd import FD
from .Region import Region
from .Fv import FV
from .AprioriSection import AprioriSection
from .FfsInfStatement import FfsInfStatement
from .FfsFileStatement import FileStatement
from .VerSection import VerSection
from .UiSection import UiSection
from .FvImageSection import FvImageSection
from .DataSection import DataSection
from .DepexSection import DepexSection
from .CompressSection import CompressSection
from .GuidSection import GuidSection
from .SubTypeGuidSection import SubTypeGuidSection
from .Capsule import EFI_CERT_TYPE_PKCS7_GUID, EFI_CERT_TYPE_RSA2048_SHA256_GUID, Capsule
from .CapsuleData import CapsuleFfs, CapsulePayload, CapsuleFv, CapsuleFd, CapsuleAnyFile, CapsuleAfile
from .RuleComplexFile import RuleComplexFile
from .RuleSimpleFile import RuleSimpleFile
from .EfiSection import EfiSection
from .OptionRom import OPTIONROM
from .OptRomInfStatement import OptRomInfStatement, OverrideAttribs
from .OptRomFileStatement import OptRomFileStatement
from .GenFdsGlobalVariable import GenFdsGlobalVariable

T_CHAR_CR = '\r'
T_CHAR_TAB = '\t'
T_CHAR_DOUBLE_QUOTE = '\"'
T_CHAR_SINGLE_QUOTE = '\''
T_CHAR_BRACE_R = '}'

SEPARATORS = {TAB_EQUAL_SPLIT, TAB_VALUE_SPLIT, TAB_COMMA_SPLIT, '{', T_CHAR_BRACE_R}
ALIGNMENTS = {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
                                    "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
ALIGNMENT_NOAUTO = ALIGNMENTS - {"Auto"}
CR_LB_SET = {T_CHAR_CR, TAB_LINE_BREAK}

RegionSizePattern = compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
RegionSizeGuidPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
RegionOffsetPcdPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
ShortcutPcdPattern = compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
BaseAddrValuePattern = compile('^0[xX][0-9a-fA-F]+')
FileExtensionPattern = compile(r'([a-zA-Z][a-zA-Z0-9]*)')
TokenFindPattern = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
AllIncludeFileList = []

# Get the closest parent
def GetParentAtLine (Line):
    for Profile in AllIncludeFileList:
        if Profile.IsLineInFile(Line):
            return Profile
    return None

# Check include loop
def IsValidInclude (File, Line):
    for Profile in AllIncludeFileList:
        if Profile.IsLineInFile(Line) and Profile.FileName == File:
            return False

    return True

def GetRealFileLine (File, Line):
    InsertedLines = 0
    for Profile in AllIncludeFileList:
        if Profile.IsLineInFile(Line):
            return Profile.GetLineInFile(Line)
        elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:
            InsertedLines += Profile.GetTotalLines()

    return (File, Line - InsertedLines)

## The exception class that used to report error messages when parsing FDF
#
# Currently the "ToolName" is set to be "FdfParser".
#
class Warning (Exception):
    ## The constructor
    #
    #   @param  self        The object pointer
    #   @param  Str         The message to record
    #   @param  File        The FDF name
    #   @param  Line        The Line number that error occurs
    #
    def __init__(self, Str, File = None, Line = None):
        FileLineTuple = GetRealFileLine(File, Line)
        self.FileName = FileLineTuple[0]
        self.LineNumber = FileLineTuple[1]
        self.OriginalLineNumber = Line
        self.Message = Str
        self.ToolName = 'FdfParser'

    def __str__(self):
        return self.Message

    # helper functions to facilitate consistency in warnings
    # each function is for a different common warning
    @staticmethod
    def Expected(Str, File, Line):
        return Warning("expected {}".format(Str), File, Line)
    @staticmethod
    def ExpectedEquals(File, Line):
        return Warning.Expected("'='", File, Line)
    @staticmethod
    def ExpectedCurlyOpen(File, Line):
        return Warning.Expected("'{'", File, Line)
    @staticmethod
    def ExpectedCurlyClose(File, Line):
        return Warning.Expected("'}'", File, Line)
    @staticmethod
    def ExpectedBracketClose(File, Line):
        return Warning.Expected("']'", File, Line)

## The Include file content class that used to record file data when parsing include file
#
# May raise Exception when opening file.
#
class IncludeFileProfile:
    ## The constructor
    #
    #   @param  self        The object pointer
    #   @param  FileName    The file that to be parsed
    #
    def __init__(self, FileName):
        self.FileName = FileName
        self.FileLinesList = []
        try:
            with open(FileName, "r") as fsock:
                self.FileLinesList = fsock.readlines()
                for index, line in enumerate(self.FileLinesList):
                    if not line.endswith(TAB_LINE_BREAK):
                        self.FileLinesList[index] += TAB_LINE_BREAK
        except:
            EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)

        self.InsertStartLineNumber = None
        self.InsertAdjust = 0
        self.IncludeFileList = []
        self.Level = 1 # first level include file

    def GetTotalLines(self):
        TotalLines = self.InsertAdjust + len(self.FileLinesList)

        for Profile in self.IncludeFileList:
            TotalLines += Profile.GetTotalLines()

        return TotalLines

    def IsLineInFile(self, Line):
        if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():
            return True

        return False

    def GetLineInFile(self, Line):
        if not self.IsLineInFile (Line):
            return (self.FileName, -1)

        InsertedLines = self.InsertStartLineNumber

        for Profile in self.IncludeFileList:
            if Profile.IsLineInFile(Line):
                return Profile.GetLineInFile(Line)
            elif Line >= Profile.InsertStartLineNumber:
                InsertedLines += Profile.GetTotalLines()

        return (self.FileName, Line - InsertedLines + 1)

## The FDF content class that used to record file data when parsing FDF
#
# May raise Exception when opening file.
#
class FileProfile:
    ## The constructor
    #
    #   @param  self        The object pointer
    #   @param  FileName    The file that to be parsed
    #
    def __init__(self, FileName):
        self.FileLinesList = []
        try:
            with open(FileName, "r") as fsock:
                self.FileLinesList = fsock.readlines()

        except:
            EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)

        self.FileName = FileName
        self.PcdDict = OrderedDict()
        self.PcdLocalDict = OrderedDict()
        self.InfList = []
        self.InfDict = {'ArchTBD':[]}
        # ECC will use this Dict and List information
        self.PcdFileLineDict = {}
        self.InfFileLineList = []

        self.FdDict = {}
        self.FdNameNotSet = False
        self.FvDict = {}
        self.CapsuleDict = {}
        self.RuleDict = {}
        self.OptRomDict = {}
        self.FmpPayloadDict = {}

## The syntax parser for FDF
#
# PreprocessFile method should be called prior to ParseFile
# CycleReferenceCheck method can detect cycles in FDF contents
#
# GetNext*** procedures mean these procedures will get next token first, then make judgement.
# Get*** procedures mean these procedures will make judgement on current token only.
#
class FdfParser:
    ## The constructor
    #
    #   @param  self        The object pointer
    #   @param  FileName    The file that to be parsed
    #
    def __init__(self, FileName):
        self.Profile = FileProfile(FileName)
        self.FileName = FileName
        self.CurrentLineNumber = 1
        self.CurrentOffsetWithinLine = 0
        self.CurrentFdName = None
        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 = OrderedDict()

        self._WipeOffArea = []
        if GenFdsGlobalVariable.WorkSpaceDir == '':
            GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")

    ## _SkipWhiteSpace() method
    #
    #   Skip white spaces from current char.
    #
    #   @param  self        The object pointer
    #
    def _SkipWhiteSpace(self):
        while not self._EndOfFile():
            if self._CurrentChar() in {TAB_PRINTCHAR_NUL, T_CHAR_CR, TAB_LINE_BREAK, TAB_SPACE_SPLIT, T_CHAR_TAB}:
                self._SkippedChars += str(self._CurrentChar())
                self._GetOneChar()
            else:
                return
        return

    ## _EndOfFile() method
    #
    #   Judge current buffer pos is at file end
    #
    #   @param  self        The object pointer
    #   @retval True        Current File buffer position is at file end
    #   @retval False       Current File buffer position is NOT at file end
    #
    def _EndOfFile(self):
        NumberOfLines = len(self.Profile.FileLinesList)
        SizeOfLastLine = len(self.Profile.FileLinesList[-1])
        if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
            return True
        if self.CurrentLineNumber > NumberOfLines:
            return True
        return False

    ## _EndOfLine() method
    #
    #   Judge current buffer pos is at line end
    #
    #   @param  self        The object pointer
    #   @retval True        Current File buffer position is at line end
    #   @retval False       Current File buffer position is NOT at line end
    #
    def _EndOfLine(self):
        if self.CurrentLineNumber > len(self.Profile.FileLinesList):
            return True
        SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
        if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
            return True
        return False

    ## Rewind() method
    #
    #   Reset file data buffer to the initial state
    #
    #   @param  self        The object pointer
    #   @param  DestLine    Optional new destination line number.
    #   @param  DestOffset  Optional new destination offset.
    #
    def Rewind(self, DestLine = 1, DestOffset = 0):
        self.CurrentLineNumber = DestLine
        self.CurrentOffsetWithinLine = DestOffset

    ## _UndoOneChar() method
    #
    #   Go back one char in the file buffer
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully go back one char
    #   @retval False       Not able to go back one char as file beginning reached
    #
    def _UndoOneChar(self):
        if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
            return False
        elif self.CurrentOffsetWithinLine == 0:
            self.CurrentLineNumber -= 1
            self.CurrentOffsetWithinLine = len(self._CurrentLine()) - 1
        else:
            self.CurrentOffsetWithinLine -= 1
        return True

    ## _GetOneChar() method
    #
    #   Move forward one char in the file buffer
    #
    #   @param  self        The object pointer
    #
    def _GetOneChar(self):
        if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
            self.CurrentLineNumber += 1
            self.CurrentOffsetWithinLine = 0
        else:
            self.CurrentOffsetWithinLine += 1

    ## _CurrentChar() method
    #
    #   Get the char pointed to by the file buffer pointer
    #
    #   @param  self        The object pointer
    #   @retval Char        Current char
    #
    def _CurrentChar(self):
        return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]

    ## _NextChar() method
    #
    #   Get the one char pass the char pointed to by the file buffer pointer
    #
    #   @param  self        The object pointer
    #   @retval Char        Next char
    #
    def _NextChar(self):
        if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
            return self.Profile.FileLinesList[self.CurrentLineNumber][0]
        return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]

    ## _SetCurrentCharValue() method
    #
    #   Modify the value of current char
    #
    #   @param  self        The object pointer
    #   @param  Value       The new value of current char
    #
    def _SetCurrentCharValue(self, Value):
        self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value

    ## _CurrentLine() method
    #
    #   Get the list that contains current line contents
    #
    #   @param  self        The object pointer
    #   @retval List        current line contents
    #
    def _CurrentLine(self):
        return self.Profile.FileLinesList[self.CurrentLineNumber - 1]

    def _StringToList(self):
        self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
        if not self.Profile.FileLinesList:
            EdkLogger.error('FdfParser', FILE_READ_FAILURE, 'The file is empty!', File=self.FileName)
        self.Profile.FileLinesList[-1].append(' ')

    def _ReplaceFragment(self, StartPos, EndPos, Value = ' '):
        if StartPos[0] == EndPos[0]:
            Offset = StartPos[1]
            while Offset <= EndPos[1]:
                self.Profile.FileLinesList[StartPos[0]][Offset] = Value
                Offset += 1
            return

        Offset = StartPos[1]
        while self.Profile.FileLinesList[StartPos[0]][Offset] not in CR_LB_SET:
            self.Profile.FileLinesList[StartPos[0]][Offset] = Value
            Offset += 1

        Line = StartPos[0]
        while Line < EndPos[0]:
            Offset = 0
            while self.Profile.FileLinesList[Line][Offset] not in CR_LB_SET:
                self.Profile.FileLinesList[Line][Offset] = Value
                Offset += 1
            Line += 1

        Offset = 0
        while Offset <= EndPos[1]:
            self.Profile.FileLinesList[EndPos[0]][Offset] = Value
            Offset += 1

    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
        # [OptionRom.DriverName]
        self._CurSection = []
        Section = Section.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT)
        ItemList = Section.split(TAB_SPLIT)
        Item = ItemList[0]
        if Item == '' or Item == 'RULE':
            return

        if Item == TAB_COMMON_DEFINES.upper():
            self._CurSection = [TAB_COMMON, TAB_COMMON, TAB_COMMON]
        elif len(ItemList) > 1:
            self._CurSection = [ItemList[0], ItemList[1], TAB_COMMON]
        elif len(ItemList) > 0:
            self._CurSection = [ItemList[0], 'DUMMY', TAB_COMMON]

    ## PreprocessFile() method
    #
    #   Preprocess file contents, replace comments with spaces.
    #   In the end, rewind the file buffer pointer to the beginning
    #   BUGBUG: No !include statement processing contained in this procedure
    #   !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
    #
    #   @param  self        The object pointer
    #
    def PreprocessFile(self):
        self.Rewind()
        InComment = False
        DoubleSlashComment = False
        HashComment = False
        # HashComment in quoted string " " is ignored.
        InString = False

        while not self._EndOfFile():

            if self._CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
                InString = not InString
            # meet new line, then no longer in a comment for // and '#'
            if self._CurrentChar() == TAB_LINE_BREAK:
                self.CurrentLineNumber += 1
                self.CurrentOffsetWithinLine = 0
                if InComment and DoubleSlashComment:
                    InComment = False
                    DoubleSlashComment = False
                if InComment and HashComment:
                    InComment = False
                    HashComment = False
            # check for */ comment end
            elif InComment and not DoubleSlashComment and not HashComment and self._CurrentChar() == TAB_STAR and self._NextChar() == TAB_BACK_SLASH:
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
                InComment = False
            # set comments to spaces
            elif InComment:
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
            # check for // comment
            elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_BACK_SLASH and not self._EndOfLine():
                InComment = True
                DoubleSlashComment = True
            # check for '#' comment
            elif self._CurrentChar() == TAB_COMMENT_SPLIT and not self._EndOfLine() and not InString:
                InComment = True
                HashComment = True
            # check for /* comment start
            elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_STAR:
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
                InComment = True
            else:
                self._GetOneChar()

        # restore from ListOfList to ListOfString
        self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
        self.Rewind()

    ## PreprocessIncludeFile() method
    #
    #   Preprocess file contents, replace !include statements with file contents.
    #   In the end, rewind the file buffer pointer to the beginning
    #
    #   @param  self        The object pointer
    #
    def PreprocessIncludeFile(self):
      # nested include support
        Processed = False
        MacroDict = {}
        while self._GetNextToken():

            if self._Token == TAB_DEFINE:
                if not self._GetNextToken():
                    raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber)
                Macro = self._Token
                if not self._IsToken(TAB_EQUAL_SPLIT):
                    raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                Value = self._GetExpression()
                MacroDict[Macro] = Value

            elif self._Token == TAB_INCLUDE:
                Processed = True
                IncludeLine = self.CurrentLineNumber
                IncludeOffset = self.CurrentOffsetWithinLine - len(TAB_INCLUDE)
                if not self._GetNextToken():
                    raise Warning.Expected("include file name", self.FileName, self.CurrentLineNumber)
                IncFileName = self._Token
                PreIndex = 0
                StartPos = IncFileName.find('$(', PreIndex)
                EndPos = IncFileName.find(')', StartPos+2)
                while StartPos != -1 and EndPos != -1:
                    Macro = IncFileName[StartPos+2: EndPos]
                    MacroVal = self._GetMacroValue(Macro)
                    if not MacroVal:
                        if Macro in MacroDict:
                            MacroVal = MacroDict[Macro]
                    if MacroVal is not None:
                        IncFileName = IncFileName.replace('$(' + Macro + ')', MacroVal, 1)
                        if MacroVal.find('$(') != -1:
                            PreIndex = StartPos
                        else:
                            PreIndex = StartPos + len(MacroVal)
                    else:
                        raise Warning("The Macro %s is not defined" %Macro, self.FileName, self.CurrentLineNumber)
                    StartPos = IncFileName.find('$(', PreIndex)
                    EndPos = IncFileName.find(')', StartPos+2)

                IncludedFile = NormPath(IncFileName)
                #
                # 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)

                if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):
                    raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)

                IncFileProfile = IncludeFileProfile(IncludedFile1.Path)

                CurrentLine = self.CurrentLineNumber
                CurrentOffset = self.CurrentOffsetWithinLine
                # list index of the insertion, note that line number is 'CurrentLine + 1'
                InsertAtLine = CurrentLine
                ParentProfile = GetParentAtLine (CurrentLine)
                if ParentProfile is not None:
                    ParentProfile.IncludeFileList.insert(0, IncFileProfile)
                    IncFileProfile.Level = ParentProfile.Level + 1
                IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
                # deal with remaining portions after "!include filename", if exists.
                if self._GetNextToken():
                    if self.CurrentLineNumber == CurrentLine:
                        RemainingLine = self._CurrentLine()[CurrentOffset:]
                        self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
                        IncFileProfile.InsertAdjust += 1
                        self.CurrentLineNumber += 1
                        self.CurrentOffsetWithinLine = 0

                for Line in IncFileProfile.FileLinesList:
                    self.Profile.FileLinesList.insert(InsertAtLine, Line)
                    self.CurrentLineNumber += 1
                    InsertAtLine += 1

                # reversely sorted to better determine error in file
                AllIncludeFileList.insert(0, IncFileProfile)

                # comment out the processed include file statement
                TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
                TempList.insert(IncludeOffset, TAB_COMMENT_SPLIT)
                self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
            if Processed: # Nested and back-to-back support
                self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)
                Processed = False
        # Preprocess done.
        self.Rewind()

    @staticmethod
    def _GetIfListCurrentItemStat(IfList):
        if len(IfList) == 0:
            return True

        for Item in IfList:
            if Item[1] == False:
                return False

        return True

    ## PreprocessConditionalStatement() method
    #
    #   Preprocess conditional statement.
    #   In the end, rewind the file buffer pointer to the beginning
    #
    #   @param  self        The object pointer
    #
    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(TAB_SECTION_START):
                    Header = self._Token
                    if not self._Token.endswith(TAB_SECTION_END):
                        self._SkipToToken(TAB_SECTION_END)
                        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 {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF, TAB_ELSE_IF}:
                        MacroName = CurLine[StartPos+2: EndPos]
                        MacroValue = self._GetMacroValue(MacroName)
                        if MacroValue is not None:
                            CurLine = CurLine.replace('$(' + MacroName + ')', MacroValue, 1)
                            if MacroValue.find('$(') != -1:
                                PreIndex = StartPos
                            else:
                                PreIndex = StartPos + len(MacroValue)
                        else:
                            PreIndex = EndPos + 1
                        StartPos = CurLine.find('$(', PreIndex)
                        EndPos = CurLine.find(')', StartPos+2)
                    self.Profile.FileLinesList[ReplacedLine - 1] = CurLine
                    continue

            if self._Token == TAB_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(TAB_DEFINE)
                    if not self._GetNextToken():
                        raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber)
                    Macro = self._Token
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

                    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._GetNextPcdSettings()
                PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
                if not self._IsToken(TAB_EQUAL_SPLIT):
                    raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

                Value = self._GetExpression()
                Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)

                self._PcdDict[PcdName] = Value

                self.Profile.PcdDict[PcdPair] = Value
                self.SetPcdLocalation(PcdPair)
                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 {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF}:
                IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))
                IfList.append([IfStartPos, None, None])

                CondLabel = self._Token
                Expression = self._GetExpression()

                if CondLabel == TAB_IF:
                    ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
                else:
                    ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
                    if CondLabel == TAB_IF_N_DEF:
                        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)))
            elif self._Token in {TAB_ELSE_IF, TAB_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)))
                else:
                    self._WipeOffArea.append((IfList[-1][0], ElseStartPos))
                    IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
                    if self._Token == TAB_ELSE_IF:
                        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]:
                        if IfList[-1][2]:
                            IfList[-1][1] = False
                        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 IfList:
            raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
        self.Rewind()

    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[TAB_COMMON, TAB_COMMON, TAB_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)
        for Item in GlobalData.BuildOptionPcd:
            if isinstance(Item, tuple):
                continue
            PcdName, TmpValue = Item.split(TAB_EQUAL_SPLIT)
            TmpValue = BuildOptionValue(TmpValue, {})
            MacroDict[PcdName.strip()] = TmpValue
        # Highest priority

        return MacroDict

    def _EvaluateConditional(self, Expression, Line, Op = None, Value = None):
        MacroPcdDict = self._CollectMacroPcd()
        if Op == 'eval':
            try:
                if Value:
                    return ValueExpression(Expression, MacroPcdDict)(True)
                else:
                    return ValueExpression(Expression, MacroPcdDict)()
            except WrnExpression as Excpt:
                #
                # Catch expression evaluation warning here. We need to report
                # the precise number of line and return the evaluation result
                #
                EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
                                File=self.FileName, ExtraData=self._CurrentLine(),
                                Line=Line)
                return Excpt.result
            except Exception as 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]),
                                      self.FileName, Line)
                    else:
                        raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),
                                      self.FileName, Line)
                else:
                    raise Warning(str(Excpt), self.FileName, Line)
        else:
            if Expression.startswith('$(') and Expression[-1] == ')':
                Expression = Expression[2:-1]
            return Expression in MacroPcdDict

    ## _IsToken() method
    #
    #   Check whether input string is found from current char position along
    #   If found, the string value is put into self._Token
    #
    #   @param  self        The object pointer
    #   @param  String      The string to search
    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
    #   @retval True        Successfully find string, file buffer pointer moved forward
    #   @retval False       Not able to find string, file buffer pointer not changed
    #
    def _IsToken(self, String, IgnoreCase = False):
        self._SkipWhiteSpace()

        # Only consider the same line, no multi-line token allowed
        StartPos = self.CurrentOffsetWithinLine
        index = -1
        if IgnoreCase:
            index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())
        else:
            index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)
        if index == 0:
            self.CurrentOffsetWithinLine += len(String)
            self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
            return True
        return False

    ## _IsKeyword() method
    #
    #   Check whether input keyword is found from current char position along, whole word only!
    #   If found, the string value is put into self._Token
    #
    #   @param  self        The object pointer
    #   @param  Keyword     The string to search
    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
    #   @retval True        Successfully find string, file buffer pointer moved forward
    #   @retval False       Not able to find string, file buffer pointer not changed
    #
    def _IsKeyword(self, KeyWord, IgnoreCase = False):
        self._SkipWhiteSpace()

        # Only consider the same line, no multi-line token allowed
        StartPos = self.CurrentOffsetWithinLine
        index = -1
        if IgnoreCase:
            index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(KeyWord.upper())
        else:
            index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(KeyWord)
        if index == 0:
            followingChar = self._CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
            if not str(followingChar).isspace() and followingChar not in SEPARATORS:
                return False
            self.CurrentOffsetWithinLine += len(KeyWord)
            self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
            return True
        return False

    def _GetExpression(self):
        Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
        Index = len(Line) - 1
        while Line[Index] in CR_LB_SET:
            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
    #   If found, the string value is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a C name string, file buffer pointer moved forward
    #   @retval False       Not able to find a C name string, file buffer pointer not changed
    #
    def _GetNextWord(self):
        self._SkipWhiteSpace()
        if self._EndOfFile():
            return False

        TempChar = self._CurrentChar()
        StartPos = self.CurrentOffsetWithinLine
        if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
            self._GetOneChar()
            while not self._EndOfLine():
                TempChar = self._CurrentChar()
                if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
                or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
                    self._GetOneChar()

                else:
                    break

            self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
            return True

        return False

    def _GetNextPcdWord(self):
        self._SkipWhiteSpace()
        if self._EndOfFile():
            return False

        TempChar = self._CurrentChar()
        StartPos = self.CurrentOffsetWithinLine
        if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END:
            self._GetOneChar()
            while not self._EndOfLine():
                TempChar = self._CurrentChar()
                if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
                or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END:
                    self._GetOneChar()

                else:
                    break

            self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
            return True

        return False

    ## _GetNextToken() method
    #
    #   Get next token unit before a separator
    #   If found, the string value is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a token unit, file buffer pointer moved forward
    #   @retval False       Not able to find a token unit, file buffer pointer not changed
    #
    def _GetNextToken(self):
        # Skip leading spaces, if exist.
        self._SkipWhiteSpace()
        if self._EndOfFile():
            return False
        # Record the token start position, the position of the first non-space char.
        StartPos = self.CurrentOffsetWithinLine
        StartLine = self.CurrentLineNumber
        while StartLine == self.CurrentLineNumber:
            TempChar = self._CurrentChar()
            # Try to find the end char that is not a space and not in separator tuple.
            # 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 TempChar not in SEPARATORS:
                self._GetOneChar()
            # if we happen to meet a separator as the first char, we must proceed to get it.
            # That is, we get a token that is a separator char. normally it is the boundary of other tokens.
            elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:
                self._GetOneChar()
                break
            else:
                break
#        else:
#            return False

        EndPos = self.CurrentOffsetWithinLine
        if self.CurrentLineNumber != StartLine:
            EndPos = len(self.Profile.FileLinesList[StartLine-1])
        self._Token = self.Profile.FileLinesList[StartLine-1][StartPos: EndPos]
        if self._Token.lower() in {TAB_IF, TAB_END_IF, TAB_ELSE_IF, TAB_ELSE, TAB_IF_DEF, TAB_IF_N_DEF, TAB_ERROR, TAB_INCLUDE}:
            self._Token = self._Token.lower()
        if StartPos != self.CurrentOffsetWithinLine:
            return True
        else:
            return False

    ## _GetNextGuid() method
    #
    #   Get next token unit before a separator
    #   If found, the GUID string is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a registry format GUID, file buffer pointer moved forward
    #   @retval False       Not able to find a registry format GUID, file buffer pointer not changed
    #
    def _GetNextGuid(self):
        if not self._GetNextToken():
            return False
        if GlobalData.gGuidPattern.match(self._Token) is not None:
            return True
        elif self._Token in GlobalData.gGuidDict:
            return True
        else:
            self._UndoToken()
            return False

    @staticmethod
    def _Verify(Name, Value, Scope):
        # value verification only applies to numeric values.
        if Scope not in TAB_PCD_NUMERIC_TYPES:
            return

        ValueNumber = 0
        try:
            ValueNumber = int(Value, 0)
        except:
            EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)
        if ValueNumber < 0:
            EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)
        if ValueNumber > MAX_VAL_TYPE[Scope]:
            EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)
        return True

    ## _UndoToken() method
    #
    #   Go back one token unit in file buffer
    #
    #   @param  self        The object pointer
    #
    def _UndoToken(self):
        self._UndoOneChar()
        while self._CurrentChar().isspace():
            if not self._UndoOneChar():
                self._GetOneChar()
                return


        StartPos = self.CurrentOffsetWithinLine
        CurrentLine = self.CurrentLineNumber
        while CurrentLine == self.CurrentLineNumber:

            TempChar = self._CurrentChar()
            # Try to find the end char that is not a space and not in separator tuple.
            # 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 SEPARATORS:
                if not self._UndoOneChar():
                    return
            # if we happen to meet a separator as the first char, we must proceed to get it.
            # That is, we get a token that is a separator char. normally it is the boundary of other tokens.
            elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:
                return
            else:
                break

        self._GetOneChar()

    ## _GetNextHexNumber() method
    #
    #   Get next HEX data before a separator
    #   If found, the HEX data is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a HEX data, file buffer pointer moved forward
    #   @retval False       Not able to find a HEX data, file buffer pointer not changed
    #
    def _GetNextHexNumber(self):
        if not self._GetNextToken():
            return False
        if GlobalData.gHexPatternAll.match(self._Token):
            return True
        else:
            self._UndoToken()
            return False

    ## _GetNextDecimalNumber() method
    #
    #   Get next decimal data before a separator
    #   If found, the decimal data is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a decimal data, file buffer pointer moved forward
    #   @retval False       Not able to find a decimal data, file buffer pointer not changed
    #
    def _GetNextDecimalNumber(self):
        if not self._GetNextToken():
            return False
        if self._Token.isdigit():
            return True
        else:
            self._UndoToken()
            return False

    def _GetNextPcdSettings(self):
        if not self._GetNextWord():
            raise Warning.Expected("<PcdTokenSpaceCName>", self.FileName, self.CurrentLineNumber)
        pcdTokenSpaceCName = self._Token

        if not self._IsToken(TAB_SPLIT):
            raise Warning.Expected(".", self.FileName, self.CurrentLineNumber)

        if not self._GetNextWord():
            raise Warning.Expected("<PcdCName>", self.FileName, self.CurrentLineNumber)
        pcdCName = self._Token

        Fields = []
        while self._IsToken(TAB_SPLIT):
            if not self._GetNextPcdWord():
                raise Warning.Expected("Pcd Fields", self.FileName, self.CurrentLineNumber)
            Fields.append(self._Token)

        return (pcdCName, pcdTokenSpaceCName,TAB_SPLIT.join(Fields))

    ## _GetStringData() method
    #
    #   Get string contents quoted in ""
    #   If found, the decimal data is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a string data, file buffer pointer moved forward
    #   @retval False       Not able to find a string data, file buffer pointer not changed
    #
    def _GetStringData(self):
        QuoteToUse = None
        if self._Token.startswith(T_CHAR_DOUBLE_QUOTE) or self._Token.startswith("L\""):
            QuoteToUse = T_CHAR_DOUBLE_QUOTE
        elif self._Token.startswith(T_CHAR_SINGLE_QUOTE) or self._Token.startswith("L\'"):
            QuoteToUse = T_CHAR_SINGLE_QUOTE
        else:
            return False

        self._UndoToken()
        self._SkipToToken(QuoteToUse)
        currentLineNumber = self.CurrentLineNumber

        if not self._SkipToToken(QuoteToUse):
            raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)
        if currentLineNumber != self.CurrentLineNumber:
            raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)
        self._Token = self._SkippedChars.rstrip(QuoteToUse)
        return True

    ## _SkipToToken() method
    #
    #   Search forward in file buffer for the string
    #   The skipped chars are put into self._SkippedChars
    #
    #   @param  self        The object pointer
    #   @param  String      The string to search
    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
    #   @retval True        Successfully find the string, file buffer pointer moved forward
    #   @retval False       Not able to find the string, file buffer pointer not changed
    #
    def _SkipToToken(self, String, IgnoreCase = False):
        StartPos = self.GetFileBufferPos()

        self._SkippedChars = ""
        while not self._EndOfFile():
            index = -1
            if IgnoreCase:
                index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())
            else:
                index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)
            if index == 0:
                self.CurrentOffsetWithinLine += len(String)
                self._SkippedChars += String
                return True
            self._SkippedChars += str(self._CurrentChar())
            self._GetOneChar()

        self.SetFileBufferPos(StartPos)
        self._SkippedChars = ""
        return False

    ## GetFileBufferPos() method
    #
    #   Return the tuple of current line and offset within the line
    #
    #   @param  self        The object pointer
    #   @retval Tuple       Line number and offset pair
    #
    def GetFileBufferPos(self):
        return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)

    ## SetFileBufferPos() method
    #
    #   Restore the file buffer position
    #
    #   @param  self        The object pointer
    #   @param  Pos         The new file buffer position
    #
    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
    #   Exception will be raised if syntax error found
    #
    #   @param  self        The object pointer
    #
    def ParseFile(self):
        try:
            self.Preprocess()
            self._GetError()
            #
            # Keep processing sections of the FDF until no new sections or a syntax error is found
            #
            while self._GetFd() or self._GetFv() or self._GetFmp() or self._GetCapsule() or self._GetRule() or self._GetOptionRom():
                pass

        except Warning as X:
            self._UndoToken()
            #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
            # At this point, the closest parent would be the included file itself
            Profile = GetParentAtLine(X.OriginalLineNumber)
            if Profile is not None:
                X.Message += ' near line %d, column %d: %s' \
                % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])
            else:
                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                X.Message += ' near line %d, column %d: %s' \
                % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:].rstrip(TAB_LINE_BREAK).rstrip(T_CHAR_CR))
            raise

    ## SectionParser() method
    #
    #   Parse the file section info
    #   Exception will be raised if syntax error found
    #
    #   @param  self          The object pointer
    #   @param  section       The section string

    def SectionParser(self, section):
        S = section.upper()
        if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
             and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):
            raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber)

    ## _GetDefines() method
    #
    #   Get Defines section contents and store its data into AllMacrosList
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a Defines
    #   @retval False       Not able to find a Defines
    #
    def _GetDefines(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[DEFINES"):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[DEFINES", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning.Expected("[DEFINES", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        while self._GetNextWord():
            # handle the SET statement
            if self._Token == 'SET':
                self._UndoToken()
                self._GetSetStatement(None)
                continue

            Macro = self._Token

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken() or self._Token.startswith(TAB_SECTION_START):
                raise Warning.Expected("MACRO value", self.FileName, self.CurrentLineNumber)
            Value = self._Token

        return False

    ##_GetError() method
    def _GetError(self):
        #save the Current information
        CurrentLine = self.CurrentLineNumber
        CurrentOffset = self.CurrentOffsetWithinLine
        while self._GetNextToken():
            if self._Token == TAB_ERROR:
                EdkLogger.error('FdfParser', ERROR_STATEMENT, self._CurrentLine().replace(TAB_ERROR, '', 1), File=self.FileName, Line=self.CurrentLineNumber)
        self.CurrentLineNumber = CurrentLine
        self.CurrentOffsetWithinLine = CurrentOffset

    ## _GetFd() method
    #
    #   Get FD section contents and store its data into FD dictionary of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a FD
    #   @retval False       Not able to find a FD
    #
    def _GetFd(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[FD."):
            if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
                and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
                raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[FD.", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning.Expected("[FD.]", self.FileName, self.CurrentLineNumber)

        FdName = self._GetUiName()
        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)
        self.CurrentFdName = FdName.upper()

        if self.CurrentFdName in self.Profile.FdDict:
            raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        FdObj = FD()
        FdObj.FdUiName = self.CurrentFdName
        self.Profile.FdDict[self.CurrentFdName] = FdObj

        if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:
            raise Warning.Expected("all FDs have their name", self.FileName, self.CurrentLineNumber)

        Status = self._GetCreateFile(FdObj)
        if not Status:
            raise Warning("FD name error", self.FileName, self.CurrentLineNumber)

        while self._GetTokenStatements(FdObj):
            pass
        for Attr in ("BaseAddress", "Size", "ErasePolarity"):
            if getattr(FdObj, Attr) is 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)

        self._GetSetStatements(FdObj)

        if not self._GetRegionLayout(FdObj):
            raise Warning.Expected("region layout", self.FileName, self.CurrentLineNumber)

        while self._GetRegionLayout(FdObj):
            pass
        return True

    ## _GetUiName() method
    #
    #   Return the UI name of a section
    #
    #   @param  self        The object pointer
    #   @retval FdName      UI name
    #
    def _GetUiName(self):
        Name = ""
        if self._GetNextWord():
            Name = self._Token

        return Name

    ## _GetCreateFile() method
    #
    #   Return the output file name of object
    #
    #   @param  self        The object pointer
    #   @param  Obj         object whose data will be stored in file
    #   @retval FdName      UI name
    #
    def _GetCreateFile(self, Obj):
        if self._IsKeyword("CREATE_FILE"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)

            FileName = self._Token
            Obj.CreateFileName = FileName

        return True

    def SetPcdLocalation(self,pcdpair):
        self.Profile.PcdLocalDict[pcdpair] = (self.Profile.FileName,self.CurrentLineNumber)

    ## _GetTokenStatements() method
    #
    #   Get token statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom token statement is got
    #
    def _GetTokenStatements(self, Obj):
        if self._IsKeyword("BaseAddress"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(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(TAB_VALUE_SPLIT):
                pcdPair = self._GetNextPcdSettings()
                Obj.BaseAddressPcd = pcdPair
                self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
                self.SetPcdLocalation(pcdPair)
                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
            return True

        if self._IsKeyword("Size"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextHexNumber():
                raise Warning.Expected("Hex size", self.FileName, self.CurrentLineNumber)

            Size = self._Token
            if self._IsToken(TAB_VALUE_SPLIT):
                pcdPair = self._GetNextPcdSettings()
                Obj.SizePcd = pcdPair
                self.Profile.PcdDict[pcdPair] = Size
                self.SetPcdLocalation(pcdPair)
                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
            Obj.Size = int(Size, 0)
            return True

        if self._IsKeyword("ErasePolarity"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("Erase Polarity", self.FileName, self.CurrentLineNumber)

            if not self._Token in {"1", "0"}:
                raise Warning.Expected("1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)

            Obj.ErasePolarity = self._Token
            return True

        return self._GetBlockStatements(Obj)

    ## _GetAddressStatements() method
    #
    #   Get address statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom address statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetAddressStatements(self, Obj):
        if self._IsKeyword("BsBaseAddress"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
                raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)

            BsAddress = int(self._Token, 0)
            Obj.BsBaseAddress = BsAddress

        if self._IsKeyword("RtBaseAddress"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
                raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)

            RtAddress = int(self._Token, 0)
            Obj.RtBaseAddress = RtAddress

    ## _GetBlockStatements() method
    #
    #   Get block statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom block statement is got
    #
    def _GetBlockStatements(self, Obj):
        IsBlock = False
        while self._GetBlockStatement(Obj):
            IsBlock = True

            Item = Obj.BlockSizeList[-1]
            if Item[0] is None or Item[1] is None:
                raise Warning.Expected("block statement", self.FileName, self.CurrentLineNumber)
        return IsBlock

    ## _GetBlockStatement() method
    #
    #   Get block statement
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom block statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetBlockStatement(self, Obj):
        if not self._IsKeyword("BlockSize"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():
            raise Warning.Expected("Hex or Integer block size", self.FileName, self.CurrentLineNumber)

        BlockSize = self._Token
        BlockSizePcd = None
        if self._IsToken(TAB_VALUE_SPLIT):
            PcdPair = self._GetNextPcdSettings()
            BlockSizePcd = PcdPair
            self.Profile.PcdDict[PcdPair] = BlockSize
            self.SetPcdLocalation(PcdPair)
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
        BlockSize = int(BlockSize, 0)

        BlockNumber = None
        if self._IsKeyword("NumBlocks"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
                raise Warning.Expected("block numbers", self.FileName, self.CurrentLineNumber)

            BlockNumber = int(self._Token, 0)

        Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
        return True

    ## _GetDefineStatements() method
    #
    #   Get define statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom define statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetDefineStatements(self, Obj):
        while self._GetDefineStatement(Obj):
            pass

    ## _GetDefineStatement() method
    #
    #   Get define statement
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom define statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetDefineStatement(self, Obj):
        if self._IsKeyword(TAB_DEFINE):
            self._GetNextToken()
            Macro = self._Token
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)

            Value = self._Token
            Macro = '$(' + Macro + ')'
            Obj.DefineVarDict[Macro] = Value
            return True

        return False

    ## _GetSetStatements() method
    #
    #   Get set statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom set statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetSetStatements(self, Obj):
        while self._GetSetStatement(Obj):
            pass

    ## _GetSetStatement() method
    #
    #   Get set statement
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom set statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetSetStatement(self, Obj):
        if self._IsKeyword("SET"):
            PcdPair = self._GetNextPcdSettings()

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            Value = self._GetExpression()
            Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)

            if Obj:
                Obj.SetVarDict[PcdPair] = Value
            self.Profile.PcdDict[PcdPair] = Value
            self.SetPcdLocalation(PcdPair)
            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 int(
                ValueExpression(Expr,
                                self._CollectMacroPcd()
                                )(True), 0)
        except Exception:
            self.SetFileBufferPos(StartPos)
            return None

    ## _GetRegionLayout() method
    #
    #   Get region layout for FD
    #
    #   @param  self        The object pointer
    #   @param  theFd       for whom region is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetRegionLayout(self, theFd):
        Offset = self._CalcRegionExpr()
        if Offset is None:
            return False

        RegionObj = Region()
        RegionObj.Offset = Offset
        theFd.RegionList.append(RegionObj)

        if not self._IsToken(TAB_VALUE_SPLIT):
            raise Warning.Expected("'|'", self.FileName, self.CurrentLineNumber)

        Size = self._CalcRegionExpr()
        if Size is None:
            raise Warning.Expected("Region Size", self.FileName, self.CurrentLineNumber)
        RegionObj.Size = Size

        if not self._GetNextWord():
            return True

        if not self._Token in {"SET", BINARY_FILE_TYPE_FV, "FILE", "DATA", "CAPSULE", "INF"}:
            #
            # 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()
            IsRegionPcd = (RegionSizeGuidPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]) or
                           RegionOffsetPcdPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]))
            if IsRegionPcd:
                RegionObj.PcdOffset = self._GetNextPcdSettings()
                self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + int(theFd.BaseAddress, 0))
                self.SetPcdLocalation(RegionObj.PcdOffset)
                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(TAB_VALUE_SPLIT):
                    RegionObj.PcdSize = self._GetNextPcdSettings()
                    self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
                    self.SetPcdLocalation(RegionObj.PcdSize)
                    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

        if self._Token == "SET":
            self._UndoToken()
            self._GetSetStatements(RegionObj)
            if not self._GetNextWord():
                return True

        elif self._Token == BINARY_FILE_TYPE_FV:
            self._UndoToken()
            self._GetRegionFvType(RegionObj)

        elif self._Token == "CAPSULE":
            self._UndoToken()
            self._GetRegionCapType(RegionObj)

        elif self._Token == "FILE":
            self._UndoToken()
            self._GetRegionFileType(RegionObj)

        elif self._Token == "INF":
            self._UndoToken()
            RegionObj.RegionType = "INF"
            while self._IsKeyword("INF"):
                self._UndoToken()
                ffsInf = self._ParseInfStatement()
                if not ffsInf:
                    break
                RegionObj.RegionDataList.append(ffsInf)

        elif self._Token == "DATA":
            self._UndoToken()
            self._GetRegionDataType(RegionObj)
        else:
            self._UndoToken()
            if self._GetRegionLayout(theFd):
                return True
            raise Warning("A valid region type was not found. "
                          "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
                          self.FileName, self.CurrentLineNumber)

        return True

    ## _GetRegionFvType() method
    #
    #   Get region fv data for region
    #
    #   @param  self        The object pointer
    #   @param  RegionObj   for whom region data is got
    #
    def _GetRegionFvType(self, RegionObj):
        if not self._IsKeyword(BINARY_FILE_TYPE_FV):
            raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)

        RegionObj.RegionType = BINARY_FILE_TYPE_FV
        RegionObj.RegionDataList.append((self._Token).upper())

        while self._IsKeyword(BINARY_FILE_TYPE_FV):

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)

            RegionObj.RegionDataList.append((self._Token).upper())

    ## _GetRegionCapType() method
    #
    #   Get region capsule data for region
    #
    #   @param  self        The object pointer
    #   @param  RegionObj   for whom region data is got
    #
    def _GetRegionCapType(self, RegionObj):
        if not self._IsKeyword("CAPSULE"):
            raise Warning.Expected("'CAPSULE'", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)

        RegionObj.RegionType = "CAPSULE"
        RegionObj.RegionDataList.append(self._Token)

        while self._IsKeyword("CAPSULE"):

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)

            RegionObj.RegionDataList.append(self._Token)

    ## _GetRegionFileType() method
    #
    #   Get region file data for region
    #
    #   @param  self        The object pointer
    #   @param  RegionObj   for whom region data is got
    #
    def _GetRegionFileType(self, RegionObj):
        if not self._IsKeyword("FILE"):
            raise Warning.Expected("'FILE'", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)

        RegionObj.RegionType = "FILE"
        RegionObj.RegionDataList.append(self._Token)

        while self._IsKeyword("FILE"):

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("FILE name", self.FileName, self.CurrentLineNumber)

            RegionObj.RegionDataList.append(self._Token)

    ## _GetRegionDataType() method
    #
    #   Get region array data for region
    #
    #   @param  self        The object pointer
    #   @param  RegionObj   for whom region data is got
    #
    def _GetRegionDataType(self, RegionObj):
        if not self._IsKeyword("DATA"):
            raise Warning.Expected("Region Data type", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._IsToken("{"):
            raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

        if not self._GetNextHexNumber():
            raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)

        if len(self._Token) > 18:
            raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)

        # convert hex string value to byte hex string array
        AllString = self._Token
        AllStrLen = len (AllString)
        DataString = ""
        while AllStrLen > 4:
            DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT
            AllStrLen  = AllStrLen - 2
        DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT

        # byte value array
        if len (self._Token) <= 4:
            while self._IsToken(TAB_COMMA_SPLIT):
                if not self._GetNextHexNumber():
                    raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
                if len(self._Token) > 4:
                    raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
                DataString += self._Token
                DataString += TAB_COMMA_SPLIT

        if not self._IsToken(T_CHAR_BRACE_R):
            raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

        DataString = DataString.rstrip(TAB_COMMA_SPLIT)
        RegionObj.RegionType = "DATA"
        RegionObj.RegionDataList.append(DataString)

        while self._IsKeyword("DATA"):

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

            if not self._GetNextHexNumber():
                raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)

            if len(self._Token) > 18:
                raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)

            # convert hex string value to byte hex string array
            AllString = self._Token
            AllStrLen = len (AllString)
            DataString = ""
            while AllStrLen > 4:
                DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT
                AllStrLen  = AllStrLen - 2
            DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT

            # byte value array
            if len (self._Token) <= 4:
                while self._IsToken(TAB_COMMA_SPLIT):
                    if not self._GetNextHexNumber():
                        raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
                    if len(self._Token) > 4:
                        raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
                    DataString += self._Token
                    DataString += TAB_COMMA_SPLIT

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            DataString = DataString.rstrip(TAB_COMMA_SPLIT)
            RegionObj.RegionDataList.append(DataString)

    ## _GetFv() method
    #
    #   Get FV section contents and store its data into FV dictionary of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a FV
    #   @retval False       Not able to find a FV
    #
    def _GetFv(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[FV."):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[FV.", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        FvName = self._GetUiName()
        self.CurrentFvName = FvName.upper()

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        FvObj = FV(Name=self.CurrentFvName)
        self.Profile.FvDict[self.CurrentFvName] = FvObj

        Status = self._GetCreateFile(FvObj)
        if not Status:
            raise Warning("FV name error", self.FileName, self.CurrentLineNumber)

        self._GetDefineStatements(FvObj)

        self._GetAddressStatements(FvObj)

        while True:
            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) or self._GetFvNameString(FvObj)):
                break

        if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:
            raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)

        self._GetAprioriSection(FvObj)
        self._GetAprioriSection(FvObj)

        while True:
            isInf = self._GetInfStatement(FvObj)
            isFile = self._GetFileStatement(FvObj)
            if not isInf and not isFile:
                break

        return True

    ## _GetFvAlignment() method
    #
    #   Get alignment for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom alignment is got
    #   @retval True        Successfully find a alignment statement
    #   @retval False       Not able to find a alignment statement
    #
    def _GetFvAlignment(self, Obj):
        if not self._IsKeyword("FvAlignment"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)

        if self._Token.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
                                        "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
                                        "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
                                        "1G", "2G"}:
            raise Warning("Unknown alignment value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
        Obj.FvAlignment = self._Token
        return True

    ## _GetFvBaseAddress() method
    #
    #   Get BaseAddress for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom FvBaseAddress is got
    #   @retval True        Successfully find a FvBaseAddress statement
    #   @retval False       Not able to find a FvBaseAddress statement
    #
    def _GetFvBaseAddress(self, Obj):
        if not self._IsKeyword("FvBaseAddress"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FV base address value", self.FileName, self.CurrentLineNumber)

        if not BaseAddrValuePattern.match(self._Token.upper()):
            raise Warning("Unknown FV base address value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
        Obj.FvBaseAddress = self._Token
        return True

    ## _GetFvForceRebase() method
    #
    #   Get FvForceRebase for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom FvForceRebase is got
    #   @retval True        Successfully find a FvForceRebase statement
    #   @retval False       Not able to find a FvForceRebase statement
    #
    def _GetFvForceRebase(self, Obj):
        if not self._IsKeyword("FvForceRebase"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FvForceRebase value", self.FileName, self.CurrentLineNumber)

        if self._Token.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
            raise Warning("Unknown FvForceRebase value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        if self._Token.upper() in {"TRUE", "1", "0X1", "0X01"}:
            Obj.FvForceRebase = True
        elif self._Token.upper() in {"FALSE", "0", "0X0", "0X00"}:
            Obj.FvForceRebase = False
        else:
            Obj.FvForceRebase = None

        return True


    ## _GetFvAttributes() method
    #
    #   Get attributes for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom attribute is got
    #   @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", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
                self._UndoToken()
                return False

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(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)

            FvObj.FvAttributeDict[name] = self._Token

        return IsWordToken

    ## _GetFvNameGuid() method
    #
    #   Get FV GUID for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom GUID is got
    #   @retval None
    #
    def _GetFvNameGuid(self, FvObj):
        if not self._IsKeyword("FvNameGuid"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextGuid():
            raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)
        if self._Token in GlobalData.gGuidDict:
            self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()

        FvObj.FvNameGuid = self._Token

        return True

    def _GetFvNameString(self, FvObj):
        if not self._IsKeyword("FvNameString"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken() or self._Token.upper() not in {'TRUE', 'FALSE'}:
            raise Warning.Expected("TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)

        FvObj.FvNameString = self._Token

        return True

    def _GetFvExtEntryStatement(self, FvObj):
        if not (self._IsKeyword("FV_EXT_ENTRY") or self._IsKeyword("FV_EXT_ENTRY_TYPE")):
            return False

        if not self._IsKeyword ("TYPE"):
            raise Warning.Expected("'TYPE'", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():
            raise Warning.Expected("Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)

        FvObj.FvExtEntryTypeValue.append(self._Token)

        if not self._IsToken("{"):
            raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

        if not self._IsKeyword("FILE") and not self._IsKeyword("DATA"):
            raise Warning.Expected("'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)

        FvObj.FvExtEntryType.append(self._Token)

        if self._Token == 'DATA':
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

            if not self._GetNextHexNumber():
                raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)

            if len(self._Token) > 4:
                raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)

            DataString = self._Token
            DataString += TAB_COMMA_SPLIT

            while self._IsToken(TAB_COMMA_SPLIT):
                if not self._GetNextHexNumber():
                    raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
                if len(self._Token) > 4:
                    raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
                DataString += self._Token
                DataString += TAB_COMMA_SPLIT

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            DataString = DataString.rstrip(TAB_COMMA_SPLIT)
            FvObj.FvExtEntryData.append(DataString)

        if self._Token == 'FILE':
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)

            FvObj.FvExtEntryData.append(self._Token)

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

        return True

    ## _GetAprioriSection() method
    #
    #   Get token statements
    #
    #   @param  self        The object pointer
    #   @param  FvObj       for whom apriori is got
    #   @retval True        Successfully find apriori statement
    #   @retval False       Not able to find apriori statement
    #
    def _GetAprioriSection(self, FvObj):
        if not self._IsKeyword("APRIORI"):
            return False

        if not self._IsKeyword("PEI") and not self._IsKeyword("DXE"):
            raise Warning.Expected("Apriori file type", self.FileName, self.CurrentLineNumber)
        AprType = self._Token

        if not self._IsToken("{"):
            raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

        AprSectionObj = AprioriSection()
        AprSectionObj.AprioriType = AprType

        self._GetDefineStatements(AprSectionObj)

        while True:
            IsInf = self._GetInfStatement(AprSectionObj)
            IsFile = self._GetFileStatement(AprSectionObj)
            if not IsInf and not IsFile:
                break

        if not self._IsToken(T_CHAR_BRACE_R):
            raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

        FvObj.AprioriSectionList.append(AprSectionObj)
        return True

    def _ParseInfStatement(self):
        if not self._IsKeyword("INF"):
            return None

        ffsInf = FfsInfStatement()
        self._GetInfOptions(ffsInf)

        if not self._GetNextToken():
            raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)
        ffsInf.InfFileName = self._Token
        if not ffsInf.InfFileName.endswith('.inf'):
            raise Warning.Expected(".inf file path", self.FileName, self.CurrentLineNumber)

        ffsInf.CurrentLineNum = self.CurrentLineNumber
        ffsInf.CurrentLineContent = self._CurrentLine()

        #Replace $(SAPCE) with real space
        ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')

        if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:
            #do case sensitive check for file path
            ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
            if ErrorCode != 0:
                EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)

        NewFileName = ffsInf.InfFileName
        if ffsInf.OverrideGuid:
            NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path

        if not NewFileName in self.Profile.InfList:
            self.Profile.InfList.append(NewFileName)
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            self.Profile.InfFileLineList.append(FileLineTuple)
            if ffsInf.UseArch:
                if ffsInf.UseArch not in self.Profile.InfDict:
                    self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
                else:
                    self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
            else:
                self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)

        if self._IsToken(TAB_VALUE_SPLIT):
            if self._IsKeyword('RELOCS_STRIPPED'):
                ffsInf.KeepReloc = False
            elif self._IsKeyword('RELOCS_RETAINED'):
                ffsInf.KeepReloc = True
            else:
                raise Warning("Unknown reloc strip flag '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
        return ffsInf

    ## _GetInfStatement() method
    #
    #   Get INF statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom inf statement is got
    #   @retval True        Successfully find inf statement
    #   @retval False       Not able to find inf statement
    #
    def _GetInfStatement(self, Obj, ForCapsule=False):
        ffsInf = self._ParseInfStatement()
        if not ffsInf:
            return False

        if ForCapsule:
            myCapsuleFfs = CapsuleFfs()
            myCapsuleFfs.Ffs = ffsInf
            Obj.CapsuleDataList.append(myCapsuleFfs)
        else:
            Obj.FfsList.append(ffsInf)
        return True

    ## _GetInfOptions() method
    #
    #   Get options for INF
    #
    #   @param  self        The object pointer
    #   @param  FfsInfObj   for whom option is got
    #
    def _GetInfOptions(self, FfsInfObj):
        if self._IsKeyword("FILE_GUID"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextGuid():
                raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)
            if self._Token in GlobalData.gGuidDict:
                self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
            FfsInfObj.OverrideGuid = self._Token

        if self._IsKeyword("RuleOverride"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("Rule name", self.FileName, self.CurrentLineNumber)
            FfsInfObj.Rule = self._Token

        if self._IsKeyword("VERSION"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("Version", self.FileName, self.CurrentLineNumber)

            if self._GetStringData():
                FfsInfObj.Version = self._Token

        if self._IsKeyword(BINARY_FILE_TYPE_UI):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("UI name", self.FileName, self.CurrentLineNumber)

            if self._GetStringData():
                FfsInfObj.Ui = self._Token

        if self._IsKeyword("USE"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber)
            FfsInfObj.UseArch = self._Token


        if self._GetNextToken():
            p = 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(TAB_COMMA_SPLIT):
                    return
            else:
                self._UndoToken()
                return

            while self._GetNextToken():
                if not p.match(self._Token):
                    raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
                FfsInfObj.KeyStringList.append(self._Token)

                if not self._IsToken(TAB_COMMA_SPLIT):
                    break

    ## _GetFileStatement() method
    #
    #   Get FILE statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom FILE statement is got
    #   @retval True        Successfully find FILE statement
    #   @retval False       Not able to find FILE statement
    #
    def _GetFileStatement(self, Obj, ForCapsule = False):
        if not self._IsKeyword("FILE"):
            return False

        if not self._GetNextWord():
            raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)

        if ForCapsule and self._Token == 'DATA':
            self._UndoToken()
            self._UndoToken()
            return False

        FfsFileObj = FileStatement()
        FfsFileObj.FvFileType = self._Token

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextGuid():
            if not self._GetNextWord():
                raise Warning.Expected("File GUID", self.FileName, self.CurrentLineNumber)
            if self._Token == 'PCD':
                if not self._IsToken("("):
                    raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
                PcdPair = self._GetNextPcdSettings()
                if not self._IsToken(")"):
                    raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
                self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'

        if self._Token in GlobalData.gGuidDict:
            self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
        FfsFileObj.NameGuid = self._Token

        self._GetFilePart(FfsFileObj)

        if ForCapsule:
            capsuleFfs = CapsuleFfs()
            capsuleFfs.Ffs = FfsFileObj
            Obj.CapsuleDataList.append(capsuleFfs)
        else:
            Obj.FfsList.append(FfsFileObj)

        return True

    ## _FileCouldHaveRelocFlag() method
    #
    #   Check whether reloc strip flag can be set for a file type.
    #
    #   @param  FileType    The file type to check with
    #   @retval True        This type could have relocation strip flag
    #   @retval False       No way to have it
    #
    @staticmethod
    def _FileCouldHaveRelocFlag (FileType):
        if FileType in {SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE, 'PEI_DXE_COMBO'}:
            return True
        else:
            return False

    ## _SectionCouldHaveRelocFlag() method
    #
    #   Check whether reloc strip flag can be set for a section type.
    #
    #   @param  SectionType The section type to check with
    #   @retval True        This type could have relocation strip flag
    #   @retval False       No way to have it
    #
    @staticmethod
    def _SectionCouldHaveRelocFlag (SectionType):
        if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}:
            return True
        else:
            return False

    ## _GetFilePart() method
    #
    #   Get components for FILE statement
    #
    #   @param  self        The object pointer
    #   @param  FfsFileObj   for whom component is got
    #
    def _GetFilePart(self, FfsFileObj):
        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("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("File name or section data", self.FileName, self.CurrentLineNumber)

        if self._Token == BINARY_FILE_TYPE_FV:
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)
            FfsFileObj.FvName = self._Token

        elif self._Token == "FD":
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)
            FfsFileObj.FdName = self._Token

        elif self._Token in {TAB_DEFINE, "APRIORI", "SECTION"}:
            self._UndoToken()
            self._GetSectionData(FfsFileObj)

        elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':
            self._UndoToken()
            self._GetRAWData(FfsFileObj)

        else:
            FfsFileObj.CurrentLineNum = self.CurrentLineNumber
            FfsFileObj.CurrentLineContent = self._CurrentLine()
            FfsFileObj.FileName = self._Token.replace('$(SPACE)', ' ')
            self._VerifyFile(FfsFileObj.FileName)

        if not self._IsToken(T_CHAR_BRACE_R):
            raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

    ## _GetRAWData() method
    #
    #   Get RAW data for FILE statement
    #
    #   @param  self         The object pointer
    #   @param  FfsFileObj   for whom section is got
    #
    def _GetRAWData(self, FfsFileObj):
        FfsFileObj.FileName = []
        FfsFileObj.SubAlignment = []
        while True:
            AlignValue = None
            if self._GetAlignment():
                if self._Token not in ALIGNMENTS:
                    raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
                #For FFS, Auto is default option same to ""
                if not self._Token == "Auto":
                    AlignValue = self._Token
            if not self._GetNextToken():
                raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)

            FileName = self._Token.replace('$(SPACE)', ' ')
            if FileName == T_CHAR_BRACE_R:
                self._UndoToken()
                raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)

            self._VerifyFile(FileName)
            File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)
            FfsFileObj.FileName.append(File.Path)
            FfsFileObj.SubAlignment.append(AlignValue)

            if self._IsToken(T_CHAR_BRACE_R):
                self._UndoToken()
                break

        if len(FfsFileObj.SubAlignment) == 1:
            FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]
        if len(FfsFileObj.FileName) == 1:
            FfsFileObj.FileName = FfsFileObj.FileName[0]

    ## _GetFileOpts() method
    #
    #   Get options for FILE statement
    #
    #   @param  self        The object pointer
    #   @param  FfsFileObj   for whom options is got
    #
    def _GetFileOpts(self, FfsFileObj):
        if self._GetNextToken():
            if TokenFindPattern.match(self._Token):
                FfsFileObj.KeyStringList.append(self._Token)
                if self._IsToken(TAB_COMMA_SPLIT):
                    while self._GetNextToken():
                        if not TokenFindPattern.match(self._Token):
                            raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
                        FfsFileObj.KeyStringList.append(self._Token)

                        if not self._IsToken(TAB_COMMA_SPLIT):
                            break

            else:
                self._UndoToken()

        if self._IsKeyword("FIXED", True):
            FfsFileObj.Fixed = True

        if self._IsKeyword("CHECKSUM", True):
            FfsFileObj.CheckSum = True

        if self._GetAlignment():
            if self._Token not in ALIGNMENTS:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            #For FFS, Auto is default option same to ""
            if not self._Token == "Auto":
                FfsFileObj.Alignment = self._Token

    ## _GetAlignment() method
    #
    #   Return the alignment value
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find alignment
    #   @retval False       Not able to find alignment
    #
    def _GetAlignment(self):
        if self._IsKeyword("Align", True):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)
            return True

        return False

    ## _GetSectionData() method
    #
    #   Get section data for FILE statement
    #
    #   @param  self        The object pointer
    #   @param  FfsFileObj   for whom section is got
    #
    def _GetSectionData(self, FfsFileObj):
        self._GetDefineStatements(FfsFileObj)

        while True:
            IsLeafSection = self._GetLeafSection(FfsFileObj)
            IsEncapSection = self._GetEncapsulationSec(FfsFileObj)
            if not IsLeafSection and not IsEncapSection:
                break

    ## _GetLeafSection() method
    #
    #   Get leaf section for Obj
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom leaf section is got
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetLeafSection(self, Obj):
        OldPos = self.GetFileBufferPos()

        if not self._IsKeyword("SECTION"):
            if len(Obj.SectionList) == 0:
                raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)
            else:
                return False

        AlignValue = None
        if self._GetAlignment():
            if self._Token not in ALIGNMENTS:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            AlignValue = self._Token

        BuildNum = None
        if self._IsKeyword("BUILD_NUM"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("Build number value", self.FileName, self.CurrentLineNumber)

            BuildNum = self._Token

        if self._IsKeyword("VERSION"):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("version", self.FileName, self.CurrentLineNumber)
            VerSectionObj = VerSection()
            VerSectionObj.Alignment = AlignValue
            VerSectionObj.BuildNum = BuildNum
            if self._GetStringData():
                VerSectionObj.StringData = self._Token
            else:
                VerSectionObj.FileName = self._Token
            Obj.SectionList.append(VerSectionObj)

        elif self._IsKeyword(BINARY_FILE_TYPE_UI):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("UI", self.FileName, self.CurrentLineNumber)
            UiSectionObj = UiSection()
            UiSectionObj.Alignment = AlignValue
            if self._GetStringData():
                UiSectionObj.StringData = self._Token
            else:
                UiSectionObj.FileName = self._Token
            Obj.SectionList.append(UiSectionObj)

        elif self._IsKeyword("FV_IMAGE"):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("FV name or FV file path", self.FileName, self.CurrentLineNumber)

            FvName = self._Token
            FvObj = None

            if self._IsToken("{"):
                FvObj = FV()
                FvObj.UiFvName = FvName.upper()
                self._GetDefineStatements(FvObj)

                self._GetBlockStatement(FvObj)
                self._GetSetStatements(FvObj)
                self._GetFvAlignment(FvObj)
                self._GetFvAttributes(FvObj)

                while True:
                    IsInf = self._GetInfStatement(FvObj)
                    IsFile = self._GetFileStatement(FvObj)
                    if not IsInf and not IsFile:
                        break

                if not self._IsToken(T_CHAR_BRACE_R):
                    raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            FvImageSectionObj = FvImageSection()
            FvImageSectionObj.Alignment = AlignValue
            if FvObj is not None:
                FvImageSectionObj.Fv = FvObj
                FvImageSectionObj.FvName = None
            else:
                FvImageSectionObj.FvName = FvName.upper()
                FvImageSectionObj.FvFileName = FvName

            Obj.SectionList.append(FvImageSectionObj)

        elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            DepexSectionObj = DepexSection()
            DepexSectionObj.Alignment = AlignValue
            DepexSectionObj.DepexType = self._Token

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
            if not self._SkipToToken(T_CHAR_BRACE_R):
                raise Warning.Expected("Depex expression ending '}'", self.FileName, self.CurrentLineNumber)

            DepexSectionObj.Expression = self._SkippedChars.rstrip(T_CHAR_BRACE_R)
            Obj.SectionList.append(DepexSectionObj)

        elif self._IsKeyword("SUBTYPE_GUID"):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            SubTypeGuidValue = None
            if not self._GetNextGuid():
                raise Warning.Expected("GUID", self.FileName, self.CurrentLineNumber)
            else:
                SubTypeGuidValue = self._Token

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber)
            FileName = self._Token

            SubTypeGuidSectionObj = SubTypeGuidSection()
            SubTypeGuidSectionObj.Alignment = AlignValue
            SubTypeGuidSectionObj.SubTypeGuid = SubTypeGuidValue
            SubTypeGuidSectionObj.SectFileName = FileName
            Obj.SectionList.append(SubTypeGuidSectionObj)

        else:
            if not self._GetNextWord():
                raise Warning.Expected("section type", self.FileName, self.CurrentLineNumber)

            # Encapsulation section appear, UndoToken and return
            if self._Token == "COMPRESS" or self._Token == "GUIDED":
                self.SetFileBufferPos(OldPos)
                return False

            if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\
                               BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}:
                raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE):
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)

            # DataSection
            DataSectionObj = DataSection()
            DataSectionObj.Alignment = AlignValue
            DataSectionObj.SecType = self._Token

            if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
                if self._FileCouldHaveRelocFlag(Obj.FvFileType) and self._SectionCouldHaveRelocFlag(DataSectionObj.SecType):
                    if self._Token == 'RELOCS_STRIPPED':
                        DataSectionObj.KeepReloc = False
                    else:
                        DataSectionObj.KeepReloc = True
                else:
                    raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

            if self._IsToken(TAB_EQUAL_SPLIT):
                if not self._GetNextToken():
                    raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber)
                DataSectionObj.SectFileName = self._Token
                self._VerifyFile(DataSectionObj.SectFileName)
            else:
                if not self._GetCglSection(DataSectionObj):
                    return False

            Obj.SectionList.append(DataSectionObj)

        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(TAB_WORKSPACE, '').find('$') != -1:
            return
        if not GlobalData.gAutoGenPhase or not self._GetMacroValue(TAB_DSC_DEFINES_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
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom leaf section is got
    #   @param  AlignValue  alignment value for complex section
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetCglSection(self, Obj, AlignValue = None):

        if self._IsKeyword("COMPRESS"):
            type = "PI_STD"
            if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):
                type = self._Token

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

            CompressSectionObj = CompressSection()
            CompressSectionObj.Alignment = AlignValue
            CompressSectionObj.CompType = type
            # Recursive sections...
            while True:
                IsLeafSection = self._GetLeafSection(CompressSectionObj)
                IsEncapSection = self._GetEncapsulationSec(CompressSectionObj)
                if not IsLeafSection and not IsEncapSection:
                    break


            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
            Obj.SectionList.append(CompressSectionObj)
            return True

        elif self._IsKeyword("GUIDED"):
            GuidValue = None
            if self._GetNextGuid():
                if self._Token in GlobalData.gGuidDict:
                    self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
                GuidValue = self._Token

            AttribDict = self._GetGuidAttrib()
            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
            GuidSectionObj = GuidSection()
            GuidSectionObj.Alignment = AlignValue
            GuidSectionObj.NameGuid = GuidValue
            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)
                IsEncapSection = self._GetEncapsulationSec(GuidSectionObj)
                if not IsLeafSection and not IsEncapSection:
                    break

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
            Obj.SectionList.append(GuidSectionObj)

            return True

        return False

    ## _GetGuidAttri() method
    #
    #   Get attributes for GUID section
    #
    #   @param  self        The object pointer
    #   @retval AttribDict  Dictionary of key-value pair of section attributes
    #
    def _GetGuidAttrib(self):
        AttribDict = {}
        AttribDict["PROCESSING_REQUIRED"] = "NONE"
        AttribDict["AUTH_STATUS_VALID"] = "NONE"
        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(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            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

        return AttribDict

    ## _GetEncapsulationSec() method
    #
    #   Get encapsulation section for FILE
    #
    #   @param  self        The object pointer
    #   @param  FfsFile     for whom section is got
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetEncapsulationSec(self, FfsFileObj):
        OldPos = self.GetFileBufferPos()
        if not self._IsKeyword("SECTION"):
            if len(FfsFileObj.SectionList) == 0:
                raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)
            else:
                return False

        AlignValue = None
        if self._GetAlignment():
            if self._Token not in ALIGNMENT_NOAUTO:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            AlignValue = self._Token

        if not self._GetCglSection(FfsFileObj, AlignValue):
            self.SetFileBufferPos(OldPos)
            return False
        else:
            return True

    def _GetFmp(self):
        if not self._GetNextToken():
            return False
        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[FMPPAYLOAD."):
            self.SectionParser(S)
            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 = CapsulePayload()
        FmpData.UiName = FmpUiName

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(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', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
        while self._Token in FmpKeyList:
            Name = self._Token
            FmpKeyList.remove(Name)
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(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
            elif Name == 'CERTIFICATE_GUID':
                if not self._GetNextGuid():
                    raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
                FmpData.Certificate_Guid = self._Token
                if UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:
                    raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
            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':
                    if FdfParser._Verify(Name, Value, 'UINT8'):
                        FmpData.Version = Value
                elif Name == 'IMAGE_INDEX':
                    if FdfParser._Verify(Name, Value, 'UINT8'):
                        FmpData.ImageIndex = Value
                elif Name == 'HARDWARE_INSTANCE':
                    if FdfParser._Verify(Name, Value, 'UINT8'):
                        FmpData.HardwareInstance = Value
                elif Name == 'MONOTONIC_COUNT':
                    if FdfParser._Verify(Name, Value, 'UINT64'):
                        FmpData.MonotonicCount = Value
                        if FmpData.MonotonicCount.upper().startswith('0X'):
                            FmpData.MonotonicCount = int(FmpData.MonotonicCount, 16)
                        else:
                            FmpData.MonotonicCount = int(FmpData.MonotonicCount)
            if not self._GetNextToken():
                break
        else:
            self._UndoToken()

        if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):
            EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")

        # Only the IMAGE_TYPE_ID is required item
        if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList:
            raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self.FileName, self.CurrentLineNumber)
        # get the Image file and Vendor code file
        self._GetFMPCapsuleData(FmpData)
        if not FmpData.ImageFile:
            raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)
        # check whether more than one Vendor code file
        if len(FmpData.VendorCodeFile) > 1:
            raise Warning("Vendor code file max of 1 per FMP payload section.", self.FileName, self.CurrentLineNumber)
        self.Profile.FmpPayloadDict[FmpUiName] = FmpData
        return True

    ## _GetCapsule() method
    #
    #   Get capsule section contents and store its data into capsule list of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a capsule
    #   @retval False       Not able to find a capsule
    #
    def _GetCapsule(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[CAPSULE."):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[CAPSULE.", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning.Expected("[Capsule.]", self.FileName, self.CurrentLineNumber)

        CapsuleObj = Capsule()

        CapsuleName = self._GetUiName()
        if not CapsuleName:
            raise Warning.Expected("capsule name", self.FileName, self.CurrentLineNumber)

        CapsuleObj.UiCapsuleName = CapsuleName.upper()

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        if self._IsKeyword("CREATE_FILE"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)

            CapsuleObj.CreateFile = self._Token

        self._GetCapsuleStatements(CapsuleObj)
        self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
        return True

    ## _GetCapsuleStatements() method
    #
    #   Get statements for capsule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom statements are got
    #
    def _GetCapsuleStatements(self, Obj):
        self._GetCapsuleTokens(Obj)
        self._GetDefineStatements(Obj)
        self._GetSetStatements(Obj)
        self._GetCapsuleData(Obj)

    ## _GetCapsuleTokens() method
    #
    #   Get token statements for capsule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom token statements are got
    #
    def _GetCapsuleTokens(self, Obj):
        if not self._GetNextToken():
            return False
        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(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)
            if Name == 'CAPSULE_FLAGS':
                if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
                    raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
                Value = self._Token.strip()
                while self._IsToken(TAB_COMMA_SPLIT):
                    Value += TAB_COMMA_SPLIT
                    if not self._GetNextToken():
                        raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)
                    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 starting with 0x", self.FileName, self.CurrentLineNumber)
                try:
                    Value = int(Value, 0)
                except ValueError:
                    raise Warning.Expected("hex string failed to convert to value", 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
            if not self._GetNextToken():
                return False
        self._UndoToken()

    ## _GetCapsuleData() method
    #
    #   Get capsule data for capsule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom capsule data are got
    #
    def _GetCapsuleData(self, Obj):
        while True:
            IsInf = self._GetInfStatement(Obj, True)
            IsFile = self._GetFileStatement(Obj, True)
            IsFv = self._GetFvStatement(Obj)
            IsFd = self._GetFdStatement(Obj)
            IsAnyFile = self._GetAnyFileStatement(Obj)
            IsAfile = self._GetAfileStatement(Obj)
            IsFmp = self._GetFmpStatement(Obj)
            if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):
                break

    ## _GetFMPCapsuleData() method
    #
    #   Get capsule data for FMP capsule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom capsule data are got
    #
    def _GetFMPCapsuleData(self, Obj):
        while True:
            IsFv = self._GetFvStatement(Obj, True)
            IsFd = self._GetFdStatement(Obj, True)
            IsAnyFile = self._GetAnyFileStatement(Obj, True)
            if not (IsFv or IsFd or IsAnyFile):
                break

    ## _GetFvStatement() method
    #
    #   Get FV for capsule
    #
    #   @param  self        The object pointer
    #   @param  CapsuleObj  for whom FV is got
    #   @retval True        Successfully find a FV statement
    #   @retval False       Not able to find a FV statement
    #
    def _GetFvStatement(self, CapsuleObj, FMPCapsule = False):
        if not self._IsKeyword(BINARY_FILE_TYPE_FV):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)

        if self._Token.upper() not in self.Profile.FvDict:
            raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)

        myCapsuleFv = CapsuleFv()
        myCapsuleFv.FvName = self._Token
        if FMPCapsule:
            if not CapsuleObj.ImageFile:
                CapsuleObj.ImageFile.append(myCapsuleFv)
            else:
                CapsuleObj.VendorCodeFile.append(myCapsuleFv)
        else:
            CapsuleObj.CapsuleDataList.append(myCapsuleFv)
        return True

    ## _GetFdStatement() method
    #
    #   Get FD for capsule
    #
    #   @param  self        The object pointer
    #   @param  CapsuleObj  for whom FD is got
    #   @retval True        Successfully find a FD statement
    #   @retval False       Not able to find a FD statement
    #
    def _GetFdStatement(self, CapsuleObj, FMPCapsule = False):
        if not self._IsKeyword("FD"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)

        if self._Token.upper() not in self.Profile.FdDict:
            raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)

        myCapsuleFd = CapsuleFd()
        myCapsuleFd.FdName = self._Token
        if FMPCapsule:
            if not CapsuleObj.ImageFile:
                CapsuleObj.ImageFile.append(myCapsuleFd)
            else:
                CapsuleObj.VendorCodeFile.append(myCapsuleFd)
        else:
            CapsuleObj.CapsuleDataList.append(myCapsuleFd)
        return True

    def _GetFmpStatement(self, CapsuleObj):
        if not self._IsKeyword("FMP_PAYLOAD"):
            if not self._IsKeyword("FMP"):
                return False

            if not self._IsKeyword("PAYLOAD"):
                self._UndoToken()
                return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(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 None

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)

        AnyFileName = self._Token
        self._VerifyFile(AnyFileName)

        if not os.path.isabs(AnyFileName):
            AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)

        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, FMPCapsule = False):
        AnyFileName = self._ParseRawFileStatement()
        if not AnyFileName:
            return False

        myCapsuleAnyFile = CapsuleAnyFile()
        myCapsuleAnyFile.FileName = AnyFileName
        if FMPCapsule:
            if not CapsuleObj.ImageFile:
                CapsuleObj.ImageFile.append(myCapsuleAnyFile)
            else:
                CapsuleObj.VendorCodeFile.append(myCapsuleAnyFile)
        else:
            CapsuleObj.CapsuleDataList.append(myCapsuleAnyFile)
        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(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(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",BINARY_FILE_TYPE_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

        myCapsuleAfile = CapsuleAfile()
        myCapsuleAfile.FileName = AfileName
        CapsuleObj.CapsuleDataList.append(myCapsuleAfile)
        return True

    ## _GetRule() method
    #
    #   Get Rule section contents and store its data into rule list of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a Rule
    #   @retval False       Not able to find a Rule
    #
    def _GetRule(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[RULE."):
            self.SectionParser(S)
            self._UndoToken()
            return False
        self._UndoToken()
        if not self._IsToken("[Rule.", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning.Expected("[Rule.]", self.FileName, self.CurrentLineNumber)

        if not self._SkipToToken(TAB_SPLIT):
            raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)

        Arch = self._SkippedChars.rstrip(TAB_SPLIT)

        ModuleType = self._GetModuleType()

        TemplateName = ""
        if self._IsToken(TAB_SPLIT):
            if not self._GetNextWord():
                raise Warning.Expected("template name", self.FileName, self.CurrentLineNumber)
            TemplateName = self._Token

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        RuleObj = self._GetRuleFileStatements()
        RuleObj.Arch = Arch.upper()
        RuleObj.ModuleType = ModuleType
        RuleObj.TemplateName = TemplateName
        if TemplateName == '':
            self.Profile.RuleDict['RULE'             + \
                              TAB_SPLIT              + \
                              Arch.upper()           + \
                              TAB_SPLIT              + \
                              ModuleType.upper()     ] = RuleObj
        else:
            self.Profile.RuleDict['RULE'             + \
                              TAB_SPLIT              + \
                              Arch.upper()           + \
                              TAB_SPLIT              + \
                              ModuleType.upper()     + \
                              TAB_SPLIT              + \
                              TemplateName.upper() ] = RuleObj
        return True

    ## _GetModuleType() method
    #
    #   Return the module type
    #
    #   @param  self        The object pointer
    #   @retval string      module type
    #
    def _GetModuleType(self):
        if not self._GetNextWord():
            raise Warning.Expected("Module type", self.FileName, self.CurrentLineNumber)
        if self._Token.upper() not in {
                SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,
                SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER,
                SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER,
                SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_UEFI_DRIVER,
                SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, SUP_MODULE_HOST_APPLICATION,
                TAB_DEFAULT, SUP_MODULE_BASE,
                EDK_COMPONENT_TYPE_SECURITY_CORE,
                EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER,
                EDK_COMPONENT_TYPE_PIC_PEIM,
                EDK_COMPONENT_TYPE_RELOCATABLE_PEIM, "PE32_PEIM",
                EDK_COMPONENT_TYPE_BS_DRIVER, EDK_COMPONENT_TYPE_RT_DRIVER,
                EDK_COMPONENT_TYPE_SAL_RT_DRIVER,
                EDK_COMPONENT_TYPE_APPLICATION, "ACPITABLE",
                SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,
                SUP_MODULE_MM_CORE_STANDALONE}:
            raise Warning("Unknown Module type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
        return self._Token

    ## _GetFileExtension() method
    #
    #   Return the file extension
    #
    #   @param  self        The object pointer
    #   @retval string      file name extension
    #
    def _GetFileExtension(self):
        if not self._IsToken(TAB_SPLIT):
            raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)

        Ext = ""
        if self._GetNextToken():
            if FileExtensionPattern.match(self._Token):
                Ext = self._Token
                return TAB_SPLIT + Ext
            else:
                raise Warning("Unknown file extension '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        else:
            raise Warning.Expected("file extension", self.FileName, self.CurrentLineNumber)

    ## _GetRuleFileStatement() method
    #
    #   Get rule contents
    #
    #   @param  self        The object pointer
    #   @retval Rule        Rule object
    #
    def _GetRuleFileStatements(self):
        if not self._IsKeyword("FILE"):
            raise Warning.Expected("FILE", self.FileName, self.CurrentLineNumber)

        if not self._GetNextWord():
            raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)

        Type = self._Token.strip().upper()
        if Type not in {"RAW", "FREEFORM", SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,
                        "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE, EDK_COMPONENT_TYPE_APPLICATION,
                        "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,
                        SUP_MODULE_MM_CORE_STANDALONE}:
            raise Warning("Unknown FV type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._IsKeyword("$(NAMED_GUID)"):
            if not self._GetNextWord():
                NamedGuid = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip()
                if GlobalData.gGuidPatternEnd.match(NamedGuid):
                    self.CurrentOffsetWithinLine += len(NamedGuid)
                    self._Token = NamedGuid
                else:
                    raise Warning.Expected("$(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
            if self._Token == 'PCD':
                if not self._IsToken("("):
                    raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
                PcdPair = self._GetNextPcdSettings()
                if not self._IsToken(")"):
                    raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
                self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'

        NameGuid = self._Token

        KeepReloc = None
        if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
            if self._FileCouldHaveRelocFlag(Type):
                if self._Token == 'RELOCS_STRIPPED':
                    KeepReloc = False
                else:
                    KeepReloc = True
            else:
                raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

        KeyStringList = []
        if self._GetNextToken():
            if TokenFindPattern.match(self._Token):
                KeyStringList.append(self._Token)
                if self._IsToken(TAB_COMMA_SPLIT):
                    while self._GetNextToken():
                        if not TokenFindPattern.match(self._Token):
                            raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
                        KeyStringList.append(self._Token)

                        if not self._IsToken(TAB_COMMA_SPLIT):
                            break

            else:
                self._UndoToken()


        Fixed = False
        if self._IsKeyword("Fixed", True):
            Fixed = True

        CheckSum = False
        if self._IsKeyword("CheckSum", True):
            CheckSum = True

        AlignValue = ""
        if self._GetAlignment():
            if self._Token not in ALIGNMENTS:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            #For FFS, Auto is default option same to ""
            if not self._Token == "Auto":
                AlignValue = self._Token

        if self._IsToken("{"):
            # Complex file rule expected
            NewRule = RuleComplexFile()
            NewRule.FvFileType = Type
            NewRule.NameGuid = NameGuid
            NewRule.Alignment = AlignValue
            NewRule.CheckSum = CheckSum
            NewRule.Fixed = Fixed
            NewRule.KeyStringList = KeyStringList
            if KeepReloc is not None:
                NewRule.KeepReloc = KeepReloc

            while True:
                IsEncapsulate = self._GetRuleEncapsulationSection(NewRule)
                IsLeaf = self._GetEfiSection(NewRule)
                if not IsEncapsulate and not IsLeaf:
                    break

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            return NewRule

        else:
            # Simple file rule expected
            if not self._GetNextWord():
                raise Warning.Expected("leaf section type", self.FileName, self.CurrentLineNumber)

            SectionName = self._Token

            if SectionName not in {
                    "COMPAT16", BINARY_FILE_TYPE_PE32,
                    BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",
                    "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,
                    BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",
                    BINARY_FILE_TYPE_SMM_DEPEX}:
                raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)


            if self._IsKeyword("Fixed", True):
                Fixed = True

            if self._IsKeyword("CheckSum", True):
                CheckSum = True

            SectAlignment = ""
            if self._GetAlignment():
                if self._Token not in ALIGNMENTS:
                    raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
                if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):
                    raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
                SectAlignment = self._Token

            Ext = None
            if self._IsToken(TAB_VALUE_SPLIT):
                Ext = self._GetFileExtension()
            elif not self._GetNextToken():
                raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)

            NewRule = RuleSimpleFile()
            NewRule.SectionType = SectionName
            NewRule.FvFileType = Type
            NewRule.NameGuid = NameGuid
            NewRule.Alignment = AlignValue
            NewRule.SectAlignment = SectAlignment
            NewRule.CheckSum = CheckSum
            NewRule.Fixed = Fixed
            NewRule.KeyStringList = KeyStringList
            if KeepReloc is not None:
                NewRule.KeepReloc = KeepReloc
            NewRule.FileExtension = Ext
            NewRule.FileName = self._Token
            return NewRule

    ## _GetEfiSection() method
    #
    #   Get section list for Rule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom section is got
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetEfiSection(self, Obj):
        OldPos = self.GetFileBufferPos()
        EfiSectionObj = EfiSection()
        if not self._GetNextWord():
            CurrentLine = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip()
            if self._Token == '{' and Obj.FvFileType == "RAW" and TAB_SPLIT in CurrentLine:
                if self._IsToken(TAB_VALUE_SPLIT):
                    EfiSectionObj.FileExtension = self._GetFileExtension()
                elif self._GetNextToken():
                    EfiSectionObj.FileName = self._Token
                EfiSectionObj.SectionType = BINARY_FILE_TYPE_RAW
                Obj.SectionList.append(EfiSectionObj)
                return True
            else:
                return False
        SectionName = self._Token

        if SectionName not in {
                    "COMPAT16", BINARY_FILE_TYPE_PE32,
                    BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",
                    "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,
                    BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",
                    BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}:
            self._UndoToken()
            return False

        if SectionName == "FV_IMAGE":
            FvImageSectionObj = FvImageSection()
            if self._IsKeyword("FV_IMAGE"):
                pass
            if self._IsToken("{"):
                FvObj = FV()
                self._GetDefineStatements(FvObj)
                self._GetBlockStatement(FvObj)
                self._GetSetStatements(FvObj)
                self._GetFvAlignment(FvObj)
                self._GetFvAttributes(FvObj)
                self._GetAprioriSection(FvObj)
                self._GetAprioriSection(FvObj)

                while True:
                    IsInf = self._GetInfStatement(FvObj)
                    IsFile = self._GetFileStatement(FvObj)
                    if not IsInf and not IsFile:
                        break

                if not self._IsToken(T_CHAR_BRACE_R):
                    raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
                FvImageSectionObj.Fv = FvObj
                FvImageSectionObj.FvName = None

            else:
                if not self._IsKeyword(BINARY_FILE_TYPE_FV):
                    raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)
                FvImageSectionObj.FvFileType = self._Token

                if self._GetAlignment():
                    if self._Token not in ALIGNMENT_NOAUTO:
                        raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
                    FvImageSectionObj.Alignment = self._Token

                if self._IsToken(TAB_VALUE_SPLIT):
                    FvImageSectionObj.FvFileExtension = self._GetFileExtension()
                elif self._GetNextToken():
                    if self._Token not in {
                            T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,
                            BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,
                            "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,
                            BINARY_FILE_TYPE_UI, "VERSION",
                            BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,
                            BINARY_FILE_TYPE_SMM_DEPEX}:
                        FvImageSectionObj.FvFileName = self._Token
                    else:
                        self._UndoToken()
                else:
                    raise Warning.Expected("FV file name", self.FileName, self.CurrentLineNumber)

            Obj.SectionList.append(FvImageSectionObj)
            return True

        EfiSectionObj.SectionType = SectionName

        if not self._GetNextToken():
            raise Warning.Expected("file type", self.FileName, self.CurrentLineNumber)

        if self._Token == "STRING":
            if not self._RuleSectionCouldHaveString(EfiSectionObj.SectionType):
                raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("Quoted String", self.FileName, self.CurrentLineNumber)

            if self._GetStringData():
                EfiSectionObj.StringData = self._Token

            if self._IsKeyword("BUILD_NUM"):
                if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
                    raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

                if not self._IsToken(TAB_EQUAL_SPLIT):
                    raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                if not self._GetNextToken():
                    raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)
                EfiSectionObj.BuildNum = self._Token

        else:
            EfiSectionObj.FileType = self._Token
            self._CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)

        if self._IsKeyword("Optional"):
            if not self._RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
                raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
            EfiSectionObj.Optional = True

            if self._IsKeyword("BUILD_NUM"):
                if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
                    raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

                if not self._IsToken(TAB_EQUAL_SPLIT):
                    raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                if not self._GetNextToken():
                    raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)
                EfiSectionObj.BuildNum = self._Token

        if self._GetAlignment():
            if self._Token not in ALIGNMENTS:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            EfiSectionObj.Alignment = self._Token

        if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
            if self._SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
                if self._Token == 'RELOCS_STRIPPED':
                    EfiSectionObj.KeepReloc = False
                else:
                    EfiSectionObj.KeepReloc = True
                if Obj.KeepReloc is not None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
                    raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
            else:
                raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)


        if self._IsToken(TAB_VALUE_SPLIT):
            EfiSectionObj.FileExtension = self._GetFileExtension()
        elif self._GetNextToken():
            if self._Token not in {
                    T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,
                    BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,
                    "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,
                    BINARY_FILE_TYPE_UI, "VERSION",
                    BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,
                    BINARY_FILE_TYPE_SMM_DEPEX}:

                if self._Token.startswith('PCD'):
                    self._UndoToken()
                    self._GetNextWord()

                    if self._Token == 'PCD':
                        if not self._IsToken("("):
                            raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
                        PcdPair = self._GetNextPcdSettings()
                        if not self._IsToken(")"):
                            raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
                        self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'

                EfiSectionObj.FileName = self._Token

            else:
                self._UndoToken()
        else:
            raise Warning.Expected("section file name", self.FileName, self.CurrentLineNumber)

        Obj.SectionList.append(EfiSectionObj)
        return True

    ## _RuleSectionCouldBeOptional() method
    #
    #   Get whether a section could be optional
    #
    #   @param  SectionType The section type to check
    #   @retval True        section could be optional
    #   @retval False       section never optional
    #
    @staticmethod
    def _RuleSectionCouldBeOptional(SectionType):
        if SectionType in {BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "RAW", BINARY_FILE_TYPE_SMM_DEPEX}:
            return True
        else:
            return False

    ## _RuleSectionCouldHaveBuildNum() method
    #
    #   Get whether a section could have build number information
    #
    #   @param  SectionType The section type to check
    #   @retval True        section could have build number information
    #   @retval False       section never have build number information
    #
    @staticmethod
    def _RuleSectionCouldHaveBuildNum(SectionType):
        if SectionType == "VERSION":
            return True
        else:
            return False

    ## _RuleSectionCouldHaveString() method
    #
    #   Get whether a section could have string
    #
    #   @param  SectionType The section type to check
    #   @retval True        section could have string
    #   @retval False       section never have string
    #
    @staticmethod
    def _RuleSectionCouldHaveString(SectionType):
        if SectionType in {BINARY_FILE_TYPE_UI, "VERSION"}:
            return True
        else:
            return False

    ## _CheckRuleSectionFileType() method
    #
    #   Get whether a section matches a file type
    #
    #   @param  self        The object pointer
    #   @param  SectionType The section type to check
    #   @param  FileType    The file type to check
    #
    def _CheckRuleSectionFileType(self, SectionType, FileType):
        WarningString = "Incorrect section file type '%s'"
        if SectionType == "COMPAT16":
            if FileType not in {"COMPAT16", "SEC_COMPAT16"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_PE32:
            if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_PIC:
            if FileType not in {BINARY_FILE_TYPE_PIC, "SEC_PIC"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_TE:
            if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == "RAW":
            if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_DXE_DEPEX or SectionType == BINARY_FILE_TYPE_SMM_DEPEX:
            if FileType not in {BINARY_FILE_TYPE_DXE_DEPEX, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_UI:
            if FileType not in {BINARY_FILE_TYPE_UI, "SEC_UI"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == "VERSION":
            if FileType not in {"VERSION", "SEC_VERSION"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_PEI_DEPEX:
            if FileType not in {BINARY_FILE_TYPE_PEI_DEPEX, "SEC_PEI_DEPEX"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_GUID:
            if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_GUID"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)

    ## _GetRuleEncapsulationSection() method
    #
    #   Get encapsulation section for Rule
    #
    #   @param  self        The object pointer
    #   @param  theRule     for whom section is got
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetRuleEncapsulationSection(self, theRule):
        if self._IsKeyword("COMPRESS"):
            Type = "PI_STD"
            if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):
                Type = self._Token

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

            CompressSectionObj = CompressSection()

            CompressSectionObj.CompType = Type
            # Recursive sections...
            while True:
                IsEncapsulate = self._GetRuleEncapsulationSection(CompressSectionObj)
                IsLeaf = self._GetEfiSection(CompressSectionObj)
                if not IsEncapsulate and not IsLeaf:
                    break

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
            theRule.SectionList.append(CompressSectionObj)

            return True

        elif self._IsKeyword("GUIDED"):
            GuidValue = None
            if self._GetNextGuid():
                if self._Token in GlobalData.gGuidDict:
                    self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
                GuidValue = self._Token

            if self._IsKeyword("$(NAMED_GUID)"):
                GuidValue = self._Token

            AttribDict = self._GetGuidAttrib()

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
            GuidSectionObj = GuidSection()
            GuidSectionObj.NameGuid = GuidValue
            GuidSectionObj.SectionType = "GUIDED"
            GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
            GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
            GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]

            # Efi sections...
            while True:
                IsEncapsulate = self._GetRuleEncapsulationSection(GuidSectionObj)
                IsLeaf = self._GetEfiSection(GuidSectionObj)
                if not IsEncapsulate and not IsLeaf:
                    break

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
            theRule.SectionList.append(GuidSectionObj)

            return True

        return False

    ## _GetOptionRom() method
    #
    #   Get OptionROM section contents and store its data into OptionROM list of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a OptionROM
    #   @retval False       Not able to find a OptionROM
    #
    def _GetOptionRom(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[OPTIONROM."):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[OptionRom.", True):
            raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        OptRomName = self._GetUiName()

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        OptRomObj = OPTIONROM(OptRomName)
        self.Profile.OptRomDict[OptRomName] = OptRomObj

        while True:
            isInf = self._GetOptRomInfStatement(OptRomObj)
            isFile = self._GetOptRomFileStatement(OptRomObj)
            if not isInf and not isFile:
                break

        return True

    ## _GetOptRomInfStatement() method
    #
    #   Get INF statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom inf statement is got
    #   @retval True        Successfully find inf statement
    #   @retval False       Not able to find inf statement
    #
    def _GetOptRomInfStatement(self, Obj):
        if not self._IsKeyword("INF"):
            return False

        ffsInf = OptRomInfStatement()
        self._GetInfOptions(ffsInf)

        if not self._GetNextToken():
            raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)
        ffsInf.InfFileName = self._Token
        if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:
            #check for file path
            ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
            if ErrorCode != 0:
                EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)

        NewFileName = ffsInf.InfFileName
        if ffsInf.OverrideGuid:
            NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path

        if not NewFileName in self.Profile.InfList:
            self.Profile.InfList.append(NewFileName)
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            self.Profile.InfFileLineList.append(FileLineTuple)
            if ffsInf.UseArch:
                if ffsInf.UseArch not in self.Profile.InfDict:
                    self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
                else:
                    self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
            else:
                self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)


        self._GetOptRomOverrides (ffsInf)

        Obj.FfsList.append(ffsInf)
        return True

    ## _GetOptRomOverrides() method
    #
    #   Get overrides for OptROM INF & FILE
    #
    #   @param  self        The object pointer
    #   @param  FfsInfObj   for whom overrides is got
    #
    def _GetOptRomOverrides(self, Obj):
        if self._IsToken('{'):
            Overrides = OverrideAttribs()
            while True:
                if self._IsKeyword("PCI_VENDOR_ID"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    if not self._GetNextHexNumber():
                        raise Warning.Expected("Hex vendor id", self.FileName, self.CurrentLineNumber)
                    Overrides.PciVendorId = self._Token
                    continue

                if self._IsKeyword("PCI_CLASS_CODE"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    if not self._GetNextHexNumber():
                        raise Warning.Expected("Hex class code", self.FileName, self.CurrentLineNumber)
                    Overrides.PciClassCode = self._Token
                    continue

                if self._IsKeyword("PCI_DEVICE_ID"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    # Get a list of PCI IDs
                    Overrides.PciDeviceId = ""
                    while (self._GetNextHexNumber()):
                        Overrides.PciDeviceId = "{} {}".format(Overrides.PciDeviceId, self._Token)
                    if not Overrides.PciDeviceId:
                        raise Warning.Expected("one or more Hex device ids", self.FileName, self.CurrentLineNumber)
                    continue

                if self._IsKeyword("PCI_REVISION"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    if not self._GetNextHexNumber():
                        raise Warning.Expected("Hex revision", self.FileName, self.CurrentLineNumber)
                    Overrides.PciRevision = self._Token
                    continue

                if self._IsKeyword("PCI_COMPRESS"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    if not self._GetNextToken():
                        raise Warning.Expected("TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
                    Overrides.NeedCompress = self._Token.upper() == 'TRUE'
                    continue

                if self._IsToken(T_CHAR_BRACE_R):
                    break
                else:
                    EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)

            Obj.OverrideAttribs = Overrides

    ## _GetOptRomFileStatement() method
    #
    #   Get FILE statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom FILE statement is got
    #   @retval True        Successfully find FILE statement
    #   @retval False       Not able to find FILE statement
    #
    def _GetOptRomFileStatement(self, Obj):
        if not self._IsKeyword("FILE"):
            return False

        FfsFileObj = OptRomFileStatement()

        if not self._IsKeyword("EFI") and not self._IsKeyword(BINARY_FILE_TYPE_BIN):
            raise Warning.Expected("Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
        FfsFileObj.FileType = self._Token

        if not self._GetNextToken():
            raise Warning.Expected("File path", self.FileName, self.CurrentLineNumber)
        FfsFileObj.FileName = self._Token
        if FfsFileObj.FileName.replace(TAB_WORKSPACE, '').find('$') == -1:
            #check for file path
            ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
            if ErrorCode != 0:
                EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)

        if FfsFileObj.FileType == 'EFI':
            self._GetOptRomOverrides(FfsFileObj)

        Obj.FfsList.append(FfsFileObj)

        return True

    ## _GetCapInFd() method
    #
    #   Get Cap list contained in FD
    #
    #   @param  self        The object pointer
    #   @param  FdName      FD name
    #   @retval CapList     List of Capsule in FD
    #
    def _GetCapInFd (self, FdName):
        CapList = []
        if FdName.upper() in self.Profile.FdDict:
            FdObj = self.Profile.FdDict[FdName.upper()]
            for elementRegion in FdObj.RegionList:
                if elementRegion.RegionType == 'CAPSULE':
                    for elementRegionData in elementRegion.RegionDataList:
                        if elementRegionData.endswith(".cap"):
                            continue
                        if elementRegionData is not None and elementRegionData.upper() not in CapList:
                            CapList.append(elementRegionData.upper())
        return CapList

    ## _GetReferencedFdCapTuple() method
    #
    #   Get FV and FD list referenced by a capsule image
    #
    #   @param  self        The object pointer
    #   @param  CapObj      Capsule section to be searched
    #   @param  RefFdList   referenced FD by section
    #   @param  RefFvList   referenced FV by section
    #
    def _GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
        for CapsuleDataObj in CapObj.CapsuleDataList:
            if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName is not None and CapsuleDataObj.FvName.upper() not in RefFvList:
                RefFvList.append (CapsuleDataObj.FvName.upper())
            elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName is not None and CapsuleDataObj.FdName.upper() not in RefFdList:
                RefFdList.append (CapsuleDataObj.FdName.upper())
            elif CapsuleDataObj.Ffs is not None:
                if isinstance(CapsuleDataObj.Ffs, FileStatement):
                    if CapsuleDataObj.Ffs.FvName is not None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
                        RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
                    elif CapsuleDataObj.Ffs.FdName is not None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
                        RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
                    else:
                        self._GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)

    ## _GetFvInFd() method
    #
    #   Get FV list contained in FD
    #
    #   @param  self        The object pointer
    #   @param  FdName      FD name
    #   @retval FvList      list of FV in FD
    #
    def _GetFvInFd (self, FdName):
        FvList = []
        if FdName.upper() in self.Profile.FdDict:
            FdObj = self.Profile.FdDict[FdName.upper()]
            for elementRegion in FdObj.RegionList:
                if elementRegion.RegionType == BINARY_FILE_TYPE_FV:
                    for elementRegionData in elementRegion.RegionDataList:
                        if elementRegionData.endswith(".fv"):
                            continue
                        if elementRegionData is not None and elementRegionData.upper() not in FvList:
                            FvList.append(elementRegionData.upper())
        return FvList

    ## _GetReferencedFdFvTuple() method
    #
    #   Get FD and FV list referenced by a FFS file
    #
    #   @param  self        The object pointer
    #   @param  FfsFile     contains sections to be searched
    #   @param  RefFdList   referenced FD by section
    #   @param  RefFvList   referenced FV by section
    #
    def _GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
        for FfsObj in FvObj.FfsList:
            if isinstance(FfsObj, FileStatement):
                if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList:
                    RefFvList.append(FfsObj.FvName.upper())
                elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList:
                    RefFdList.append(FfsObj.FdName.upper())
                else:
                    self._GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)

    ## _GetReferencedFdFvTupleFromSection() method
    #
    #   Get FD and FV list referenced by a FFS section
    #
    #   @param  self        The object pointer
    #   @param  FfsFile     contains sections to be searched
    #   @param  FdList      referenced FD by section
    #   @param  FvList      referenced FV by section
    #
    def _GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
        SectionStack = list(FfsFile.SectionList)
        while SectionStack != []:
            SectionObj = SectionStack.pop()
            if isinstance(SectionObj, FvImageSection):
                if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList:
                    FvList.append(SectionObj.FvName.upper())
                if SectionObj.Fv is not None and SectionObj.Fv.UiFvName is not None and SectionObj.Fv.UiFvName.upper() not in FvList:
                    FvList.append(SectionObj.Fv.UiFvName.upper())
                    self._GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)

            if isinstance(SectionObj, CompressSection) or isinstance(SectionObj, GuidSection):
                SectionStack.extend(SectionObj.SectionList)

    ## CycleReferenceCheck() method
    #
    #   Check whether cycle reference exists in FDF
    #
    #   @param  self        The object pointer
    #   @retval True        cycle reference exists
    #   @retval False       Not exists cycle reference
    #
    def CycleReferenceCheck(self):
        #
        # Check the cycle between FV and FD image
        #
        MaxLength = len (self.Profile.FvDict)
        for FvName in self.Profile.FvDict:
            LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
            RefFvStack = set(FvName)
            FdAnalyzedList = set()

            Index = 0
            while RefFvStack and Index < MaxLength:
                Index = Index + 1
                FvNameFromStack = RefFvStack.pop()
                if FvNameFromStack.upper() in self.Profile.FvDict:
                    FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
                else:
                    continue

                RefFdList = []
                RefFvList = []
                self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)

                for RefFdName in RefFdList:
                    if RefFdName in FdAnalyzedList:
                        continue

                    LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
                    FvInFdList = self._GetFvInFd(RefFdName)
                    if FvInFdList != []:
                        for FvNameInFd in FvInFdList:
                            LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)
                            if FvNameInFd not in RefFvStack:
                                RefFvStack.add(FvNameInFd)

                            if FvName in RefFvStack or FvNameFromStack in RefFvStack:
                                EdkLogger.info(LogStr)
                                return True
                    FdAnalyzedList.add(RefFdName)

                for RefFvName in RefFvList:
                    LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
                    if RefFvName not in RefFvStack:
                        RefFvStack.add(RefFvName)

                    if FvName in RefFvStack or FvNameFromStack in RefFvStack:
                        EdkLogger.info(LogStr)
                        return True

        #
        # Check the cycle between Capsule and FD image
        #
        MaxLength = len (self.Profile.CapsuleDict)
        for CapName in self.Profile.CapsuleDict:
            #
            # Capsule image to be checked.
            #
            LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
            RefCapStack = {CapName}
            FdAnalyzedList = set()
            FvAnalyzedList = set()

            Index = 0
            while RefCapStack and Index < MaxLength:
                Index = Index + 1
                CapNameFromStack = RefCapStack.pop()
                if CapNameFromStack.upper() in self.Profile.CapsuleDict:
                    CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
                else:
                    continue

                RefFvList = []
                RefFdList = []
                self._GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)

                FvListLength = 0
                FdListLength = 0
                while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
                    for RefFdName in RefFdList:
                        if RefFdName in FdAnalyzedList:
                            continue

                        LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
                        for CapNameInFd in self._GetCapInFd(RefFdName):
                            LogStr += "FD %s contains Capsule %s\n" % (RefFdName, CapNameInFd)
                            if CapNameInFd not in RefCapStack:
                                RefCapStack.append(CapNameInFd)

                            if CapName in RefCapStack or CapNameFromStack in RefCapStack:
                                EdkLogger.info(LogStr)
                                return True

                        for FvNameInFd in self._GetFvInFd(RefFdName):
                            LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)
                            if FvNameInFd not in RefFvList:
                                RefFvList.append(FvNameInFd)

                        FdAnalyzedList.add(RefFdName)
                    #
                    # the number of the parsed FV and FD image
                    #
                    FvListLength = len (RefFvList)
                    FdListLength = len (RefFdList)
                    for RefFvName in RefFvList:
                        if RefFvName in FvAnalyzedList:
                            continue
                        LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
                        if RefFvName.upper() in self.Profile.FvDict:
                            FvObj = self.Profile.FvDict[RefFvName.upper()]
                        else:
                            continue
                        self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
                        FvAnalyzedList.add(RefFvName)

        return False

    def GetAllIncludedFile (self):
        global AllIncludeFileList
        return AllIncludeFileList

if __name__ == "__main__":
    import sys
    try:
        test_file = sys.argv[1]
    except IndexError as v:
        print("Usage: %s filename" % sys.argv[0])
        sys.exit(1)

    parser = FdfParser(test_file)
    try:
        parser.ParseFile()
        parser.CycleReferenceCheck()
    except Warning as X:
        print(str(X))
    else:
        print("Success!")

