Home | History | Annotate | Download | only in GenFds
      1 ## @file

      2 # parse FDF file

      3 #

      4 #  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>

      5 #  Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>

      6 #

      7 #  This program and the accompanying materials

      8 #  are licensed and made available under the terms and conditions of the BSD License

      9 #  which accompanies this distribution.  The full text of the license may be found at

     10 #  http://opensource.org/licenses/bsd-license.php

     11 #

     12 #  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     13 #  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     14 #

     15 
     16 ##

     17 # Import Modules

     18 #

     19 import re
     20 
     21 import Fd
     22 import Region
     23 import Fv
     24 import AprioriSection
     25 import FfsInfStatement
     26 import FfsFileStatement
     27 import VerSection
     28 import UiSection
     29 import FvImageSection
     30 import DataSection
     31 import DepexSection
     32 import CompressSection
     33 import GuidSection
     34 import Capsule
     35 import CapsuleData
     36 import Rule
     37 import RuleComplexFile
     38 import RuleSimpleFile
     39 import EfiSection
     40 import Vtf
     41 import ComponentStatement
     42 import OptionRom
     43 import OptRomInfStatement
     44 import OptRomFileStatement
     45 
     46 from GenFdsGlobalVariable import GenFdsGlobalVariable
     47 from Common.BuildToolError import *
     48 from Common import EdkLogger
     49 from Common.Misc import PathClass
     50 from Common.String import NormPath
     51 import Common.GlobalData as GlobalData
     52 from Common.Expression import *
     53 from Common import GlobalData
     54 from Common.String import ReplaceMacro
     55 import uuid
     56 from Common.Misc import tdict
     57 from Common.MultipleWorkspace import MultipleWorkspace as mws
     58 import Common.LongFilePathOs as os
     59 from Common.LongFilePathSupport import OpenLongFilePath as open
     60 from Capsule import EFI_CERT_TYPE_PKCS7_GUID
     61 from Capsule import EFI_CERT_TYPE_RSA2048_SHA256_GUID
     62 
     63 ##define T_CHAR_SPACE                ' '

     64 ##define T_CHAR_NULL                 '\0'

     65 ##define T_CHAR_CR                   '\r'

     66 ##define T_CHAR_TAB                  '\t'

     67 ##define T_CHAR_LF                   '\n'

     68 ##define T_CHAR_SLASH                '/'

     69 ##define T_CHAR_BACKSLASH            '\\'

     70 ##define T_CHAR_DOUBLE_QUOTE         '\"'

     71 ##define T_CHAR_SINGLE_QUOTE         '\''

     72 ##define T_CHAR_STAR                 '*'

     73 ##define T_CHAR_HASH                 '#'

     74 
     75 (T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \
     76 T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
     77 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
     78 
     79 SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
     80 
     81 RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
     82 RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
     83 RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")
     84 ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
     85 
     86 AllIncludeFileList = []
     87 
     88 # Get the closest parent
     89 def GetParentAtLine (Line):
     90     for Profile in AllIncludeFileList:
     91         if Profile.IsLineInFile(Line):
     92             return Profile
     93     return None
     94 
     95 # Check include loop
     96 def IsValidInclude (File, Line):
     97     for Profile in AllIncludeFileList:
     98         if Profile.IsLineInFile(Line) and Profile.FileName == File:
     99             return False
    100 
    101     return True
    102 
    103 def GetRealFileLine (File, Line):
    104 
    105     InsertedLines = 0
    106     for Profile in AllIncludeFileList:
    107         if Profile.IsLineInFile(Line):
    108             return Profile.GetLineInFile(Line)
    109         elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:
    110             InsertedLines += Profile.GetTotalLines()
    111 
    112     return (File, Line - InsertedLines)
    113 
    114 ## The exception class that used to report error messages when parsing FDF
    115 #
    116 # Currently the "ToolName" is set to be "FDF Parser".
    117 #
    118 class Warning (Exception):
    119     ## The constructor
    120     #
    121     #   @param  self        The object pointer
    122     #   @param  Str         The message to record
    123     #   @param  File        The FDF name
    124     #   @param  Line        The Line number that error occurs
    125     #
    126     def __init__(self, Str, File = None, Line = None):
    127 
    128         FileLineTuple = GetRealFileLine(File, Line)
    129         self.FileName = FileLineTuple[0]
    130         self.LineNumber = FileLineTuple[1]
    131         self.OriginalLineNumber = Line
    132         self.Message = Str
    133         self.ToolName = 'FdfParser'
    134 
    135     def __str__(self):
    136         return self.Message
    137 
    138 ## The MACRO class that used to record macro value data when parsing include file
    139 #
    140 #
    141 class MacroProfile :
    142     ## The constructor
    143     #
    144     #   @param  self        The object pointer
    145     #   @param  FileName    The file that to be parsed
    146     #
    147     def __init__(self, FileName, Line):
    148         self.FileName = FileName
    149         self.DefinedAtLine  = Line
    150         self.MacroName = None
    151         self.MacroValue = None
    152 
    153 ## The Include file content class that used to record file data when parsing include file
    154 #
    155 # May raise Exception when opening file.
    156 #
    157 class IncludeFileProfile :
    158     ## The constructor
    159     #
    160     #   @param  self        The object pointer
    161     #   @param  FileName    The file that to be parsed
    162     #
    163     def __init__(self, FileName):
    164         self.FileName = FileName
    165         self.FileLinesList = []
    166         try:
    167             fsock = open(FileName, "rb", 0)
    168             try:
    169                 self.FileLinesList = fsock.readlines()
    170             finally:
    171                 fsock.close()
    172 
    173         except:
    174             EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
    175 
    176         self.InsertStartLineNumber = None
    177         self.InsertAdjust = 0
    178         self.IncludeFileList = []
    179         self.Level = 1 # first level include file
    180     
    181     def GetTotalLines(self):
    182         TotalLines = self.InsertAdjust + len(self.FileLinesList)
    183 
    184         for Profile in self.IncludeFileList:
    185             TotalLines += Profile.GetTotalLines()
    186 
    187         return TotalLines
    188 
    189     def IsLineInFile(self, Line):
    190         if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():
    191             return True
    192 
    193         return False
    194 
    195     def GetLineInFile(self, Line):
    196         if not self.IsLineInFile (Line):
    197             return (self.FileName, -1)
    198         
    199         InsertedLines = self.InsertStartLineNumber
    200 
    201         for Profile in self.IncludeFileList:
    202             if Profile.IsLineInFile(Line):
    203                 return Profile.GetLineInFile(Line)
    204             elif Line >= Profile.InsertStartLineNumber:
    205                 InsertedLines += Profile.GetTotalLines()
    206 
    207         return (self.FileName, Line - InsertedLines + 1)
    208 
    209 
    210 
    211 ## The FDF content class that used to record file data when parsing FDF
    212 #
    213 # May raise Exception when opening file.
    214 #
    215 class FileProfile :
    216     ## The constructor
    217     #
    218     #   @param  self        The object pointer
    219     #   @param  FileName    The file that to be parsed
    220     #
    221     def __init__(self, FileName):
    222         self.FileLinesList = []
    223         try:
    224             fsock = open(FileName, "rb", 0)
    225             try:
    226                 self.FileLinesList = fsock.readlines()
    227             finally:
    228                 fsock.close()
    229 
    230         except:
    231             EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
    232 
    233 
    234         self.PcdDict = {}
    235         self.InfList = []
    236         self.InfDict = {'ArchTBD':[]}
    237         # ECC will use this Dict and List information
    238         self.PcdFileLineDict = {}
    239         self.InfFileLineList = []
    240         
    241         self.FdDict = {}
    242         self.FdNameNotSet = False
    243         self.FvDict = {}
    244         self.CapsuleDict = {}
    245         self.VtfList = []
    246         self.RuleDict = {}
    247         self.OptRomDict = {}
    248         self.FmpPayloadDict = {}
    249 
    250 ## The syntax parser for FDF
    251 #
    252 # PreprocessFile method should be called prior to ParseFile
    253 # CycleReferenceCheck method can detect cycles in FDF contents
    254 #
    255 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
    256 # Get*** procedures mean these procedures will make judgement on current token only.
    257 #
    258 class FdfParser:
    259     ## The constructor
    260     #
    261     #   @param  self        The object pointer
    262     #   @param  FileName    The file that to be parsed
    263     #
    264     def __init__(self, FileName):
    265         self.Profile = FileProfile(FileName)
    266         self.FileName = FileName
    267         self.CurrentLineNumber = 1
    268         self.CurrentOffsetWithinLine = 0
    269         self.CurrentFdName = None
    270         self.CurrentFvName = None
    271         self.__Token = ""
    272         self.__SkippedChars = ""
    273         GlobalData.gFdfParser = self
    274 
    275         # Used to section info
    276         self.__CurSection = []
    277         # Key: [section name, UI name, arch]
    278         # Value: {MACRO_NAME : MACRO_VALUE}
    279         self.__MacroDict = tdict(True, 3)
    280         self.__PcdDict = {}
    281 
    282         self.__WipeOffArea = []
    283         if GenFdsGlobalVariable.WorkSpaceDir == '':
    284             GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")
    285 
    286     ## __IsWhiteSpace() method
    287     #
    288     #   Whether char at current FileBufferPos is whitespace
    289     #
    290     #   @param  self        The object pointer
    291     #   @param  Char        The char to test
    292     #   @retval True        The char is a kind of white space
    293     #   @retval False       The char is NOT a kind of white space
    294     #
    295     def __IsWhiteSpace(self, Char):
    296         if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):
    297             return True
    298         else:
    299             return False
    300 
    301     ## __SkipWhiteSpace() method
    302     #
    303     #   Skip white spaces from current char, return number of chars skipped
    304     #
    305     #   @param  self        The object pointer
    306     #   @retval Count       The number of chars skipped
    307     #
    308     def __SkipWhiteSpace(self):
    309         Count = 0
    310         while not self.__EndOfFile():
    311             Count += 1
    312             if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):
    313                 self.__SkippedChars += str(self.__CurrentChar())
    314                 self.__GetOneChar()
    315 
    316             else:
    317                 Count = Count - 1
    318                 return Count
    319 
    320     ## __EndOfFile() method
    321     #
    322     #   Judge current buffer pos is at file end
    323     #
    324     #   @param  self        The object pointer
    325     #   @retval True        Current File buffer position is at file end
    326     #   @retval False       Current File buffer position is NOT at file end
    327     #
    328     def __EndOfFile(self):
    329         NumberOfLines = len(self.Profile.FileLinesList)
    330         SizeOfLastLine = len(self.Profile.FileLinesList[-1])
    331         if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
    332             return True
    333         elif self.CurrentLineNumber > NumberOfLines:
    334             return True
    335         else:
    336             return False
    337 
    338     ## __EndOfLine() method
    339     #
    340     #   Judge current buffer pos is at line end
    341     #
    342     #   @param  self        The object pointer
    343     #   @retval True        Current File buffer position is at line end
    344     #   @retval False       Current File buffer position is NOT at line end
    345     #
    346     def __EndOfLine(self):
    347         if self.CurrentLineNumber > len(self.Profile.FileLinesList):
    348             return True
    349         SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
    350         if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
    351             return True
    352         else:
    353             return False
    354 
    355     ## Rewind() method
    356     #
    357     #   Reset file data buffer to the initial state
    358     #
    359     #   @param  self        The object pointer
    360     #   @param  DestLine    Optional new destination line number.
    361     #   @param  DestOffset  Optional new destination offset.     
    362     #
    363     def Rewind(self, DestLine = 1, DestOffset = 0):  
    364         self.CurrentLineNumber = DestLine           
    365         self.CurrentOffsetWithinLine = DestOffset   
    366 
    367     ## __UndoOneChar() method
    368     #
    369     #   Go back one char in the file buffer
    370     #
    371     #   @param  self        The object pointer
    372     #   @retval True        Successfully go back one char
    373     #   @retval False       Not able to go back one char as file beginning reached
    374     #
    375     def __UndoOneChar(self):
    376 
    377         if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
    378             return False
    379         elif self.CurrentOffsetWithinLine == 0:
    380             self.CurrentLineNumber -= 1
    381             self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1
    382         else:
    383             self.CurrentOffsetWithinLine -= 1
    384         return True
    385 
    386     ## __GetOneChar() method
    387     #
    388     #   Move forward one char in the file buffer
    389     #
    390     #   @param  self        The object pointer
    391     #
    392     def __GetOneChar(self):
    393         if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
    394             self.CurrentLineNumber += 1
    395             self.CurrentOffsetWithinLine = 0
    396         else:
    397             self.CurrentOffsetWithinLine += 1
    398 
    399     ## __CurrentChar() method
    400     #
    401     #   Get the char pointed to by the file buffer pointer
    402     #
    403     #   @param  self        The object pointer
    404     #   @retval Char        Current char
    405     #
    406     def __CurrentChar(self):
    407         return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]
    408 
    409     ## __NextChar() method
    410     #
    411     #   Get the one char pass the char pointed to by the file buffer pointer
    412     #
    413     #   @param  self        The object pointer
    414     #   @retval Char        Next char
    415     #
    416     def __NextChar(self):
    417         if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
    418             return self.Profile.FileLinesList[self.CurrentLineNumber][0]
    419         else:
    420             return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]
    421 
    422     ## __SetCurrentCharValue() method
    423     #
    424     #   Modify the value of current char
    425     #
    426     #   @param  self        The object pointer
    427     #   @param  Value       The new value of current char
    428     #
    429     def __SetCurrentCharValue(self, Value):
    430         self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value
    431 
    432     ## __CurrentLine() method
    433     #
    434     #   Get the list that contains current line contents
    435     #
    436     #   @param  self        The object pointer
    437     #   @retval List        current line contents
    438     #
    439     def __CurrentLine(self):
    440         return self.Profile.FileLinesList[self.CurrentLineNumber - 1]
    441 
    442     def __StringToList(self):
    443         self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
    444         self.Profile.FileLinesList[-1].append(' ')
    445 
    446     def __ReplaceFragment(self, StartPos, EndPos, Value = ' '):
    447         if StartPos[0] == EndPos[0]:
    448             Offset = StartPos[1]
    449             while Offset <= EndPos[1]:
    450                 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
    451                 Offset += 1
    452             return
    453 
    454         Offset = StartPos[1]
    455         while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):
    456             self.Profile.FileLinesList[StartPos[0]][Offset] = Value
    457             Offset += 1
    458 
    459         Line = StartPos[0]
    460         while Line < EndPos[0]:
    461             Offset = 0
    462             while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):
    463                 self.Profile.FileLinesList[Line][Offset] = Value
    464                 Offset += 1
    465             Line += 1
    466 
    467         Offset = 0
    468         while Offset <= EndPos[1]:
    469             self.Profile.FileLinesList[EndPos[0]][Offset] = Value
    470             Offset += 1
    471 
    472 
    473     def __GetMacroName(self):
    474         if not self.__GetNextToken():
    475             raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
    476         MacroName = self.__Token
    477         NotFlag = False
    478         if MacroName.startswith('!'):
    479             NotFlag = True
    480             MacroName = MacroName[1:].strip()
    481          
    482         if not MacroName.startswith('$(') or not MacroName.endswith(')'):
    483             raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},
    484                           self.FileName, self.CurrentLineNumber)
    485         MacroName = MacroName[2:-1]
    486         return MacroName, NotFlag
    487 
    488     def __SetMacroValue(self, Macro, Value):
    489         if not self.__CurSection:
    490             return
    491 
    492         MacroDict = {}
    493         if not self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]:
    494             self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] = MacroDict
    495         else:
    496             MacroDict = self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]
    497         MacroDict[Macro] = Value
    498 
    499     def __GetMacroValue(self, Macro):
    500         # Highest priority
    501         if Macro in GlobalData.gCommandLineDefines:
    502             return GlobalData.gCommandLineDefines[Macro]
    503         if Macro in GlobalData.gGlobalDefines:
    504             return GlobalData.gGlobalDefines[Macro]
    505 
    506         if self.__CurSection:
    507             MacroDict = self.__MacroDict[
    508                         self.__CurSection[0],
    509                         self.__CurSection[1],
    510                         self.__CurSection[2]
    511             ]
    512             if MacroDict and Macro in MacroDict:
    513                 return MacroDict[Macro]
    514 
    515         # Lowest priority
    516         if Macro in GlobalData.gPlatformDefines:
    517             return GlobalData.gPlatformDefines[Macro]
    518         return None
    519 
    520     def __SectionHeaderParser(self, Section):
    521         # [Defines]
    522         # [FD.UiName]: use dummy instead if UI name is optional
    523         # [FV.UiName]
    524         # [Capsule.UiName]
    525         # [Rule]: don't take rule section into account, macro is not allowed in this section
    526         # [VTF.arch.UiName, arch]
    527         # [OptionRom.DriverName]
    528         self.__CurSection = []
    529         Section = Section.strip()[1:-1].upper().replace(' ', '').strip('.')
    530         ItemList = Section.split('.')
    531         Item = ItemList[0]
    532         if Item == '' or Item == 'RULE':
    533             return
    534 
    535         if Item == 'DEFINES':
    536             self.__CurSection = ['COMMON', 'COMMON', 'COMMON']
    537         elif Item == 'VTF' and len(ItemList) == 3:
    538             UiName = ItemList[2]
    539             Pos = UiName.find(',')
    540             if Pos != -1:
    541                 UiName = UiName[:Pos]
    542             self.__CurSection = ['VTF', UiName, ItemList[1]]
    543         elif len(ItemList) > 1:
    544             self.__CurSection = [ItemList[0], ItemList[1], 'COMMON']
    545         elif len(ItemList) > 0:
    546             self.__CurSection = [ItemList[0], 'DUMMY', 'COMMON']
    547 
    548     ## PreprocessFile() method
    549     #
    550     #   Preprocess file contents, replace comments with spaces.
    551     #   In the end, rewind the file buffer pointer to the beginning
    552     #   BUGBUG: No !include statement processing contained in this procedure
    553     #   !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
    554     #
    555     #   @param  self        The object pointer
    556     #
    557     def PreprocessFile(self):
    558 
    559         self.Rewind()
    560         InComment = False
    561         DoubleSlashComment = False
    562         HashComment = False
    563         # HashComment in quoted string " " is ignored.
    564         InString = False
    565 
    566         while not self.__EndOfFile():
    567 
    568             if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
    569                 InString = not InString
    570             # meet new line, then no longer in a comment for // and '#'
    571             if self.__CurrentChar() == T_CHAR_LF:
    572                 self.CurrentLineNumber += 1
    573                 self.CurrentOffsetWithinLine = 0
    574                 if InComment and DoubleSlashComment:
    575                     InComment = False
    576                     DoubleSlashComment = False
    577                 if InComment and HashComment:
    578                     InComment = False
    579                     HashComment = False
    580             # check for */ comment end
    581             elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:
    582                 self.__SetCurrentCharValue(T_CHAR_SPACE)
    583                 self.__GetOneChar()
    584                 self.__SetCurrentCharValue(T_CHAR_SPACE)
    585                 self.__GetOneChar()
    586                 InComment = False
    587             # set comments to spaces
    588             elif InComment:
    589                 self.__SetCurrentCharValue(T_CHAR_SPACE)
    590                 self.__GetOneChar()
    591             # check for // comment
    592             elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():
    593                 InComment = True
    594                 DoubleSlashComment = True
    595             # check for '#' comment
    596             elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:
    597                 InComment = True
    598                 HashComment = True
    599             # check for /* comment start
    600             elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:
    601                 self.__SetCurrentCharValue( T_CHAR_SPACE)
    602                 self.__GetOneChar()
    603                 self.__SetCurrentCharValue( T_CHAR_SPACE)
    604                 self.__GetOneChar()
    605                 InComment = True
    606             else:
    607                 self.__GetOneChar()
    608 
    609         # restore from ListOfList to ListOfString
    610         self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
    611         self.Rewind()
    612 
    613     ## PreprocessIncludeFile() method
    614     #
    615     #   Preprocess file contents, replace !include statements with file contents.
    616     #   In the end, rewind the file buffer pointer to the beginning
    617     #
    618     #   @param  self        The object pointer
    619     #
    620     def PreprocessIncludeFile(self):
    621 	    # nested include support
    622         Processed = False
    623         while self.__GetNextToken():
    624 
    625             if self.__Token == '!include':
    626                 Processed = True
    627                 IncludeLine = self.CurrentLineNumber
    628                 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')
    629                 if not self.__GetNextToken():
    630                     raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)
    631                 IncFileName = self.__Token
    632                 __IncludeMacros = {}
    633                 for Macro in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']:
    634                     MacroVal = self.__GetMacroValue(Macro)
    635                     if MacroVal:
    636                         __IncludeMacros[Macro] = MacroVal
    637 
    638                 try:
    639                     IncludedFile = NormPath(ReplaceMacro(IncFileName, __IncludeMacros, RaiseError=True))
    640                 except:
    641                     raise Warning("only these system environment variables are permitted to start the path of the included file: "
    642                                   "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)",
    643                                   self.FileName, self.CurrentLineNumber)
    644                 #
    645                 # First search the include file under the same directory as FDF file
    646                 #
    647                 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))
    648                 ErrorCode = IncludedFile1.Validate()[0]
    649                 if ErrorCode != 0:
    650                     #
    651                     # Then search the include file under the same directory as DSC file
    652                     #
    653                     PlatformDir = ''
    654                     if GenFdsGlobalVariable.ActivePlatform:
    655                         PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir
    656                     elif GlobalData.gActivePlatform:
    657                         PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir
    658                     IncludedFile1 = PathClass(IncludedFile, PlatformDir)
    659                     ErrorCode = IncludedFile1.Validate()[0]
    660                     if ErrorCode != 0:
    661                         #
    662                         # Also search file under the WORKSPACE directory
    663                         #
    664                         IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)
    665                         ErrorCode = IncludedFile1.Validate()[0]
    666                         if ErrorCode != 0:
    667                             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), 
    668                                           self.FileName, self.CurrentLineNumber)
    669 
    670                 if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):
    671                     raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)
    672 
    673                 IncFileProfile = IncludeFileProfile(IncludedFile1.Path)
    674 
    675                 CurrentLine = self.CurrentLineNumber
    676                 CurrentOffset = self.CurrentOffsetWithinLine
    677                 # list index of the insertion, note that line number is 'CurrentLine + 1'
    678                 InsertAtLine = CurrentLine
    679                 ParentProfile = GetParentAtLine (CurrentLine)
    680                 if ParentProfile != None:
    681                     ParentProfile.IncludeFileList.insert(0, IncFileProfile)
    682                     IncFileProfile.Level = ParentProfile.Level + 1
    683                 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
    684                 # deal with remaining portions after "!include filename", if exists.
    685                 if self.__GetNextToken():
    686                     if self.CurrentLineNumber == CurrentLine:
    687                         RemainingLine = self.__CurrentLine()[CurrentOffset:]
    688                         self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
    689                         IncFileProfile.InsertAdjust += 1
    690                         self.CurrentLineNumber += 1
    691                         self.CurrentOffsetWithinLine = 0
    692 
    693                 for Line in IncFileProfile.FileLinesList:
    694                     self.Profile.FileLinesList.insert(InsertAtLine, Line)
    695                     self.CurrentLineNumber += 1
    696                     InsertAtLine += 1
    697 
    698                 # reversely sorted to better determine error in file
    699                 AllIncludeFileList.insert(0, IncFileProfile)
    700 
    701                 # comment out the processed include file statement
    702                 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
    703                 TempList.insert(IncludeOffset, '#')
    704                 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
    705             if Processed: # Nested and back-to-back support
    706                 self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)
    707                 Processed = False
    708         # Preprocess done.
    709         self.Rewind()
    710         
    711     def __GetIfListCurrentItemStat(self, IfList):
    712         if len(IfList) == 0:
    713             return True
    714         
    715         for Item in IfList:
    716             if Item[1] == False:
    717                 return False
    718         
    719         return True
    720     
    721     ## PreprocessConditionalStatement() method
    722     #
    723     #   Preprocess conditional statement.
    724     #   In the end, rewind the file buffer pointer to the beginning
    725     #
    726     #   @param  self        The object pointer
    727     #
    728     def PreprocessConditionalStatement(self):
    729         # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
    730         IfList = []
    731         RegionLayoutLine = 0
    732         ReplacedLine = -1
    733         while self.__GetNextToken():
    734             # Determine section name and the location dependent macro
    735             if self.__GetIfListCurrentItemStat(IfList):
    736                 if self.__Token.startswith('['):
    737                     Header = self.__Token
    738                     if not self.__Token.endswith(']'):
    739                         self.__SkipToToken(']')
    740                         Header += self.__SkippedChars
    741                     if Header.find('$(') != -1:
    742                         raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)
    743                     self.__SectionHeaderParser(Header)
    744                     continue
    745                 # Replace macros except in RULE section or out of section
    746                 elif self.__CurSection and ReplacedLine != self.CurrentLineNumber:
    747                     ReplacedLine = self.CurrentLineNumber
    748                     self.__UndoToken()
    749                     CurLine = self.Profile.FileLinesList[ReplacedLine - 1]
    750                     PreIndex = 0
    751                     StartPos = CurLine.find('$(', PreIndex)
    752                     EndPos = CurLine.find(')', StartPos+2)
    753                     while StartPos != -1 and EndPos != -1 and self.__Token not in ['!ifdef', '!ifndef', '!if', '!elseif']:
    754                         MacroName = CurLine[StartPos+2 : EndPos]
    755                         MacorValue = self.__GetMacroValue(MacroName)
    756                         if MacorValue != None:
    757                             CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)
    758                             if MacorValue.find('$(') != -1:
    759                                 PreIndex = StartPos
    760                             else:
    761                                 PreIndex = StartPos + len(MacorValue)
    762                         else:
    763                             PreIndex = EndPos + 1
    764                         StartPos = CurLine.find('$(', PreIndex)
    765                         EndPos = CurLine.find(')', StartPos+2)
    766                     self.Profile.FileLinesList[ReplacedLine - 1] = CurLine
    767                     continue
    768 
    769             if self.__Token == 'DEFINE':
    770                 if self.__GetIfListCurrentItemStat(IfList):
    771                     if not self.__CurSection:
    772                         raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)
    773                     DefineLine = self.CurrentLineNumber - 1
    774                     DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
    775                     if not self.__GetNextToken():
    776                         raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
    777                     Macro = self.__Token
    778                     if not self.__IsToken( "="):
    779                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
    780     
    781                     Value = self.__GetExpression()
    782                     self.__SetMacroValue(Macro, Value)
    783                     self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
    784             elif self.__Token == 'SET':
    785                 if not self.__GetIfListCurrentItemStat(IfList):
    786                     continue
    787                 SetLine = self.CurrentLineNumber - 1
    788                 SetOffset = self.CurrentOffsetWithinLine - len('SET')
    789                 PcdPair = self.__GetNextPcdName()
    790                 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
    791                 if not self.__IsToken( "="):
    792                     raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
    793 
    794                 Value = self.__GetExpression()
    795                 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
    796 
    797                 self.__PcdDict[PcdName] = Value
    798 
    799                 self.Profile.PcdDict[PcdPair] = Value
    800                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
    801                 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
    802 
    803                 self.__WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
    804             elif self.__Token in ('!ifdef', '!ifndef', '!if'):
    805                 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
    806                 IfList.append([IfStartPos, None, None])
    807 
    808                 CondLabel = self.__Token
    809                 Expression = self.__GetExpression()
    810                 
    811                 if CondLabel == '!if':
    812                     ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
    813                 else:
    814                     ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
    815                     if CondLabel == '!ifndef':
    816                         ConditionSatisfied = not ConditionSatisfied
    817 
    818                 BranchDetermined = ConditionSatisfied
    819                 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
    820                 if ConditionSatisfied:
    821                     self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))                 
    822             elif self.__Token in ('!elseif', '!else'):
    823                 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
    824                 if len(IfList) <= 0:
    825                     raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
    826 
    827                 if IfList[-1][1]:
    828                     IfList[-1] = [ElseStartPos, False, True]
    829                     self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
    830                 else:
    831                     self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
    832                     IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
    833                     if self.__Token == '!elseif':
    834                         Expression = self.__GetExpression()
    835                         ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
    836                         IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
    837 
    838                     if IfList[-1][1]:
    839                         if IfList[-1][2]:
    840                             IfList[-1][1] = False
    841                         else:
    842                             IfList[-1][2] = True
    843                             self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
    844             elif self.__Token == '!endif':
    845                 if len(IfList) <= 0:
    846                     raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
    847                 if IfList[-1][1]:
    848                     self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
    849                 else:
    850                     self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
    851 
    852                 IfList.pop()
    853             elif not IfList:    # Don't use PCDs inside conditional directive
    854                 if self.CurrentLineNumber <= RegionLayoutLine:
    855                     # Don't try the same line twice

    856                     continue
    857                 SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
    858                 if SetPcd:
    859                     self.__PcdDict[SetPcd.group('name')] = SetPcd.group('value')
    860                     RegionLayoutLine = self.CurrentLineNumber
    861                     continue
    862                 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
    863                 if not RegionSize:
    864                     RegionLayoutLine = self.CurrentLineNumber
    865                     continue
    866                 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])
    867                 if not RegionSizeGuid:
    868                     RegionLayoutLine = self.CurrentLineNumber + 1
    869                     continue
    870                 self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
    871                 self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
    872                 RegionLayoutLine = self.CurrentLineNumber + 1
    873 
    874         if IfList:
    875             raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
    876         self.Rewind()
    877 
    878     def __CollectMacroPcd(self):
    879         MacroDict = {}
    880 
    881         # PCD macro

    882         MacroDict.update(GlobalData.gPlatformPcds)
    883         MacroDict.update(self.__PcdDict)
    884 
    885         # Lowest priority

    886         MacroDict.update(GlobalData.gPlatformDefines)
    887 
    888         if self.__CurSection:
    889             # Defines macro

    890             ScopeMacro = self.__MacroDict['COMMON', 'COMMON', 'COMMON']
    891             if ScopeMacro:
    892                 MacroDict.update(ScopeMacro)
    893     
    894             # Section macro

    895             ScopeMacro = self.__MacroDict[
    896                         self.__CurSection[0],
    897                         self.__CurSection[1],
    898                         self.__CurSection[2]
    899             ]
    900             if ScopeMacro:
    901                 MacroDict.update(ScopeMacro)
    902 
    903         MacroDict.update(GlobalData.gGlobalDefines)
    904         MacroDict.update(GlobalData.gCommandLineDefines)
    905         # Highest priority

    906 
    907         return MacroDict
    908 
    909     def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):
    910         FileLineTuple = GetRealFileLine(self.FileName, Line)
    911         MacroPcdDict = self.__CollectMacroPcd()
    912         if Op == 'eval':
    913             try:
    914                 if Value:
    915                     return ValueExpression(Expression, MacroPcdDict)(True)
    916                 else:
    917                     return ValueExpression(Expression, MacroPcdDict)()
    918             except WrnExpression, Excpt:
    919                 # 

    920                 # Catch expression evaluation warning here. We need to report

    921                 # the precise number of line and return the evaluation result

    922                 #

    923                 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
    924                                 File=self.FileName, ExtraData=self.__CurrentLine(), 
    925                                 Line=Line)
    926                 return Excpt.result
    927             except Exception, Excpt:
    928                 if hasattr(Excpt, 'Pcd'):
    929                     if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
    930                         Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]
    931                         raise Warning("Cannot use this PCD (%s) in an expression as"
    932                                       " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
    933                                       " of the DSC file (%s), and it is currently defined in this section:"
    934                                       " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),
    935                                       *FileLineTuple)
    936                     else:
    937                         raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),
    938                                       *FileLineTuple)
    939                 else:
    940                     raise Warning(str(Excpt), *FileLineTuple)
    941         else:
    942             if Expression.startswith('$(') and Expression[-1] == ')':
    943                 Expression = Expression[2:-1]            
    944             return Expression in MacroPcdDict
    945 
    946     ## __IsToken() method

    947     #

    948     #   Check whether input string is found from current char position along

    949     #   If found, the string value is put into self.__Token

    950     #

    951     #   @param  self        The object pointer

    952     #   @param  String      The string to search

    953     #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive

    954     #   @retval True        Successfully find string, file buffer pointer moved forward

    955     #   @retval False       Not able to find string, file buffer pointer not changed

    956     #

    957     def __IsToken(self, String, IgnoreCase = False):
    958         self.__SkipWhiteSpace()
    959 
    960         # Only consider the same line, no multi-line token allowed

    961         StartPos = self.CurrentOffsetWithinLine
    962         index = -1
    963         if IgnoreCase:
    964             index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
    965         else:
    966             index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
    967         if index == 0:
    968             self.CurrentOffsetWithinLine += len(String)
    969             self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
    970             return True
    971         return False
    972 
    973     ## __IsKeyword() method

    974     #

    975     #   Check whether input keyword is found from current char position along, whole word only!

    976     #   If found, the string value is put into self.__Token

    977     #

    978     #   @param  self        The object pointer

    979     #   @param  Keyword     The string to search

    980     #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive

    981     #   @retval True        Successfully find string, file buffer pointer moved forward

    982     #   @retval False       Not able to find string, file buffer pointer not changed

    983     #

    984     def __IsKeyword(self, KeyWord, IgnoreCase = False):
    985         self.__SkipWhiteSpace()
    986 
    987         # Only consider the same line, no multi-line token allowed

    988         StartPos = self.CurrentOffsetWithinLine
    989         index = -1
    990         if IgnoreCase:
    991             index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())
    992         else:
    993             index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)
    994         if index == 0:
    995             followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
    996             if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:
    997                 return False
    998             self.CurrentOffsetWithinLine += len(KeyWord)
    999             self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
   1000             return True
   1001         return False
   1002 
   1003     def __GetExpression(self):
   1004         Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
   1005         Index = len(Line) - 1
   1006         while Line[Index] in ['\r', '\n']:
   1007             Index -= 1
   1008         ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]
   1009         self.CurrentOffsetWithinLine += len(ExpressionString)
   1010         ExpressionString = ExpressionString.strip()
   1011         return ExpressionString
   1012 
   1013     ## __GetNextWord() method

   1014     #

   1015     #   Get next C name from file lines

   1016     #   If found, the string value is put into self.__Token

   1017     #

   1018     #   @param  self        The object pointer

   1019     #   @retval True        Successfully find a C name string, file buffer pointer moved forward

   1020     #   @retval False       Not able to find a C name string, file buffer pointer not changed

   1021     #

   1022     def __GetNextWord(self):
   1023         self.__SkipWhiteSpace()
   1024         if self.__EndOfFile():
   1025             return False
   1026 
   1027         TempChar = self.__CurrentChar()
   1028         StartPos = self.CurrentOffsetWithinLine
   1029         if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
   1030             self.__GetOneChar()
   1031             while not self.__EndOfLine():
   1032                 TempChar = self.__CurrentChar()
   1033                 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
   1034                 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
   1035                     self.__GetOneChar()
   1036 
   1037                 else:
   1038                     break
   1039 
   1040             self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
   1041             return True
   1042 
   1043         return False
   1044 
   1045     ## __GetNextToken() method

   1046     #

   1047     #   Get next token unit before a seperator

   1048     #   If found, the string value is put into self.__Token

   1049     #

   1050     #   @param  self        The object pointer

   1051     #   @retval True        Successfully find a token unit, file buffer pointer moved forward

   1052     #   @retval False       Not able to find a token unit, file buffer pointer not changed

   1053     #

   1054     def __GetNextToken(self):
   1055         # Skip leading spaces, if exist.

   1056         self.__SkipWhiteSpace()
   1057         if self.__EndOfFile():
   1058             return False
   1059         # Record the token start position, the position of the first non-space char.

   1060         StartPos = self.CurrentOffsetWithinLine
   1061         StartLine = self.CurrentLineNumber
   1062         while StartLine == self.CurrentLineNumber:
   1063             TempChar = self.__CurrentChar()
   1064             # Try to find the end char that is not a space and not in seperator tuple.

   1065             # That is, when we got a space or any char in the tuple, we got the end of token.

   1066             if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:
   1067                 self.__GetOneChar()
   1068             # if we happen to meet a seperator as the first char, we must proceed to get it.

   1069             # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.

   1070             elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
   1071                 self.__GetOneChar()
   1072                 break
   1073             else:
   1074                 break
   1075 #        else:

   1076 #            return False

   1077 
   1078         EndPos = self.CurrentOffsetWithinLine
   1079         if self.CurrentLineNumber != StartLine:
   1080             EndPos = len(self.Profile.FileLinesList[StartLine-1])
   1081         self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]
   1082         if StartPos != self.CurrentOffsetWithinLine:
   1083             return True
   1084         else:
   1085             return False
   1086 
   1087     def __GetNextOp(self):
   1088         # Skip leading spaces, if exist.

   1089         self.__SkipWhiteSpace()
   1090         if self.__EndOfFile():
   1091             return False
   1092         # Record the token start position, the position of the first non-space char.

   1093         StartPos = self.CurrentOffsetWithinLine
   1094         while not self.__EndOfLine():
   1095             TempChar = self.__CurrentChar()
   1096             # Try to find the end char that is not a space

   1097             if not str(TempChar).isspace():
   1098                 self.__GetOneChar()
   1099             else:
   1100                 break
   1101         else:
   1102             return False
   1103 
   1104         if StartPos != self.CurrentOffsetWithinLine:
   1105             self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
   1106             return True
   1107         else:
   1108             return False
   1109     ## __GetNextGuid() method

   1110     #

   1111     #   Get next token unit before a seperator

   1112     #   If found, the GUID string is put into self.__Token

   1113     #

   1114     #   @param  self        The object pointer

   1115     #   @retval True        Successfully find a registry format GUID, file buffer pointer moved forward

   1116     #   @retval False       Not able to find a registry format GUID, file buffer pointer not changed

   1117     #

   1118     def __GetNextGuid(self):
   1119 
   1120         if not self.__GetNextToken():
   1121             return False
   1122         p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')
   1123         if p.match(self.__Token) != None:
   1124             return True
   1125         else:
   1126             self.__UndoToken()
   1127             return False
   1128 
   1129     def __Verify(self, Name, Value, Scope):
   1130         if Scope in ['UINT64', 'UINT8']:
   1131             ValueNumber = 0
   1132             try:
   1133                 if Value.upper().startswith('0X'):
   1134                     ValueNumber = int (Value, 16)
   1135                 else:
   1136                     ValueNumber = int (Value)
   1137             except:
   1138                 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)
   1139             if ValueNumber < 0:
   1140                 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)
   1141             if Scope == 'UINT64':
   1142                 if ValueNumber >= 0x10000000000000000:
   1143                     EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)
   1144             if Scope == 'UINT8':
   1145                 if ValueNumber >= 0x100:
   1146                     EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)
   1147             return True
   1148 
   1149     ## __UndoToken() method

   1150     #

   1151     #   Go back one token unit in file buffer

   1152     #

   1153     #   @param  self        The object pointer

   1154     #

   1155     def __UndoToken(self):
   1156         self.__UndoOneChar()
   1157         while self.__CurrentChar().isspace():
   1158             if not self.__UndoOneChar():
   1159                 self.__GetOneChar()
   1160                 return
   1161 
   1162 
   1163         StartPos = self.CurrentOffsetWithinLine
   1164         CurrentLine = self.CurrentLineNumber
   1165         while CurrentLine == self.CurrentLineNumber:
   1166 
   1167             TempChar = self.__CurrentChar()
   1168             # Try to find the end char that is not a space and not in seperator tuple.

   1169             # That is, when we got a space or any char in the tuple, we got the end of token.

   1170             if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:
   1171                 if not self.__UndoOneChar():
   1172                     return
   1173             # if we happen to meet a seperator as the first char, we must proceed to get it.

   1174             # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.

   1175             elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
   1176                 return
   1177             else:
   1178                 break
   1179 
   1180         self.__GetOneChar()
   1181 
   1182     ## __HexDigit() method

   1183     #

   1184     #   Whether char input is a Hex data bit

   1185     #

   1186     #   @param  self        The object pointer

   1187     #   @param  TempChar    The char to test

   1188     #   @retval True        The char is a Hex data bit

   1189     #   @retval False       The char is NOT a Hex data bit

   1190     #

   1191     def __HexDigit(self, TempChar):
   1192         if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \
   1193                 or (TempChar >= '0' and TempChar <= '9'):
   1194                     return True
   1195         else:
   1196             return False
   1197 
   1198     def __IsHex(self, HexStr):
   1199         if not HexStr.upper().startswith("0X"):
   1200             return False
   1201         if len(self.__Token) <= 2:
   1202             return False
   1203         charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]
   1204         if len(charList) == 0:
   1205             return True
   1206         else:
   1207             return False
   1208     ## __GetNextHexNumber() method

   1209     #

   1210     #   Get next HEX data before a seperator

   1211     #   If found, the HEX data is put into self.__Token

   1212     #

   1213     #   @param  self        The object pointer

   1214     #   @retval True        Successfully find a HEX data, file buffer pointer moved forward

   1215     #   @retval False       Not able to find a HEX data, file buffer pointer not changed

   1216     #

   1217     def __GetNextHexNumber(self):
   1218         if not self.__GetNextToken():
   1219             return False
   1220         if self.__IsHex(self.__Token):
   1221             return True
   1222         else:
   1223             self.__UndoToken()
   1224             return False
   1225 
   1226     ## __GetNextDecimalNumber() method

   1227     #

   1228     #   Get next decimal data before a seperator

   1229     #   If found, the decimal data is put into self.__Token

   1230     #

   1231     #   @param  self        The object pointer

   1232     #   @retval True        Successfully find a decimal data, file buffer pointer moved forward

   1233     #   @retval False       Not able to find a decimal data, file buffer pointer not changed

   1234     #

   1235     def __GetNextDecimalNumber(self):
   1236         if not self.__GetNextToken():
   1237             return False
   1238         if self.__Token.isdigit():
   1239             return True
   1240         else:
   1241             self.__UndoToken()
   1242             return False
   1243 
   1244     ## __GetNextPcdName() method

   1245     #

   1246     #   Get next PCD token space C name and PCD C name pair before a seperator

   1247     #   If found, the decimal data is put into self.__Token

   1248     #

   1249     #   @param  self        The object pointer

   1250     #   @retval Tuple       PCD C name and PCD token space C name pair

   1251     #

   1252     def __GetNextPcdName(self):
   1253         if not self.__GetNextWord():
   1254             raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
   1255         pcdTokenSpaceCName = self.__Token
   1256 
   1257         if not self.__IsToken( "."):
   1258             raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
   1259 
   1260         if not self.__GetNextWord():
   1261             raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
   1262         pcdCName = self.__Token
   1263 
   1264         return (pcdCName, pcdTokenSpaceCName)
   1265 
   1266     ## __GetStringData() method

   1267     #

   1268     #   Get string contents quoted in ""

   1269     #   If found, the decimal data is put into self.__Token

   1270     #

   1271     #   @param  self        The object pointer

   1272     #   @retval True        Successfully find a string data, file buffer pointer moved forward

   1273     #   @retval False       Not able to find a string data, file buffer pointer not changed

   1274     #

   1275     def __GetStringData(self):
   1276         if self.__Token.startswith("\"") or self.__Token.startswith("L\""):
   1277             self.__UndoToken()
   1278             self.__SkipToToken("\"")
   1279             currentLineNumber = self.CurrentLineNumber
   1280 
   1281             if not self.__SkipToToken("\""):
   1282                 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)
   1283             if currentLineNumber != self.CurrentLineNumber:
   1284                 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)
   1285             self.__Token = self.__SkippedChars.rstrip('\"')
   1286             return True
   1287 
   1288         elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):
   1289             self.__UndoToken()
   1290             self.__SkipToToken("\'")
   1291             currentLineNumber = self.CurrentLineNumber
   1292 
   1293             if not self.__SkipToToken("\'"):
   1294                 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)
   1295             if currentLineNumber != self.CurrentLineNumber:
   1296                 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)
   1297             self.__Token = self.__SkippedChars.rstrip('\'')
   1298             return True
   1299 
   1300         else:
   1301             return False
   1302 
   1303     ## __SkipToToken() method

   1304     #

   1305     #   Search forward in file buffer for the string

   1306     #   The skipped chars are put into self.__SkippedChars

   1307     #

   1308     #   @param  self        The object pointer

   1309     #   @param  String      The string to search

   1310     #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive

   1311     #   @retval True        Successfully find the string, file buffer pointer moved forward

   1312     #   @retval False       Not able to find the string, file buffer pointer not changed

   1313     #

   1314     def __SkipToToken(self, String, IgnoreCase = False):
   1315         StartPos = self.GetFileBufferPos()
   1316 
   1317         self.__SkippedChars = ""
   1318         while not self.__EndOfFile():
   1319             index = -1
   1320             if IgnoreCase:
   1321                 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
   1322             else:
   1323                 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
   1324             if index == 0:
   1325                 self.CurrentOffsetWithinLine += len(String)
   1326                 self.__SkippedChars += String
   1327                 return True
   1328             self.__SkippedChars += str(self.__CurrentChar())
   1329             self.__GetOneChar()
   1330 
   1331         self.SetFileBufferPos( StartPos)
   1332         self.__SkippedChars = ""
   1333         return False
   1334 
   1335     ## GetFileBufferPos() method

   1336     #

   1337     #   Return the tuple of current line and offset within the line

   1338     #

   1339     #   @param  self        The object pointer

   1340     #   @retval Tuple       Line number and offset pair

   1341     #

   1342     def GetFileBufferPos(self):
   1343         return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
   1344 
   1345     ## SetFileBufferPos() method

   1346     #

   1347     #   Restore the file buffer position

   1348     #

   1349     #   @param  self        The object pointer

   1350     #   @param  Pos         The new file buffer position

   1351     #

   1352     def SetFileBufferPos(self, Pos):
   1353         (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos
   1354 
   1355     ## Preprocess() method

   1356     #

   1357     #   Preprocess comment, conditional directive, include directive, replace macro.

   1358     #   Exception will be raised if syntax error found

   1359     #

   1360     #   @param  self        The object pointer

   1361     #

   1362     def Preprocess(self):
   1363         self.__StringToList()
   1364         self.PreprocessFile()
   1365         self.PreprocessIncludeFile()
   1366         self.__StringToList()
   1367         self.PreprocessFile()
   1368         self.PreprocessConditionalStatement()
   1369         self.__StringToList()
   1370         for Pos in self.__WipeOffArea:
   1371             self.__ReplaceFragment(Pos[0], Pos[1])
   1372         self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
   1373 
   1374         while self.__GetDefines():
   1375             pass
   1376 
   1377     ## ParseFile() method

   1378     #

   1379     #   Parse the file profile buffer to extract fd, fv ... information

   1380     #   Exception will be raised if syntax error found

   1381     #

   1382     #   @param  self        The object pointer

   1383     #

   1384     def ParseFile(self):
   1385 
   1386         try:
   1387             self.Preprocess()
   1388             #

   1389             # Keep processing sections of the FDF until no new sections or a syntax error is found

   1390             #

   1391             while self.__GetFd() or self.__GetFv() or self.__GetFmp() or self.__GetCapsule() or self.__GetVtf() or self.__GetRule() or self.__GetOptionRom():
   1392                 pass
   1393 
   1394         except Warning, X:
   1395             self.__UndoToken()
   1396             #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \

   1397             # At this point, the closest parent would be the included file itself

   1398             Profile = GetParentAtLine(X.OriginalLineNumber)
   1399             if Profile != None:
   1400                 X.Message += ' near line %d, column %d: %s' \
   1401                 % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])
   1402             else:
   1403                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1404                 X.Message += ' near line %d, column %d: %s' \
   1405                 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'))
   1406             raise
   1407 
   1408     ## SectionParser() method

   1409     #

   1410     #   Parse the file section info

   1411     #   Exception will be raised if syntax error found

   1412     #

   1413     #   @param  self          The object pointer

   1414     #   @param  section       The section string

   1415 
   1416     def SectionParser(self, section):
   1417         S = section.upper()
   1418         if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
   1419             and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):
   1420             raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber)
   1421 
   1422     ## __GetDefines() method

   1423     #

   1424     #   Get Defines section contents and store its data into AllMacrosList

   1425     #

   1426     #   @param  self        The object pointer

   1427     #   @retval True        Successfully find a Defines

   1428     #   @retval False       Not able to find a Defines

   1429     #

   1430     def __GetDefines(self):
   1431 
   1432         if not self.__GetNextToken():
   1433             return False
   1434 
   1435         S = self.__Token.upper()
   1436         if S.startswith("[") and not S.startswith("[DEFINES"):
   1437             self.SectionParser(S)
   1438             self.__UndoToken()
   1439             return False
   1440 
   1441         self.__UndoToken()
   1442         if not self.__IsToken("[DEFINES", True):
   1443             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1444             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

   1445             #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)

   1446             raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)
   1447 
   1448         if not self.__IsToken( "]"):
   1449             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   1450 
   1451         while self.__GetNextWord():
   1452             # handle the SET statement

   1453             if self.__Token == 'SET':
   1454                 self.__UndoToken()
   1455                 self.__GetSetStatement(None)
   1456                 continue
   1457             
   1458             Macro = self.__Token
   1459             
   1460             if not self.__IsToken("="):
   1461                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1462             if not self.__GetNextToken() or self.__Token.startswith('['):
   1463                 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
   1464             Value = self.__Token
   1465 
   1466         return False
   1467 
   1468     ## __GetFd() method

   1469     #

   1470     #   Get FD section contents and store its data into FD dictionary of self.Profile

   1471     #

   1472     #   @param  self        The object pointer

   1473     #   @retval True        Successfully find a FD

   1474     #   @retval False       Not able to find a FD

   1475     #

   1476     def __GetFd(self):
   1477 
   1478         if not self.__GetNextToken():
   1479             return False
   1480 
   1481         S = self.__Token.upper()
   1482         if S.startswith("[") and not S.startswith("[FD."):
   1483             if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
   1484                 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
   1485                 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
   1486             self.__UndoToken()
   1487             return False
   1488 
   1489         self.__UndoToken()
   1490         if not self.__IsToken("[FD.", True):
   1491             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1492             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

   1493             #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)

   1494             raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)
   1495 
   1496         FdName = self.__GetUiName()
   1497         if FdName == "":
   1498             if len (self.Profile.FdDict) == 0:
   1499                 FdName = GenFdsGlobalVariable.PlatformName
   1500                 if FdName == "" and GlobalData.gActivePlatform:
   1501                     FdName = GlobalData.gActivePlatform.PlatformName
   1502                 self.Profile.FdNameNotSet = True
   1503             else:
   1504                 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)
   1505         self.CurrentFdName = FdName.upper()
   1506         
   1507         if self.CurrentFdName in self.Profile.FdDict:
   1508             raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)
   1509 
   1510         if not self.__IsToken( "]"):
   1511             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   1512 
   1513         FdObj = Fd.FD()
   1514         FdObj.FdUiName = self.CurrentFdName
   1515         self.Profile.FdDict[self.CurrentFdName] = FdObj
   1516 
   1517         if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:
   1518             raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)
   1519 
   1520         Status = self.__GetCreateFile(FdObj)
   1521         if not Status:
   1522             raise Warning("FD name error", self.FileName, self.CurrentLineNumber)
   1523 
   1524         while self.__GetTokenStatements(FdObj):
   1525             pass
   1526         for Attr in ("BaseAddress", "Size", "ErasePolarity"):
   1527             if getattr(FdObj, Attr) == None:
   1528                 self.__GetNextToken()
   1529                 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)
   1530 
   1531         if not FdObj.BlockSizeList:
   1532             FdObj.BlockSizeList.append((1, FdObj.Size, None))
   1533 
   1534         self.__GetDefineStatements(FdObj)
   1535 
   1536         self.__GetSetStatements(FdObj)
   1537 
   1538         if not self.__GetRegionLayout(FdObj):
   1539             raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)
   1540 
   1541         while self.__GetRegionLayout(FdObj):
   1542             pass
   1543         return True
   1544 
   1545     ## __GetUiName() method

   1546     #

   1547     #   Return the UI name of a section

   1548     #

   1549     #   @param  self        The object pointer

   1550     #   @retval FdName      UI name

   1551     #

   1552     def __GetUiName(self):
   1553         Name = ""
   1554         if self.__GetNextWord():
   1555             Name = self.__Token
   1556 
   1557         return Name
   1558 
   1559     ## __GetCreateFile() method

   1560     #

   1561     #   Return the output file name of object

   1562     #

   1563     #   @param  self        The object pointer

   1564     #   @param  Obj         object whose data will be stored in file

   1565     #   @retval FdName      UI name

   1566     #

   1567     def __GetCreateFile(self, Obj):
   1568 
   1569         if self.__IsKeyword( "CREATE_FILE"):
   1570             if not self.__IsToken( "="):
   1571                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1572 
   1573             if not self.__GetNextToken():
   1574                 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
   1575 
   1576             FileName = self.__Token
   1577             Obj.CreateFileName = FileName
   1578 
   1579         return True
   1580 
   1581     ## __GetTokenStatements() method

   1582     #

   1583     #   Get token statements

   1584     #

   1585     #   @param  self        The object pointer

   1586     #   @param  Obj         for whom token statement is got

   1587     #

   1588     def __GetTokenStatements(self, Obj):
   1589         if self.__IsKeyword( "BaseAddress"):
   1590             if not self.__IsToken( "="):
   1591                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1592     
   1593             if not self.__GetNextHexNumber():
   1594                 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
   1595     
   1596             Obj.BaseAddress = self.__Token
   1597     
   1598             if self.__IsToken( "|"):
   1599                 pcdPair = self.__GetNextPcdName()
   1600                 Obj.BaseAddressPcd = pcdPair
   1601                 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
   1602                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1603                 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
   1604             return True
   1605 
   1606         if self.__IsKeyword( "Size"):
   1607             if not self.__IsToken( "="):
   1608                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1609     
   1610             if not self.__GetNextHexNumber():
   1611                 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
   1612 
   1613             Size = self.__Token
   1614             if self.__IsToken( "|"):
   1615                 pcdPair = self.__GetNextPcdName()
   1616                 Obj.SizePcd = pcdPair
   1617                 self.Profile.PcdDict[pcdPair] = Size
   1618                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1619                 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
   1620             Obj.Size = long(Size, 0)
   1621             return True
   1622 
   1623         if self.__IsKeyword( "ErasePolarity"):
   1624             if not self.__IsToken( "="):
   1625                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1626     
   1627             if not self.__GetNextToken():
   1628                 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
   1629     
   1630             if self.__Token != "1" and self.__Token != "0":
   1631                 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
   1632     
   1633             Obj.ErasePolarity = self.__Token
   1634             return True
   1635 
   1636         return self.__GetBlockStatements(Obj)
   1637 
   1638     ## __GetAddressStatements() method

   1639     #

   1640     #   Get address statements

   1641     #

   1642     #   @param  self        The object pointer

   1643     #   @param  Obj         for whom address statement is got

   1644     #   @retval True        Successfully find

   1645     #   @retval False       Not able to find

   1646     #

   1647     def __GetAddressStatements(self, Obj):
   1648 
   1649         if self.__IsKeyword("BsBaseAddress"):
   1650             if not self.__IsToken( "="):
   1651                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1652 
   1653             if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
   1654                 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
   1655 
   1656             BsAddress = long(self.__Token, 0)
   1657             Obj.BsBaseAddress = BsAddress
   1658 
   1659         if self.__IsKeyword("RtBaseAddress"):
   1660             if not self.__IsToken( "="):
   1661                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1662 
   1663             if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
   1664                 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
   1665 
   1666             RtAddress = long(self.__Token, 0)
   1667             Obj.RtBaseAddress = RtAddress
   1668 
   1669     ## __GetBlockStatements() method

   1670     #

   1671     #   Get block statements

   1672     #

   1673     #   @param  self        The object pointer

   1674     #   @param  Obj         for whom block statement is got

   1675     #

   1676     def __GetBlockStatements(self, Obj):
   1677         IsBlock = False
   1678         while self.__GetBlockStatement(Obj):
   1679             IsBlock = True
   1680         
   1681             Item = Obj.BlockSizeList[-1]
   1682             if Item[0] == None or Item[1] == None:
   1683                 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)
   1684         return IsBlock
   1685 
   1686     ## __GetBlockStatement() method

   1687     #

   1688     #   Get block statement

   1689     #

   1690     #   @param  self        The object pointer

   1691     #   @param  Obj         for whom block statement is got

   1692     #   @retval True        Successfully find

   1693     #   @retval False       Not able to find

   1694     #

   1695     def __GetBlockStatement(self, Obj):
   1696         if not self.__IsKeyword( "BlockSize"):
   1697             return False
   1698 
   1699         if not self.__IsToken( "="):
   1700             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1701 
   1702         if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
   1703             raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)
   1704 
   1705         BlockSize = self.__Token
   1706         BlockSizePcd = None
   1707         if self.__IsToken( "|"):
   1708             PcdPair = self.__GetNextPcdName()
   1709             BlockSizePcd = PcdPair
   1710             self.Profile.PcdDict[PcdPair] = BlockSize
   1711             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1712             self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
   1713         BlockSize = long(BlockSize, 0)
   1714 
   1715         BlockNumber = None
   1716         if self.__IsKeyword( "NumBlocks"):
   1717             if not self.__IsToken( "="):
   1718                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1719 
   1720             if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
   1721                 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)
   1722 
   1723             BlockNumber = long(self.__Token, 0)
   1724 
   1725         Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
   1726         return True
   1727 
   1728     ## __GetDefineStatements() method

   1729     #

   1730     #   Get define statements

   1731     #

   1732     #   @param  self        The object pointer

   1733     #   @param  Obj         for whom define statement is got

   1734     #   @retval True        Successfully find

   1735     #   @retval False       Not able to find

   1736     #

   1737     def __GetDefineStatements(self, Obj):
   1738         while self.__GetDefineStatement( Obj):
   1739             pass
   1740 
   1741     ## __GetDefineStatement() method

   1742     #

   1743     #   Get define statement

   1744     #

   1745     #   @param  self        The object pointer

   1746     #   @param  Obj         for whom define statement is got

   1747     #   @retval True        Successfully find

   1748     #   @retval False       Not able to find

   1749     #

   1750     def __GetDefineStatement(self, Obj):
   1751         if self.__IsKeyword("DEFINE"):
   1752             self.__GetNextToken()
   1753             Macro = self.__Token
   1754             if not self.__IsToken( "="):
   1755                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1756 
   1757             if not self.__GetNextToken():
   1758                 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
   1759 
   1760             Value = self.__Token
   1761             Macro = '$(' + Macro + ')'
   1762             Obj.DefineVarDict[Macro] = Value
   1763             return True
   1764 
   1765         return False
   1766 
   1767     ## __GetSetStatements() method

   1768     #

   1769     #   Get set statements

   1770     #

   1771     #   @param  self        The object pointer

   1772     #   @param  Obj         for whom set statement is got

   1773     #   @retval True        Successfully find

   1774     #   @retval False       Not able to find

   1775     #

   1776     def __GetSetStatements(self, Obj):
   1777         while self.__GetSetStatement(Obj):
   1778             pass
   1779 
   1780     ## __GetSetStatement() method

   1781     #

   1782     #   Get set statement

   1783     #

   1784     #   @param  self        The object pointer

   1785     #   @param  Obj         for whom set statement is got

   1786     #   @retval True        Successfully find

   1787     #   @retval False       Not able to find

   1788     #

   1789     def __GetSetStatement(self, Obj):
   1790         if self.__IsKeyword("SET"):
   1791             PcdPair = self.__GetNextPcdName()
   1792 
   1793             if not self.__IsToken( "="):
   1794                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1795 
   1796             Value = self.__GetExpression()
   1797             Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
   1798 
   1799             if Obj:
   1800                 Obj.SetVarDict[PcdPair] = Value
   1801             self.Profile.PcdDict[PcdPair] = Value
   1802             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1803             self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
   1804             return True
   1805 
   1806         return False
   1807 
   1808     ## __CalcRegionExpr(self)

   1809     #

   1810     #   Calculate expression for offset or size of a region

   1811     #

   1812     #   @return: None if invalid expression

   1813     #            Calculated number if successfully

   1814     #

   1815     def __CalcRegionExpr(self):
   1816         StartPos = self.GetFileBufferPos()
   1817         Expr = ''
   1818         PairCount = 0
   1819         while not self.__EndOfFile():
   1820             CurCh = self.__CurrentChar()
   1821             if CurCh == '(':
   1822                 PairCount += 1
   1823             elif CurCh == ')':
   1824                 PairCount -= 1
   1825 
   1826             if CurCh in '|\r\n' and PairCount == 0:
   1827                 break
   1828             Expr += CurCh
   1829             self.__GetOneChar()
   1830         try:
   1831             return long(
   1832                 ValueExpression(Expr,
   1833                                 self.__CollectMacroPcd()
   1834                                 )(True),0)
   1835         except Exception:
   1836             self.SetFileBufferPos(StartPos)
   1837             return None
   1838 
   1839     ## __GetRegionLayout() method

   1840     #

   1841     #   Get region layout for FD

   1842     #

   1843     #   @param  self        The object pointer

   1844     #   @param  Fd          for whom region is got

   1845     #   @retval True        Successfully find

   1846     #   @retval False       Not able to find

   1847     #

   1848     def __GetRegionLayout(self, Fd):
   1849         Offset = self.__CalcRegionExpr() 
   1850         if Offset == None:
   1851             return False
   1852 
   1853         RegionObj = Region.Region()
   1854         RegionObj.Offset = Offset
   1855         Fd.RegionList.append(RegionObj)
   1856 
   1857         if not self.__IsToken( "|"):
   1858             raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)
   1859 
   1860         Size = self.__CalcRegionExpr()
   1861         if Size == None:
   1862             raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)
   1863         RegionObj.Size = Size
   1864 
   1865         if not self.__GetNextWord():
   1866             return True
   1867 
   1868         if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
   1869             #

   1870             # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]

   1871             # Or it might be next region's offset described by an expression which starts with a PCD.

   1872             #    PcdOffset[|PcdSize] or OffsetPcdExpression|Size

   1873             #

   1874             self.__UndoToken()
   1875             IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or
   1876                            RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))
   1877             if IsRegionPcd:
   1878                 RegionObj.PcdOffset = self.__GetNextPcdName()
   1879                 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
   1880                 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset
   1881                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1882                 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
   1883                 if self.__IsToken( "|"):
   1884                     RegionObj.PcdSize = self.__GetNextPcdName()
   1885                     self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
   1886                     self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size
   1887                     FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1888                     self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
   1889 
   1890             if not self.__GetNextWord():
   1891                 return True
   1892 
   1893         if self.__Token == "SET":
   1894             self.__UndoToken()
   1895             self.__GetSetStatements( RegionObj)
   1896             if not self.__GetNextWord():
   1897                 return True
   1898 
   1899         elif self.__Token == "FV":
   1900             self.__UndoToken()
   1901             self.__GetRegionFvType( RegionObj)
   1902 
   1903         elif self.__Token == "CAPSULE":
   1904             self.__UndoToken()
   1905             self.__GetRegionCapType( RegionObj)
   1906 
   1907         elif self.__Token == "FILE":
   1908             self.__UndoToken()
   1909             self.__GetRegionFileType(RegionObj)
   1910 
   1911         elif self.__Token == "INF":
   1912             self.__UndoToken()
   1913             RegionObj.RegionType = "INF"
   1914             while self.__IsKeyword("INF"):
   1915                 self.__UndoToken()
   1916                 ffsInf = self.__ParseInfStatement()
   1917                 if not ffsInf:
   1918                     break
   1919                 RegionObj.RegionDataList.append(ffsInf)
   1920 
   1921         elif self.__Token == "DATA":
   1922             self.__UndoToken()
   1923             self.__GetRegionDataType(RegionObj)
   1924         else:
   1925             self.__UndoToken()
   1926             if self.__GetRegionLayout(Fd):
   1927                 return True
   1928             raise Warning("A valid region type was not found. "
   1929                           "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
   1930                           self.FileName, self.CurrentLineNumber)
   1931 
   1932         return True
   1933 
   1934     ## __GetRegionFvType() method

   1935     #

   1936     #   Get region fv data for region

   1937     #

   1938     #   @param  self        The object pointer

   1939     #   @param  RegionObj   for whom region data is got

   1940     #

   1941     def __GetRegionFvType(self, RegionObj):
   1942 
   1943         if not self.__IsKeyword( "FV"):
   1944             raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)
   1945 
   1946         if not self.__IsToken( "="):
   1947             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1948 
   1949         if not self.__GetNextToken():
   1950             raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
   1951 
   1952         RegionObj.RegionType = "FV"
   1953         RegionObj.RegionDataList.append((self.__Token).upper())
   1954 
   1955         while self.__IsKeyword( "FV"):
   1956 
   1957             if not self.__IsToken( "="):
   1958                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1959 
   1960             if not self.__GetNextToken():
   1961                 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
   1962 
   1963             RegionObj.RegionDataList.append((self.__Token).upper())
   1964 
   1965     ## __GetRegionCapType() method

   1966     #

   1967     #   Get region capsule data for region

   1968     #

   1969     #   @param  self        The object pointer

   1970     #   @param  RegionObj   for whom region data is got

   1971     #

   1972     def __GetRegionCapType(self, RegionObj):
   1973 
   1974         if not self.__IsKeyword("CAPSULE"):
   1975             raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)
   1976 
   1977         if not self.__IsToken("="):
   1978             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1979 
   1980         if not self.__GetNextToken():
   1981             raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
   1982 
   1983         RegionObj.RegionType = "CAPSULE"
   1984         RegionObj.RegionDataList.append(self.__Token)
   1985 
   1986         while self.__IsKeyword("CAPSULE"):
   1987 
   1988             if not self.__IsToken("="):
   1989                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1990 
   1991             if not self.__GetNextToken():
   1992                 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
   1993 
   1994             RegionObj.RegionDataList.append(self.__Token)
   1995 
   1996     ## __GetRegionFileType() method

   1997     #

   1998     #   Get region file data for region

   1999     #

   2000     #   @param  self        The object pointer

   2001     #   @param  RegionObj   for whom region data is got

   2002     #

   2003     def __GetRegionFileType(self, RegionObj):
   2004 
   2005         if not self.__IsKeyword( "FILE"):
   2006             raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)
   2007 
   2008         if not self.__IsToken( "="):
   2009             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2010 
   2011         if not self.__GetNextToken():
   2012             raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
   2013 
   2014         RegionObj.RegionType = "FILE"
   2015         RegionObj.RegionDataList.append( self.__Token)
   2016 
   2017         while self.__IsKeyword( "FILE"):
   2018 
   2019             if not self.__IsToken( "="):
   2020                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2021 
   2022             if not self.__GetNextToken():
   2023                 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)
   2024 
   2025             RegionObj.RegionDataList.append(self.__Token)
   2026 
   2027     ## __GetRegionDataType() method

   2028     #

   2029     #   Get region array data for region

   2030     #

   2031     #   @param  self        The object pointer

   2032     #   @param  RegionObj   for whom region data is got

   2033     #

   2034     def __GetRegionDataType(self, RegionObj):
   2035 
   2036         if not self.__IsKeyword( "DATA"):
   2037             raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)
   2038 
   2039         if not self.__IsToken( "="):
   2040             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2041 
   2042         if not self.__IsToken( "{"):
   2043             raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2044 
   2045         if not self.__GetNextHexNumber():
   2046             raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
   2047 
   2048         if len(self.__Token) > 18:
   2049             raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
   2050 
   2051         # convert hex string value to byte hex string array

   2052         AllString = self.__Token
   2053         AllStrLen = len (AllString)
   2054         DataString = ""
   2055         while AllStrLen > 4:
   2056             DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
   2057             AllStrLen  = AllStrLen - 2
   2058         DataString = DataString + AllString[:AllStrLen] + ","
   2059 
   2060         # byte value array

   2061         if len (self.__Token) <= 4:
   2062             while self.__IsToken(","):
   2063                 if not self.__GetNextHexNumber():
   2064                     raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
   2065                 if len(self.__Token) > 4:
   2066                     raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
   2067                 DataString += self.__Token
   2068                 DataString += ","
   2069 
   2070         if not self.__IsToken( "}"):
   2071             raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2072 
   2073         DataString = DataString.rstrip(",")
   2074         RegionObj.RegionType = "DATA"
   2075         RegionObj.RegionDataList.append( DataString)
   2076 
   2077         while self.__IsKeyword( "DATA"):
   2078 
   2079             if not self.__IsToken( "="):
   2080                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2081 
   2082             if not self.__IsToken( "{"):
   2083                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2084 
   2085             if not self.__GetNextHexNumber():
   2086                 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
   2087 
   2088             if len(self.__Token) > 18:
   2089                 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
   2090 
   2091             # convert hex string value to byte hex string array

   2092             AllString = self.__Token
   2093             AllStrLen = len (AllString)
   2094             DataString = ""
   2095             while AllStrLen > 4:
   2096                 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
   2097                 AllStrLen  = AllStrLen - 2
   2098             DataString = DataString + AllString[:AllStrLen] + ","
   2099 
   2100             # byte value array

   2101             if len (self.__Token) <= 4:
   2102                 while self.__IsToken(","):
   2103                     if not self.__GetNextHexNumber():
   2104                         raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
   2105                     if len(self.__Token) > 4:
   2106                         raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
   2107                     DataString += self.__Token
   2108                     DataString += ","
   2109 
   2110             if not self.__IsToken( "}"):
   2111                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2112 
   2113             DataString = DataString.rstrip(",")
   2114             RegionObj.RegionDataList.append( DataString)
   2115 
   2116     ## __GetFv() method

   2117     #

   2118     #   Get FV section contents and store its data into FV dictionary of self.Profile

   2119     #

   2120     #   @param  self        The object pointer

   2121     #   @retval True        Successfully find a FV

   2122     #   @retval False       Not able to find a FV

   2123     #

   2124     def __GetFv(self):
   2125         if not self.__GetNextToken():
   2126             return False
   2127 
   2128         S = self.__Token.upper()
   2129         if S.startswith("[") and not S.startswith("[FV."):
   2130             self.SectionParser(S)
   2131             self.__UndoToken()
   2132             return False
   2133 
   2134         self.__UndoToken()
   2135         if not self.__IsToken("[FV.", True):
   2136             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   2137             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

   2138             #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)

   2139             raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2140 
   2141         FvName = self.__GetUiName()
   2142         self.CurrentFvName = FvName.upper()
   2143 
   2144         if not self.__IsToken( "]"):
   2145             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   2146 
   2147         FvObj = Fv.FV()
   2148         FvObj.UiFvName = self.CurrentFvName
   2149         self.Profile.FvDict[self.CurrentFvName] = FvObj
   2150 
   2151         Status = self.__GetCreateFile(FvObj)
   2152         if not Status:
   2153             raise Warning("FV name error", self.FileName, self.CurrentLineNumber)
   2154 
   2155         self.__GetDefineStatements(FvObj)
   2156 
   2157         self.__GetAddressStatements(FvObj)
   2158 
   2159         FvObj.FvExtEntryTypeValue = []
   2160         FvObj.FvExtEntryType = []
   2161         FvObj.FvExtEntryData = []
   2162         while True:
   2163             self.__GetSetStatements(FvObj)
   2164 
   2165             if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or 
   2166                 self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or 
   2167                 self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or 
   2168                 self.__GetFvExtEntryStatement(FvObj) or self.__GetFvNameString(FvObj)):
   2169                 break
   2170 
   2171         if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:
   2172             raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)
   2173 
   2174         self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
   2175         self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
   2176 
   2177         while True:
   2178             isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
   2179             isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
   2180             if not isInf and not isFile:
   2181                 break
   2182 
   2183         return True
   2184 
   2185     ## __GetFvAlignment() method

   2186     #

   2187     #   Get alignment for FV

   2188     #

   2189     #   @param  self        The object pointer

   2190     #   @param  Obj         for whom alignment is got

   2191     #   @retval True        Successfully find a alignment statement

   2192     #   @retval False       Not able to find a alignment statement

   2193     #

   2194     def __GetFvAlignment(self, Obj):
   2195 
   2196         if not self.__IsKeyword( "FvAlignment"):
   2197             return False
   2198 
   2199         if not self.__IsToken( "="):
   2200             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2201 
   2202         if not self.__GetNextToken():
   2203             raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
   2204 
   2205         if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
   2206                                         "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
   2207                                         "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
   2208                                         "1G", "2G"):
   2209             raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2210         Obj.FvAlignment = self.__Token
   2211         return True
   2212     
   2213     ## __GetFvBaseAddress() method

   2214     #

   2215     #   Get BaseAddress for FV

   2216     #

   2217     #   @param  self        The object pointer

   2218     #   @param  Obj         for whom FvBaseAddress is got

   2219     #   @retval True        Successfully find a FvBaseAddress statement

   2220     #   @retval False       Not able to find a FvBaseAddress statement

   2221     #

   2222     def __GetFvBaseAddress(self, Obj):
   2223 
   2224         if not self.__IsKeyword("FvBaseAddress"):
   2225             return False
   2226 
   2227         if not self.__IsToken( "="):
   2228             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2229 
   2230         if not self.__GetNextToken():
   2231             raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)
   2232 
   2233         IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')
   2234 
   2235         if not IsValidBaseAddrValue.match(self.__Token.upper()):
   2236             raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2237         Obj.FvBaseAddress = self.__Token
   2238         return True  
   2239       
   2240     ## __GetFvForceRebase() method

   2241     #

   2242     #   Get FvForceRebase for FV

   2243     #

   2244     #   @param  self        The object pointer

   2245     #   @param  Obj         for whom FvForceRebase is got

   2246     #   @retval True        Successfully find a FvForceRebase statement

   2247     #   @retval False       Not able to find a FvForceRebase statement

   2248     #

   2249     def __GetFvForceRebase(self, Obj):
   2250 
   2251         if not self.__IsKeyword("FvForceRebase"):
   2252             return False
   2253 
   2254         if not self.__IsToken( "="):
   2255             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2256 
   2257         if not self.__GetNextToken():
   2258             raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)
   2259 
   2260         if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
   2261             raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2262         
   2263         if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:
   2264             Obj.FvForceRebase = True
   2265         elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:
   2266             Obj.FvForceRebase = False
   2267         else:
   2268             Obj.FvForceRebase = None
   2269            
   2270         return True
   2271 
   2272 
   2273     ## __GetFvAttributes() method

   2274     #

   2275     #   Get attributes for FV

   2276     #

   2277     #   @param  self        The object pointer

   2278     #   @param  Obj         for whom attribute is got

   2279     #   @retval None

   2280     #

   2281     def __GetFvAttributes(self, FvObj):
   2282         IsWordToken = False
   2283         while self.__GetNextWord():
   2284             IsWordToken = True
   2285             name = self.__Token
   2286             if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
   2287                            "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
   2288                            "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
   2289                            "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
   2290                            "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
   2291                            "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):
   2292                 self.__UndoToken()
   2293                 return False
   2294 
   2295             if not self.__IsToken( "="):
   2296                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2297 
   2298             if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
   2299                 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
   2300 
   2301             FvObj.FvAttributeDict[name] = self.__Token
   2302 
   2303         return IsWordToken
   2304     
   2305     ## __GetFvNameGuid() method

   2306     #

   2307     #   Get FV GUID for FV

   2308     #

   2309     #   @param  self        The object pointer

   2310     #   @param  Obj         for whom GUID is got

   2311     #   @retval None

   2312     #

   2313     def __GetFvNameGuid(self, FvObj):
   2314 
   2315         if not self.__IsKeyword( "FvNameGuid"):
   2316             return False
   2317 
   2318         if not self.__IsToken( "="):
   2319             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2320 
   2321         if not self.__GetNextGuid():
   2322             raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)
   2323 
   2324         FvObj.FvNameGuid = self.__Token
   2325 
   2326         return True
   2327 
   2328     def __GetFvNameString(self, FvObj):
   2329 
   2330         if not self.__IsKeyword( "FvNameString"):
   2331             return False
   2332 
   2333         if not self.__IsToken( "="):
   2334             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2335 
   2336         if not self.__GetNextToken() or self.__Token not in ('TRUE', 'FALSE'):
   2337             raise Warning("expected TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)
   2338 
   2339         FvObj.FvNameString = self.__Token
   2340 
   2341         return True
   2342 
   2343     def __GetFvExtEntryStatement(self, FvObj):
   2344 
   2345         if not self.__IsKeyword( "FV_EXT_ENTRY"):
   2346             return False
   2347 
   2348         if not self.__IsKeyword ("TYPE"):
   2349             raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)
   2350             
   2351         if not self.__IsToken( "="):
   2352             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2353 
   2354         if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
   2355             raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)
   2356 
   2357         FvObj.FvExtEntryTypeValue += [self.__Token]
   2358 
   2359         if not self.__IsToken( "{"):
   2360             raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2361 
   2362         if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):
   2363             raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)
   2364 
   2365         FvObj.FvExtEntryType += [self.__Token]
   2366 
   2367         if self.__Token == 'DATA':
   2368 
   2369             if not self.__IsToken( "="):
   2370                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2371                 
   2372             if not self.__IsToken( "{"):
   2373                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2374 
   2375             if not self.__GetNextHexNumber():
   2376                 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
   2377 
   2378             if len(self.__Token) > 4:
   2379                 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
   2380 
   2381             DataString = self.__Token
   2382             DataString += ","
   2383 
   2384             while self.__IsToken(","):
   2385                 if not self.__GetNextHexNumber():
   2386                     raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
   2387                 if len(self.__Token) > 4:
   2388                     raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
   2389                 DataString += self.__Token
   2390                 DataString += ","
   2391 
   2392             if not self.__IsToken( "}"):
   2393                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2394 
   2395             if not self.__IsToken( "}"):
   2396                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2397 
   2398             DataString = DataString.rstrip(",")
   2399             FvObj.FvExtEntryData += [DataString]
   2400 
   2401         if self.__Token == 'FILE':
   2402         
   2403             if not self.__IsToken( "="):
   2404                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2405                 
   2406             if not self.__GetNextToken():
   2407                 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)
   2408                 
   2409             FvObj.FvExtEntryData += [self.__Token]
   2410 
   2411             if not self.__IsToken( "}"):
   2412                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2413 
   2414         return True
   2415 
   2416     ## __GetAprioriSection() method

   2417     #

   2418     #   Get token statements

   2419     #

   2420     #   @param  self        The object pointer

   2421     #   @param  FvObj       for whom apriori is got

   2422     #   @param  MacroDict   dictionary used to replace macro

   2423     #   @retval True        Successfully find apriori statement

   2424     #   @retval False       Not able to find apriori statement

   2425     #

   2426     def __GetAprioriSection(self, FvObj, MacroDict = {}):
   2427 
   2428         if not self.__IsKeyword( "APRIORI"):
   2429             return False
   2430 
   2431         if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):
   2432             raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)
   2433         AprType = self.__Token
   2434 
   2435         if not self.__IsToken( "{"):
   2436             raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2437 
   2438         AprSectionObj = AprioriSection.AprioriSection()
   2439         AprSectionObj.AprioriType = AprType
   2440 
   2441         self.__GetDefineStatements(AprSectionObj)
   2442         MacroDict.update(AprSectionObj.DefineVarDict)
   2443 
   2444         while True:
   2445             IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)
   2446             IsFile = self.__GetFileStatement( AprSectionObj)
   2447             if not IsInf and not IsFile:
   2448                 break
   2449 
   2450         if not self.__IsToken( "}"):
   2451             raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2452 
   2453         FvObj.AprioriSectionList.append(AprSectionObj)
   2454         return True
   2455 
   2456     def __ParseInfStatement(self):
   2457         if not self.__IsKeyword("INF"):
   2458             return None
   2459 
   2460         ffsInf = FfsInfStatement.FfsInfStatement()
   2461         self.__GetInfOptions(ffsInf)
   2462 
   2463         if not self.__GetNextToken():
   2464             raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
   2465         ffsInf.InfFileName = self.__Token
   2466 
   2467         ffsInf.CurrentLineNum = self.CurrentLineNumber
   2468         ffsInf.CurrentLineContent = self.__CurrentLine()
   2469 
   2470         #Replace $(SAPCE) with real space

   2471         ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')
   2472 
   2473         if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
   2474             #do case sensitive check for file path

   2475             ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   2476             if ErrorCode != 0:
   2477                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   2478 
   2479         if not ffsInf.InfFileName in self.Profile.InfList:
   2480             self.Profile.InfList.append(ffsInf.InfFileName)
   2481             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   2482             self.Profile.InfFileLineList.append(FileLineTuple)
   2483             if ffsInf.UseArch:
   2484                 if ffsInf.UseArch not in self.Profile.InfDict:
   2485                     self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
   2486                 else:
   2487                     self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
   2488             else:
   2489                 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)
   2490 
   2491         if self.__IsToken('|'):
   2492             if self.__IsKeyword('RELOCS_STRIPPED'):
   2493                 ffsInf.KeepReloc = False
   2494             elif self.__IsKeyword('RELOCS_RETAINED'):
   2495                 ffsInf.KeepReloc = True
   2496             else:
   2497                 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2498         return ffsInf
   2499 
   2500     ## __GetInfStatement() method

   2501     #

   2502     #   Get INF statements

   2503     #

   2504     #   @param  self        The object pointer

   2505     #   @param  Obj         for whom inf statement is got

   2506     #   @param  MacroDict   dictionary used to replace macro

   2507     #   @retval True        Successfully find inf statement

   2508     #   @retval False       Not able to find inf statement

   2509     #

   2510     def __GetInfStatement(self, Obj, ForCapsule=False, MacroDict={}):
   2511         ffsInf = self.__ParseInfStatement()
   2512         if not ffsInf:
   2513             return False
   2514 
   2515         if ForCapsule:
   2516             capsuleFfs = CapsuleData.CapsuleFfs()
   2517             capsuleFfs.Ffs = ffsInf
   2518             Obj.CapsuleDataList.append(capsuleFfs)
   2519         else:
   2520             Obj.FfsList.append(ffsInf)
   2521         return True
   2522 
   2523     ## __GetInfOptions() method

   2524     #

   2525     #   Get options for INF

   2526     #

   2527     #   @param  self        The object pointer

   2528     #   @param  FfsInfObj   for whom option is got

   2529     #

   2530     def __GetInfOptions(self, FfsInfObj):
   2531         if self.__IsKeyword("FILE_GUID"):
   2532             if not self.__IsToken("="):
   2533                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2534             if not self.__GetNextGuid():
   2535                 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)
   2536             FfsInfObj.OverrideGuid = self.__Token
   2537 
   2538         if self.__IsKeyword( "RuleOverride"):
   2539             if not self.__IsToken( "="):
   2540                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2541             if not self.__GetNextToken():
   2542                 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)
   2543             FfsInfObj.Rule = self.__Token
   2544 
   2545         if self.__IsKeyword( "VERSION"):
   2546             if not self.__IsToken( "="):
   2547                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2548             if not self.__GetNextToken():
   2549                 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)
   2550 
   2551             if self.__GetStringData():
   2552                 FfsInfObj.Version = self.__Token
   2553 
   2554         if self.__IsKeyword( "UI"):
   2555             if not self.__IsToken( "="):
   2556                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2557             if not self.__GetNextToken():
   2558                 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)
   2559 
   2560             if self.__GetStringData():
   2561                 FfsInfObj.Ui = self.__Token
   2562 
   2563         if self.__IsKeyword( "USE"):
   2564             if not self.__IsToken( "="):
   2565                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2566             if not self.__GetNextToken():
   2567                 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)
   2568             FfsInfObj.UseArch = self.__Token
   2569 
   2570                 
   2571         if self.__GetNextToken():
   2572             p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
   2573             if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):
   2574                 FfsInfObj.KeyStringList.append(self.__Token)
   2575                 if not self.__IsToken(","):
   2576                     return
   2577             else:
   2578                 self.__UndoToken()
   2579                 return
   2580 
   2581             while self.__GetNextToken():
   2582                 if not p.match(self.__Token):
   2583                     raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
   2584                 FfsInfObj.KeyStringList.append(self.__Token)
   2585 
   2586                 if not self.__IsToken(","):
   2587                     break
   2588 
   2589     ## __GetFileStatement() method

   2590     #

   2591     #   Get FILE statements

   2592     #

   2593     #   @param  self        The object pointer

   2594     #   @param  Obj         for whom FILE statement is got

   2595     #   @param  MacroDict   dictionary used to replace macro

   2596     #   @retval True        Successfully find FILE statement

   2597     #   @retval False       Not able to find FILE statement

   2598     #

   2599     def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):
   2600 
   2601         if not self.__IsKeyword( "FILE"):
   2602             return False
   2603 
   2604         if not self.__GetNextWord():
   2605             raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
   2606 
   2607         if ForCapsule and self.__Token == 'DATA':
   2608             self.__UndoToken()
   2609             self.__UndoToken()
   2610             return False
   2611         
   2612         FfsFileObj = FfsFileStatement.FileStatement()
   2613         FfsFileObj.FvFileType = self.__Token
   2614 
   2615         if not self.__IsToken( "="):
   2616             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2617 
   2618         if not self.__GetNextGuid():
   2619             if not self.__GetNextWord():
   2620                 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
   2621             if self.__Token == 'PCD':
   2622                 if not self.__IsToken( "("):
   2623                     raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
   2624                 PcdPair = self.__GetNextPcdName()
   2625                 if not self.__IsToken( ")"):
   2626                     raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
   2627                 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
   2628                 
   2629         FfsFileObj.NameGuid = self.__Token
   2630         
   2631         self.__GetFilePart( FfsFileObj, MacroDict.copy())
   2632 
   2633         if ForCapsule:
   2634             capsuleFfs = CapsuleData.CapsuleFfs()
   2635             capsuleFfs.Ffs = FfsFileObj
   2636             Obj.CapsuleDataList.append(capsuleFfs)
   2637         else:
   2638             Obj.FfsList.append(FfsFileObj)
   2639 
   2640         return True
   2641 
   2642     ## __FileCouldHaveRelocFlag() method

   2643     #

   2644     #   Check whether reloc strip flag can be set for a file type.

   2645     #

   2646     #   @param  self        The object pointer

   2647     #   @param  FileType    The file type to check with

   2648     #   @retval True        This type could have relocation strip flag

   2649     #   @retval False       No way to have it

   2650     #

   2651 
   2652     def __FileCouldHaveRelocFlag (self, FileType):
   2653         if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
   2654             return True
   2655         else:
   2656             return False
   2657 
   2658     ## __SectionCouldHaveRelocFlag() method

   2659     #

   2660     #   Check whether reloc strip flag can be set for a section type.

   2661     #

   2662     #   @param  self        The object pointer

   2663     #   @param  SectionType The section type to check with

   2664     #   @retval True        This type could have relocation strip flag

   2665     #   @retval False       No way to have it

   2666     #

   2667 
   2668     def __SectionCouldHaveRelocFlag (self, SectionType):
   2669         if SectionType in ('TE', 'PE32'):
   2670             return True
   2671         else:
   2672             return False
   2673 
   2674     ## __GetFilePart() method

   2675     #

   2676     #   Get components for FILE statement

   2677     #

   2678     #   @param  self        The object pointer

   2679     #   @param  FfsFileObj   for whom component is got

   2680     #   @param  MacroDict   dictionary used to replace macro

   2681     #

   2682     def __GetFilePart(self, FfsFileObj, MacroDict = {}):
   2683 
   2684         self.__GetFileOpts( FfsFileObj)
   2685 
   2686         if not self.__IsToken("{"):
   2687             if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
   2688                 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
   2689                     if self.__Token == 'RELOCS_STRIPPED':
   2690                         FfsFileObj.KeepReloc = False
   2691                     else:
   2692                         FfsFileObj.KeepReloc = True
   2693                 else:
   2694                     raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   2695 
   2696             if not self.__IsToken("{"):
   2697                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2698 
   2699         if not self.__GetNextToken():
   2700             raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)
   2701 
   2702         if self.__Token == "FV":
   2703             if not self.__IsToken( "="):
   2704                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2705             if not self.__GetNextToken():
   2706                 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
   2707             FfsFileObj.FvName = self.__Token
   2708 
   2709         elif self.__Token == "FD":
   2710             if not self.__IsToken( "="):
   2711                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2712             if not self.__GetNextToken():
   2713                 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
   2714             FfsFileObj.FdName = self.__Token
   2715 
   2716         elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):
   2717             self.__UndoToken()
   2718             self.__GetSectionData( FfsFileObj, MacroDict)
   2719 
   2720         elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':
   2721             self.__UndoToken()
   2722             self.__GetRAWData(FfsFileObj, MacroDict)
   2723 
   2724         else:
   2725             FfsFileObj.CurrentLineNum = self.CurrentLineNumber
   2726             FfsFileObj.CurrentLineContent = self.__CurrentLine()
   2727             FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')
   2728             self.__VerifyFile(FfsFileObj.FileName)
   2729 
   2730         if not self.__IsToken( "}"):
   2731             raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2732 
   2733     ## __GetRAWData() method

   2734     #

   2735     #   Get RAW data for FILE statement

   2736     #

   2737     #   @param  self         The object pointer

   2738     #   @param  FfsFileObj   for whom section is got

   2739     #   @param  MacroDict    dictionary used to replace macro

   2740     #

   2741     def __GetRAWData(self, FfsFileObj, MacroDict = {}):
   2742         FfsFileObj.FileName = []
   2743         FfsFileObj.SubAlignment = []
   2744         while True:
   2745             AlignValue = None
   2746             if self.__GetAlignment():
   2747                 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   2748                     raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2749                 #For FFS, Auto is default option same to ""

   2750                 if not self.__Token == "Auto":
   2751                     AlignValue = self.__Token
   2752             if not self.__GetNextToken():
   2753                 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)
   2754 
   2755             FileName = self.__Token.replace('$(SPACE)', ' ')
   2756             if FileName == '}':
   2757                 self.__UndoToken()
   2758                 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)
   2759 
   2760             self.__VerifyFile(FileName)
   2761             File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)
   2762             FfsFileObj.FileName.append(File.Path)
   2763             FfsFileObj.SubAlignment.append(AlignValue)
   2764 
   2765             if self.__IsToken( "}"):
   2766                 self.__UndoToken()
   2767                 break
   2768 
   2769         if len(FfsFileObj.SubAlignment) == 1:
   2770             FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]
   2771         if len(FfsFileObj.FileName) == 1:
   2772             FfsFileObj.FileName = FfsFileObj.FileName[0]
   2773 
   2774     ## __GetFileOpts() method

   2775     #

   2776     #   Get options for FILE statement

   2777     #

   2778     #   @param  self        The object pointer

   2779     #   @param  FfsFileObj   for whom options is got

   2780     #

   2781     def __GetFileOpts(self, FfsFileObj):
   2782 
   2783         if self.__GetNextToken():
   2784             Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
   2785             if Pattern.match(self.__Token):
   2786                 FfsFileObj.KeyStringList.append(self.__Token)
   2787                 if self.__IsToken(","):
   2788                     while self.__GetNextToken():
   2789                         if not Pattern.match(self.__Token):
   2790                             raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
   2791                         FfsFileObj.KeyStringList.append(self.__Token)
   2792 
   2793                         if not self.__IsToken(","):
   2794                             break
   2795 
   2796             else:
   2797                 self.__UndoToken()
   2798 
   2799         if self.__IsKeyword( "FIXED", True):
   2800             FfsFileObj.Fixed = True
   2801 
   2802         if self.__IsKeyword( "CHECKSUM", True):
   2803             FfsFileObj.CheckSum = True
   2804 
   2805         if self.__GetAlignment():
   2806             if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   2807                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2808             #For FFS, Auto is default option same to ""

   2809             if not self.__Token == "Auto":
   2810                 FfsFileObj.Alignment = self.__Token
   2811 
   2812     ## __GetAlignment() method

   2813     #

   2814     #   Return the alignment value

   2815     #

   2816     #   @param  self        The object pointer

   2817     #   @retval True        Successfully find alignment

   2818     #   @retval False       Not able to find alignment

   2819     #

   2820     def __GetAlignment(self):
   2821         if self.__IsKeyword( "Align", True):
   2822             if not self.__IsToken( "="):
   2823                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2824 
   2825             if not self.__GetNextToken():
   2826                 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
   2827             return True
   2828 
   2829         return False
   2830 
   2831     ## __GetFilePart() method

   2832     #

   2833     #   Get section data for FILE statement

   2834     #

   2835     #   @param  self        The object pointer

   2836     #   @param  FfsFileObj   for whom section is got

   2837     #   @param  MacroDict   dictionary used to replace macro

   2838     #

   2839     def __GetSectionData(self, FfsFileObj, MacroDict = {}):
   2840         Dict = {}
   2841         Dict.update(MacroDict)
   2842 
   2843         self.__GetDefineStatements(FfsFileObj)
   2844 
   2845         Dict.update(FfsFileObj.DefineVarDict)
   2846         self.__GetAprioriSection(FfsFileObj, Dict.copy())
   2847         self.__GetAprioriSection(FfsFileObj, Dict.copy())
   2848 
   2849         while True:
   2850             IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)
   2851             IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)
   2852             if not IsLeafSection and not IsEncapSection:
   2853                 break
   2854 
   2855     ## __GetLeafSection() method

   2856     #

   2857     #   Get leaf section for Obj

   2858     #

   2859     #   @param  self        The object pointer

   2860     #   @param  Obj         for whom leaf section is got

   2861     #   @param  MacroDict   dictionary used to replace macro

   2862     #   @retval True        Successfully find section statement

   2863     #   @retval False       Not able to find section statement

   2864     #

   2865     def __GetLeafSection(self, Obj, MacroDict = {}):
   2866 
   2867         OldPos = self.GetFileBufferPos()
   2868 
   2869         if not self.__IsKeyword( "SECTION"):
   2870             if len(Obj.SectionList) == 0:
   2871                 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
   2872             else:
   2873                 return False
   2874 
   2875         AlignValue = None
   2876         if self.__GetAlignment():
   2877             if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   2878                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2879             AlignValue = self.__Token
   2880 
   2881         BuildNum = None
   2882         if self.__IsKeyword( "BUILD_NUM"):
   2883             if not self.__IsToken( "="):
   2884                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2885 
   2886             if not self.__GetNextToken():
   2887                 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)
   2888 
   2889             BuildNum = self.__Token
   2890 
   2891         if self.__IsKeyword( "VERSION"):
   2892             if AlignValue == 'Auto':
   2893                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2894             if not self.__IsToken( "="):
   2895                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2896             if not self.__GetNextToken():
   2897                 raise Warning("expected version", self.FileName, self.CurrentLineNumber)
   2898             VerSectionObj = VerSection.VerSection()
   2899             VerSectionObj.Alignment = AlignValue
   2900             VerSectionObj.BuildNum = BuildNum
   2901             if self.__GetStringData():
   2902                 VerSectionObj.StringData = self.__Token
   2903             else:
   2904                 VerSectionObj.FileName = self.__Token
   2905             Obj.SectionList.append(VerSectionObj)
   2906             
   2907         elif self.__IsKeyword( "UI"):
   2908             if AlignValue == 'Auto':
   2909                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2910             if not self.__IsToken( "="):
   2911                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2912             if not self.__GetNextToken():
   2913                 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)
   2914             UiSectionObj = UiSection.UiSection()
   2915             UiSectionObj.Alignment = AlignValue
   2916             if self.__GetStringData():
   2917                 UiSectionObj.StringData = self.__Token
   2918             else:
   2919                 UiSectionObj.FileName = self.__Token
   2920             Obj.SectionList.append(UiSectionObj)
   2921 
   2922         elif self.__IsKeyword( "FV_IMAGE"):
   2923             if AlignValue == 'Auto':
   2924                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2925             if not self.__IsToken( "="):
   2926                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2927             if not self.__GetNextToken():
   2928                 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)
   2929 
   2930             FvName = self.__Token
   2931             FvObj = None
   2932 
   2933             if self.__IsToken( "{"):
   2934                 FvObj = Fv.FV()
   2935                 FvObj.UiFvName = FvName.upper()
   2936                 self.__GetDefineStatements(FvObj)
   2937                 MacroDict.update(FvObj.DefineVarDict)
   2938                 self.__GetBlockStatement(FvObj)
   2939                 self.__GetSetStatements(FvObj)
   2940                 self.__GetFvAlignment(FvObj)
   2941                 self.__GetFvAttributes(FvObj)
   2942                 self.__GetAprioriSection(FvObj, MacroDict.copy())
   2943                 self.__GetAprioriSection(FvObj, MacroDict.copy())
   2944 
   2945                 while True:
   2946                     IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
   2947                     IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
   2948                     if not IsInf and not IsFile:
   2949                         break
   2950 
   2951                 if not self.__IsToken( "}"):
   2952                     raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2953 
   2954             FvImageSectionObj = FvImageSection.FvImageSection()
   2955             FvImageSectionObj.Alignment = AlignValue
   2956             if FvObj != None:
   2957                 FvImageSectionObj.Fv = FvObj
   2958                 FvImageSectionObj.FvName = None
   2959             else:
   2960                 FvImageSectionObj.FvName = FvName.upper()
   2961                 FvImageSectionObj.FvFileName = FvName
   2962 
   2963             Obj.SectionList.append(FvImageSectionObj)
   2964 
   2965         elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
   2966             if AlignValue == 'Auto':
   2967                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2968             DepexSectionObj = DepexSection.DepexSection()
   2969             DepexSectionObj.Alignment = AlignValue
   2970             DepexSectionObj.DepexType = self.__Token
   2971 
   2972             if not self.__IsToken( "="):
   2973                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2974             if not self.__IsToken( "{"):
   2975                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2976             if not self.__SkipToToken( "}"):
   2977                 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)
   2978 
   2979             DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
   2980             Obj.SectionList.append(DepexSectionObj)
   2981 
   2982         else:
   2983             if not self.__GetNextWord():
   2984                 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)
   2985 
   2986             # Encapsulation section appear, UndoToken and return

   2987             if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
   2988                 self.SetFileBufferPos(OldPos)
   2989                 return False
   2990 
   2991             if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   2992                                "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
   2993                 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2994             if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
   2995                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2996 
   2997             # DataSection

   2998             DataSectionObj = DataSection.DataSection()
   2999             DataSectionObj.Alignment = AlignValue
   3000             DataSectionObj.SecType = self.__Token
   3001 
   3002             if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
   3003                 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
   3004                     if self.__Token == 'RELOCS_STRIPPED':
   3005                         DataSectionObj.KeepReloc = False
   3006                     else:
   3007                         DataSectionObj.KeepReloc = True
   3008                 else:
   3009                     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)
   3010 
   3011             if self.__IsToken("="):
   3012                 if not self.__GetNextToken():
   3013                     raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)
   3014                 DataSectionObj.SectFileName = self.__Token
   3015                 self.__VerifyFile(DataSectionObj.SectFileName)
   3016             else:
   3017                 if not self.__GetCglSection(DataSectionObj):
   3018                     return False
   3019 
   3020             Obj.SectionList.append(DataSectionObj)
   3021 
   3022         return True
   3023 
   3024     ## __VerifyFile

   3025     #

   3026     #    Check if file exists or not:

   3027     #      If current phase if GenFds, the file must exist;

   3028     #      If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist

   3029     #    @param FileName: File path to be verified.

   3030     #

   3031     def __VerifyFile(self, FileName):
   3032         if FileName.replace('$(WORKSPACE)', '').find('$') != -1:
   3033             return
   3034         if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName:
   3035             ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   3036             if ErrorCode != 0:
   3037                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   3038 
   3039     ## __GetCglSection() method

   3040     #

   3041     #   Get compressed or GUIDed section for Obj

   3042     #

   3043     #   @param  self        The object pointer

   3044     #   @param  Obj         for whom leaf section is got

   3045     #   @param  AlignValue  alignment value for complex section

   3046     #   @retval True        Successfully find section statement

   3047     #   @retval False       Not able to find section statement

   3048     #

   3049     def __GetCglSection(self, Obj, AlignValue = None):
   3050 
   3051         if self.__IsKeyword( "COMPRESS"):
   3052             type = "PI_STD"
   3053             if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
   3054                 type = self.__Token
   3055 
   3056             if not self.__IsToken("{"):
   3057                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   3058 
   3059             CompressSectionObj = CompressSection.CompressSection()
   3060             CompressSectionObj.Alignment = AlignValue
   3061             CompressSectionObj.CompType = type
   3062             # Recursive sections...

   3063             while True:
   3064                 IsLeafSection = self.__GetLeafSection(CompressSectionObj)
   3065                 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
   3066                 if not IsLeafSection and not IsEncapSection:
   3067                     break
   3068 
   3069 
   3070             if not self.__IsToken( "}"):
   3071                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3072             Obj.SectionList.append(CompressSectionObj)
   3073 
   3074 #            else:

   3075 #               raise Warning("Compress type not known")

   3076 
   3077             return True
   3078 
   3079         elif self.__IsKeyword( "GUIDED"):
   3080             GuidValue = None
   3081             if self.__GetNextGuid():
   3082                 GuidValue = self.__Token
   3083 
   3084             AttribDict = self.__GetGuidAttrib()
   3085             if not self.__IsToken("{"):
   3086                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   3087             GuidSectionObj = GuidSection.GuidSection()
   3088             GuidSectionObj.Alignment = AlignValue
   3089             GuidSectionObj.NameGuid = GuidValue
   3090             GuidSectionObj.SectionType = "GUIDED"
   3091             GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
   3092             GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
   3093             GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
   3094             # Recursive sections...

   3095             while True:
   3096                 IsLeafSection = self.__GetLeafSection(GuidSectionObj)
   3097                 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
   3098                 if not IsLeafSection and not IsEncapSection:
   3099                     break
   3100 
   3101             if not self.__IsToken( "}"):
   3102                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3103             Obj.SectionList.append(GuidSectionObj)
   3104 
   3105             return True
   3106 
   3107         return False
   3108 
   3109     ## __GetGuidAttri() method

   3110     #

   3111     #   Get attributes for GUID section

   3112     #

   3113     #   @param  self        The object pointer

   3114     #   @retval AttribDict  Dictionary of key-value pair of section attributes

   3115     #

   3116     def __GetGuidAttrib(self):
   3117 
   3118         AttribDict = {}
   3119         AttribDict["PROCESSING_REQUIRED"] = "NONE"
   3120         AttribDict["AUTH_STATUS_VALID"] = "NONE"
   3121         AttribDict["EXTRA_HEADER_SIZE"] = -1
   3122         while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \
   3123             or self.__IsKeyword("EXTRA_HEADER_SIZE"):
   3124             AttribKey = self.__Token
   3125 
   3126             if not self.__IsToken("="):
   3127                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3128 
   3129             if not self.__GetNextToken():
   3130                 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)
   3131             elif AttribKey == "EXTRA_HEADER_SIZE":
   3132                 Base = 10
   3133                 if self.__Token[0:2].upper() == "0X":
   3134                     Base = 16
   3135                 try:
   3136                     AttribDict[AttribKey] = int(self.__Token, Base)
   3137                     continue
   3138                 except ValueError:
   3139                     raise Warning("expected Number", self.FileName, self.CurrentLineNumber)
   3140             elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
   3141                 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
   3142             AttribDict[AttribKey] = self.__Token
   3143 
   3144         return AttribDict
   3145 
   3146     ## __GetEncapsulationSec() method

   3147     #

   3148     #   Get encapsulation section for FILE

   3149     #

   3150     #   @param  self        The object pointer

   3151     #   @param  FfsFile     for whom section is got

   3152     #   @retval True        Successfully find section statement

   3153     #   @retval False       Not able to find section statement

   3154     #

   3155     def __GetEncapsulationSec(self, FfsFileObj):
   3156 
   3157         OldPos = self.GetFileBufferPos()
   3158         if not self.__IsKeyword( "SECTION"):
   3159             if len(FfsFileObj.SectionList) == 0:
   3160                 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
   3161             else:
   3162                 return False
   3163 
   3164         AlignValue = None
   3165         if self.__GetAlignment():
   3166             if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3167                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3168             AlignValue = self.__Token
   3169 
   3170         if not self.__GetCglSection(FfsFileObj, AlignValue):
   3171             self.SetFileBufferPos(OldPos)
   3172             return False
   3173         else:
   3174             return True
   3175 
   3176     def __GetFmp(self):
   3177         if not self.__GetNextToken():
   3178             return False
   3179         S = self.__Token.upper()
   3180         if S.startswith("[") and not S.startswith("[FMPPAYLOAD."):
   3181             self.SectionParser(S)
   3182             self.__UndoToken()
   3183             return False
   3184 
   3185         self.__UndoToken()
   3186         self.__SkipToToken("[FMPPAYLOAD.", True)
   3187         FmpUiName = self.__GetUiName().upper()
   3188         if FmpUiName in self.Profile.FmpPayloadDict:
   3189             raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)
   3190 
   3191         FmpData = CapsuleData.CapsulePayload()
   3192         FmpData.UiName = FmpUiName
   3193 
   3194         if not self.__IsToken( "]"):
   3195             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   3196 
   3197         if not self.__GetNextToken():
   3198             raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)
   3199         FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
   3200         while self.__Token in FmpKeyList:
   3201             Name = self.__Token
   3202             FmpKeyList.remove(Name)
   3203             if not self.__IsToken("="):
   3204                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3205             if Name == 'IMAGE_TYPE_ID':
   3206                 if not self.__GetNextGuid():
   3207                     raise Warning("expected GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)
   3208                 FmpData.ImageTypeId = self.__Token
   3209             elif Name == 'CERTIFICATE_GUID':
   3210                 if not self.__GetNextGuid():
   3211                     raise Warning("expected GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
   3212                 FmpData.Certificate_Guid = self.__Token
   3213                 if uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:
   3214                     raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
   3215             else:
   3216                 if not self.__GetNextToken():
   3217                     raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)
   3218                 Value = self.__Token
   3219                 if Name == 'IMAGE_HEADER_INIT_VERSION':
   3220                     if self.__Verify(Name, Value, 'UINT8'):
   3221                         FmpData.Version = Value
   3222                 elif Name == 'IMAGE_INDEX':
   3223                     if self.__Verify(Name, Value, 'UINT8'):
   3224                         FmpData.ImageIndex = Value
   3225                 elif Name == 'HARDWARE_INSTANCE':
   3226                     if self.__Verify(Name, Value, 'UINT8'):
   3227                         FmpData.HardwareInstance = Value
   3228                 elif Name == 'MONOTONIC_COUNT':
   3229                     if self.__Verify(Name, Value, 'UINT64'):
   3230                         FmpData.MonotonicCount = Value
   3231                         if FmpData.MonotonicCount.upper().startswith('0X'):
   3232                             FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16)
   3233                         else:
   3234                             FmpData.MonotonicCount = (long)(FmpData.MonotonicCount)
   3235             if not self.__GetNextToken():
   3236                 break
   3237         else:
   3238             self.__UndoToken()
   3239 
   3240         if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):
   3241             EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
   3242         # remove CERTIFICATE_GUID and MONOTONIC_COUNT from FmpKeyList, since these keys are optional

   3243         if 'CERTIFICATE_GUID' in FmpKeyList:
   3244             FmpKeyList.remove('CERTIFICATE_GUID')
   3245         if 'MONOTONIC_COUNT' in FmpKeyList:
   3246             FmpKeyList.remove('MONOTONIC_COUNT')
   3247         if FmpKeyList:
   3248             raise Warning("Missing keywords %s in FMP payload section." % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)
   3249         # get the Image file and Vendor code file

   3250         self.__GetFMPCapsuleData(FmpData)
   3251         if not FmpData.ImageFile:
   3252             raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)
   3253         # check whether more than one Vendor code file

   3254         if len(FmpData.VendorCodeFile) > 1:
   3255             raise Warning("At most one Image file and one Vendor code file are allowed in FMP payload section.", self.FileName, self.CurrentLineNumber)
   3256         self.Profile.FmpPayloadDict[FmpUiName] = FmpData
   3257         return True
   3258 
   3259     ## __GetCapsule() method

   3260     #

   3261     #   Get capsule section contents and store its data into capsule list of self.Profile

   3262     #

   3263     #   @param  self        The object pointer

   3264     #   @retval True        Successfully find a capsule

   3265     #   @retval False       Not able to find a capsule

   3266     #

   3267     def __GetCapsule(self):
   3268 
   3269         if not self.__GetNextToken():
   3270             return False
   3271 
   3272         S = self.__Token.upper()
   3273         if S.startswith("[") and not S.startswith("[CAPSULE."):
   3274             self.SectionParser(S)
   3275             self.__UndoToken()
   3276             return False
   3277 
   3278         self.__UndoToken()
   3279         if not self.__IsToken("[CAPSULE.", True):
   3280             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   3281             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

   3282             #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)

   3283             raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)
   3284 
   3285         CapsuleObj = Capsule.Capsule()
   3286 
   3287         CapsuleName = self.__GetUiName()
   3288         if not CapsuleName:
   3289             raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)
   3290 
   3291         CapsuleObj.UiCapsuleName = CapsuleName.upper()
   3292 
   3293         if not self.__IsToken( "]"):
   3294             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   3295 
   3296         if self.__IsKeyword("CREATE_FILE"):
   3297             if not self.__IsToken( "="):
   3298                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3299 
   3300             if not self.__GetNextToken():
   3301                 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
   3302 
   3303             CapsuleObj.CreateFile = self.__Token
   3304 
   3305         self.__GetCapsuleStatements(CapsuleObj)
   3306         self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
   3307         return True
   3308 
   3309     ## __GetCapsuleStatements() method

   3310     #

   3311     #   Get statements for capsule

   3312     #

   3313     #   @param  self        The object pointer

   3314     #   @param  Obj         for whom statements are got

   3315     #

   3316     def __GetCapsuleStatements(self, Obj):
   3317         self.__GetCapsuleTokens(Obj)
   3318         self.__GetDefineStatements(Obj)
   3319         self.__GetSetStatements(Obj)
   3320         self.__GetCapsuleData(Obj)
   3321 
   3322     ## __GetCapsuleTokens() method

   3323     #

   3324     #   Get token statements for capsule

   3325     #

   3326     #   @param  self        The object pointer

   3327     #   @param  Obj         for whom token statements are got

   3328     #

   3329     def __GetCapsuleTokens(self, Obj):
   3330         if not self.__GetNextToken():
   3331             return False
   3332         while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):
   3333             Name = self.__Token.strip()
   3334             if not self.__IsToken("="):
   3335                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3336             if not self.__GetNextToken():
   3337                 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
   3338             if Name == 'CAPSULE_FLAGS':
   3339                 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
   3340                     raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
   3341                 Value = self.__Token.strip()
   3342                 while self.__IsToken(","):
   3343                     Value += ','
   3344                     if not self.__GetNextToken():
   3345                         raise Warning("expected value", self.FileName, self.CurrentLineNumber)
   3346                     if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
   3347                         raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
   3348                     Value += self.__Token.strip()
   3349             elif Name == 'OEM_CAPSULE_FLAGS':
   3350                 Value = self.__Token.strip()
   3351                 if not Value.upper().startswith('0X'):
   3352                     raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
   3353                 try:
   3354                     Value = int(Value, 0)
   3355                 except ValueError:
   3356                     raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
   3357                 if not 0x0000 <= Value <= 0xFFFF:
   3358                     raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
   3359                 Value = self.__Token.strip()
   3360             else:
   3361                 Value = self.__Token.strip()
   3362             Obj.TokensDict[Name] = Value  
   3363             if not self.__GetNextToken():
   3364                 return False
   3365         self.__UndoToken()
   3366 
   3367     ## __GetCapsuleData() method

   3368     #

   3369     #   Get capsule data for capsule

   3370     #

   3371     #   @param  self        The object pointer

   3372     #   @param  Obj         for whom capsule data are got

   3373     #

   3374     def __GetCapsuleData(self, Obj):
   3375 
   3376         while True:
   3377             IsInf = self.__GetInfStatement(Obj, True)
   3378             IsFile = self.__GetFileStatement(Obj, True)
   3379             IsFv = self.__GetFvStatement(Obj)
   3380             IsFd = self.__GetFdStatement(Obj)
   3381             IsAnyFile = self.__GetAnyFileStatement(Obj)
   3382             IsAfile = self.__GetAfileStatement(Obj)
   3383             IsFmp = self.__GetFmpStatement(Obj)
   3384             if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):
   3385                 break
   3386 
   3387     ## __GetFMPCapsuleData() method

   3388     #

   3389     #   Get capsule data for FMP capsule

   3390     #

   3391     #   @param  self        The object pointer

   3392     #   @param  Obj         for whom capsule data are got

   3393     #

   3394     def __GetFMPCapsuleData(self, Obj):
   3395 
   3396         while True:
   3397             IsFv = self.__GetFvStatement(Obj, True)
   3398             IsFd = self.__GetFdStatement(Obj, True)
   3399             IsAnyFile = self.__GetAnyFileStatement(Obj, True)
   3400             if not (IsFv or IsFd or IsAnyFile):
   3401                 break
   3402 
   3403     ## __GetFvStatement() method

   3404     #

   3405     #   Get FV for capsule

   3406     #

   3407     #   @param  self        The object pointer

   3408     #   @param  CapsuleObj  for whom FV is got

   3409     #   @retval True        Successfully find a FV statement

   3410     #   @retval False       Not able to find a FV statement

   3411     #

   3412     def __GetFvStatement(self, CapsuleObj, FMPCapsule = False):
   3413 
   3414         if not self.__IsKeyword("FV"):
   3415             return False
   3416 
   3417         if not self.__IsToken("="):
   3418             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3419 
   3420         if not self.__GetNextToken():
   3421             raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
   3422 
   3423         if self.__Token.upper() not in self.Profile.FvDict.keys():
   3424             raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)
   3425 
   3426         CapsuleFv = CapsuleData.CapsuleFv()
   3427         CapsuleFv.FvName = self.__Token
   3428         if FMPCapsule:
   3429             if not CapsuleObj.ImageFile:
   3430                 CapsuleObj.ImageFile.append(CapsuleFv)
   3431             else:
   3432                 CapsuleObj.VendorCodeFile.append(CapsuleFv)
   3433         else:
   3434             CapsuleObj.CapsuleDataList.append(CapsuleFv)
   3435         return True
   3436 
   3437     ## __GetFdStatement() method

   3438     #

   3439     #   Get FD for capsule

   3440     #

   3441     #   @param  self        The object pointer

   3442     #   @param  CapsuleObj  for whom FD is got

   3443     #   @retval True        Successfully find a FD statement

   3444     #   @retval False       Not able to find a FD statement

   3445     #

   3446     def __GetFdStatement(self, CapsuleObj, FMPCapsule = False):
   3447 
   3448         if not self.__IsKeyword("FD"):
   3449             return False
   3450 
   3451         if not self.__IsToken("="):
   3452             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3453 
   3454         if not self.__GetNextToken():
   3455             raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
   3456 
   3457         if self.__Token.upper() not in self.Profile.FdDict.keys():
   3458             raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)
   3459 
   3460         CapsuleFd = CapsuleData.CapsuleFd()
   3461         CapsuleFd.FdName = self.__Token
   3462         if FMPCapsule:
   3463             if not CapsuleObj.ImageFile:
   3464                 CapsuleObj.ImageFile.append(CapsuleFd)
   3465             else:
   3466                 CapsuleObj.VendorCodeFile.append(CapsuleFd)
   3467         else:
   3468             CapsuleObj.CapsuleDataList.append(CapsuleFd)
   3469         return True
   3470 
   3471     def __GetFmpStatement(self, CapsuleObj):
   3472         if not self.__IsKeyword("FMP_PAYLOAD"):
   3473             if not self.__IsKeyword("FMP"):
   3474                 return False
   3475 
   3476             if not self.__IsKeyword("PAYLOAD"):
   3477                 self.__UndoToken()
   3478                 return False
   3479 
   3480         if not self.__IsToken("="):
   3481             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3482 
   3483         if not self.__GetNextToken():
   3484             raise Warning("expected payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)
   3485         Payload = self.__Token.upper()
   3486         if Payload not in self.Profile.FmpPayloadDict:
   3487             raise Warning("This FMP Payload does not exist: %s" % self.__Token, self.FileName, self.CurrentLineNumber)
   3488         CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])
   3489         return True
   3490 
   3491     def __ParseRawFileStatement(self):
   3492         if not self.__IsKeyword("FILE"):
   3493             return None
   3494 
   3495         if not self.__IsKeyword("DATA"):
   3496             self.__UndoToken()
   3497             return None
   3498 
   3499         if not self.__IsToken("="):
   3500             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3501 
   3502         if not self.__GetNextToken():
   3503             raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
   3504         
   3505         AnyFileName = self.__Token
   3506         self.__VerifyFile(AnyFileName)
   3507 
   3508         if not os.path.isabs(AnyFileName):
   3509             AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)
   3510 
   3511         return AnyFileName
   3512 
   3513     ## __GetAnyFileStatement() method

   3514     #

   3515     #   Get AnyFile for capsule

   3516     #

   3517     #   @param  self        The object pointer

   3518     #   @param  CapsuleObj  for whom AnyFile is got

   3519     #   @retval True        Successfully find a Anyfile statement

   3520     #   @retval False       Not able to find a AnyFile statement

   3521     #

   3522     def __GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False):
   3523         AnyFileName = self.__ParseRawFileStatement()
   3524         if not AnyFileName:
   3525             return False
   3526 
   3527         CapsuleAnyFile = CapsuleData.CapsuleAnyFile()
   3528         CapsuleAnyFile.FileName = AnyFileName
   3529         if FMPCapsule:
   3530             if not CapsuleObj.ImageFile:
   3531                 CapsuleObj.ImageFile.append(CapsuleAnyFile)
   3532             else:
   3533                 CapsuleObj.VendorCodeFile.append(CapsuleAnyFile)
   3534         else:
   3535             CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)
   3536         return True
   3537     
   3538     ## __GetAfileStatement() method

   3539     #

   3540     #   Get Afile for capsule

   3541     #

   3542     #   @param  self        The object pointer

   3543     #   @param  CapsuleObj  for whom Afile is got

   3544     #   @retval True        Successfully find a Afile statement

   3545     #   @retval False       Not able to find a Afile statement

   3546     #

   3547     def __GetAfileStatement(self, CapsuleObj):
   3548 
   3549         if not self.__IsKeyword("APPEND"):
   3550             return False
   3551 
   3552         if not self.__IsToken("="):
   3553             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3554 
   3555         if not self.__GetNextToken():
   3556             raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)
   3557         
   3558         AfileName = self.__Token
   3559         AfileBaseName = os.path.basename(AfileName)
   3560         
   3561         if os.path.splitext(AfileBaseName)[1]  not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:
   3562             raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \
   3563                           self.FileName, self.CurrentLineNumber)
   3564         
   3565         if not os.path.isabs(AfileName):
   3566             AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)
   3567             self.__VerifyFile(AfileName)
   3568         else:
   3569             if not os.path.exists(AfileName):
   3570                 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)
   3571             else:
   3572                 pass
   3573 
   3574         CapsuleAfile = CapsuleData.CapsuleAfile()
   3575         CapsuleAfile.FileName = AfileName
   3576         CapsuleObj.CapsuleDataList.append(CapsuleAfile)
   3577         return True
   3578 
   3579     ## __GetRule() method

   3580     #

   3581     #   Get Rule section contents and store its data into rule list of self.Profile

   3582     #

   3583     #   @param  self        The object pointer

   3584     #   @retval True        Successfully find a Rule

   3585     #   @retval False       Not able to find a Rule

   3586     #

   3587     def __GetRule(self):
   3588 
   3589         if not self.__GetNextToken():
   3590             return False
   3591 
   3592         S = self.__Token.upper()
   3593         if S.startswith("[") and not S.startswith("[RULE."):
   3594             self.SectionParser(S)
   3595             self.__UndoToken()
   3596             return False
   3597         self.__UndoToken()
   3598         if not self.__IsToken("[Rule.", True):
   3599             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   3600             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

   3601             #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)

   3602             raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber)
   3603 
   3604         if not self.__SkipToToken("."):
   3605             raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
   3606 
   3607         Arch = self.__SkippedChars.rstrip(".")
   3608         if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
   3609             raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
   3610 
   3611         ModuleType = self.__GetModuleType()
   3612 
   3613         TemplateName = ""
   3614         if self.__IsToken("."):
   3615             if not self.__GetNextWord():
   3616                 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)
   3617             TemplateName = self.__Token
   3618 
   3619         if not self.__IsToken( "]"):
   3620             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   3621 
   3622         RuleObj = self.__GetRuleFileStatements()
   3623         RuleObj.Arch = Arch.upper()
   3624         RuleObj.ModuleType = ModuleType
   3625         RuleObj.TemplateName = TemplateName
   3626         if TemplateName == '' :
   3627             self.Profile.RuleDict['RULE'             + \
   3628                               '.'                    + \
   3629                               Arch.upper()           + \
   3630                               '.'                    + \
   3631                               ModuleType.upper()     ] = RuleObj
   3632         else :
   3633             self.Profile.RuleDict['RULE'             + \
   3634                               '.'                    + \
   3635                               Arch.upper()           + \
   3636                               '.'                    + \
   3637                               ModuleType.upper()     + \
   3638                               '.'                    + \
   3639                               TemplateName.upper() ] = RuleObj
   3640 #        self.Profile.RuleList.append(rule)

   3641         return True
   3642 
   3643     ## __GetModuleType() method

   3644     #

   3645     #   Return the module type

   3646     #

   3647     #   @param  self        The object pointer

   3648     #   @retval string      module type

   3649     #

   3650     def __GetModuleType(self):
   3651 
   3652         if not self.__GetNextWord():
   3653             raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)
   3654         if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
   3655                              "DXE_DRIVER", "DXE_SAL_DRIVER", \
   3656                              "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
   3657                              "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
   3658                              "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
   3659                              "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
   3660             raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3661         return self.__Token
   3662 
   3663     ## __GetFileExtension() method

   3664     #

   3665     #   Return the file extension

   3666     #

   3667     #   @param  self        The object pointer

   3668     #   @retval string      file name extension

   3669     #

   3670     def __GetFileExtension(self):
   3671         if not self.__IsToken("."):
   3672             raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
   3673 
   3674         Ext = ""
   3675         if self.__GetNextToken():
   3676             Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
   3677             if Pattern.match(self.__Token):
   3678                 Ext = self.__Token
   3679                 return '.' + Ext
   3680             else:
   3681                 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3682 
   3683         else:
   3684             raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)
   3685 
   3686     ## __GetRuleFileStatement() method

   3687     #

   3688     #   Get rule contents

   3689     #

   3690     #   @param  self        The object pointer

   3691     #   @retval Rule        Rule object

   3692     #

   3693     def __GetRuleFileStatements(self):
   3694 
   3695         if not self.__IsKeyword("FILE"):
   3696             raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)
   3697 
   3698         if not self.__GetNextWord():
   3699             raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
   3700 
   3701         Type = self.__Token.strip().upper()
   3702         if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
   3703                              "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
   3704             raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3705 
   3706         if not self.__IsToken("="):
   3707             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3708 
   3709         if not self.__IsKeyword("$(NAMED_GUID)"):
   3710             if not self.__GetNextWord():
   3711                 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
   3712             if self.__Token == 'PCD':
   3713                 if not self.__IsToken( "("):
   3714                     raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
   3715                 PcdPair = self.__GetNextPcdName()
   3716                 if not self.__IsToken( ")"):
   3717                     raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
   3718                 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
   3719             
   3720         NameGuid = self.__Token
   3721 
   3722         KeepReloc = None
   3723         if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
   3724             if self.__FileCouldHaveRelocFlag(Type):
   3725                 if self.__Token == 'RELOCS_STRIPPED':
   3726                     KeepReloc = False
   3727                 else:
   3728                     KeepReloc = True
   3729             else:
   3730                 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3731 
   3732         KeyStringList = []
   3733         if self.__GetNextToken():
   3734             Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
   3735             if Pattern.match(self.__Token):
   3736                 KeyStringList.append(self.__Token)
   3737                 if self.__IsToken(","):
   3738                     while self.__GetNextToken():
   3739                         if not Pattern.match(self.__Token):
   3740                             raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
   3741                         KeyStringList.append(self.__Token)
   3742 
   3743                         if not self.__IsToken(","):
   3744                             break
   3745 
   3746             else:
   3747                 self.__UndoToken()
   3748 
   3749 
   3750         Fixed = False
   3751         if self.__IsKeyword("Fixed", True):
   3752             Fixed = True
   3753 
   3754         CheckSum = False
   3755         if self.__IsKeyword("CheckSum", True):
   3756             CheckSum = True
   3757 
   3758         AlignValue = ""
   3759         if self.__GetAlignment():
   3760             if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3761                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3762             #For FFS, Auto is default option same to ""

   3763             if not self.__Token == "Auto":
   3764                 AlignValue = self.__Token
   3765 
   3766         if self.__IsToken("{"):
   3767             # Complex file rule expected

   3768             Rule = RuleComplexFile.RuleComplexFile()
   3769             Rule.FvFileType = Type
   3770             Rule.NameGuid = NameGuid
   3771             Rule.Alignment = AlignValue
   3772             Rule.CheckSum = CheckSum
   3773             Rule.Fixed = Fixed
   3774             Rule.KeyStringList = KeyStringList
   3775             if KeepReloc != None:
   3776                 Rule.KeepReloc = KeepReloc
   3777 
   3778             while True:
   3779                 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
   3780                 IsLeaf = self.__GetEfiSection(Rule)
   3781                 if not IsEncapsulate and not IsLeaf:
   3782                     break
   3783 
   3784             if not self.__IsToken("}"):
   3785                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3786 
   3787             return Rule
   3788 
   3789         else:
   3790             # Simple file rule expected

   3791             if not self.__GetNextWord():
   3792                 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)
   3793 
   3794             SectionName = self.__Token
   3795 
   3796             if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   3797                                     "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
   3798                 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
   3799 
   3800 
   3801             if self.__IsKeyword("Fixed", True):
   3802                 Fixed = True
   3803 
   3804             if self.__IsKeyword("CheckSum", True):
   3805                 CheckSum = True
   3806 
   3807             SectAlignment = ""
   3808             if self.__GetAlignment():
   3809                 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3810                     raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3811                 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
   3812                     raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   3813                 SectAlignment = self.__Token
   3814 
   3815             Ext = None
   3816             if self.__IsToken('|'):
   3817                 Ext = self.__GetFileExtension()
   3818             elif not self.__GetNextToken():
   3819                 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
   3820 
   3821             Rule = RuleSimpleFile.RuleSimpleFile()
   3822             Rule.SectionType = SectionName
   3823             Rule.FvFileType = Type
   3824             Rule.NameGuid = NameGuid
   3825             Rule.Alignment = AlignValue
   3826             Rule.SectAlignment = SectAlignment
   3827             Rule.CheckSum = CheckSum
   3828             Rule.Fixed = Fixed
   3829             Rule.KeyStringList = KeyStringList
   3830             if KeepReloc != None:
   3831                 Rule.KeepReloc = KeepReloc
   3832             Rule.FileExtension = Ext
   3833             Rule.FileName = self.__Token
   3834             return Rule
   3835 
   3836     ## __GetEfiSection() method

   3837     #

   3838     #   Get section list for Rule

   3839     #

   3840     #   @param  self        The object pointer

   3841     #   @param  Obj         for whom section is got

   3842     #   @retval True        Successfully find section statement

   3843     #   @retval False       Not able to find section statement

   3844     #

   3845     def __GetEfiSection(self, Obj):
   3846 
   3847         OldPos = self.GetFileBufferPos()
   3848         if not self.__GetNextWord():
   3849             return False
   3850         SectionName = self.__Token
   3851 
   3852         if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   3853                                "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
   3854             self.__UndoToken()
   3855             return False
   3856 
   3857         if SectionName == "FV_IMAGE":
   3858             FvImageSectionObj = FvImageSection.FvImageSection()
   3859             if self.__IsKeyword("FV_IMAGE"):
   3860                 pass
   3861             if self.__IsToken( "{"):
   3862                 FvObj = Fv.FV()
   3863                 self.__GetDefineStatements(FvObj)
   3864                 self.__GetBlockStatement(FvObj)
   3865                 self.__GetSetStatements(FvObj)
   3866                 self.__GetFvAlignment(FvObj)
   3867                 self.__GetFvAttributes(FvObj)
   3868                 self.__GetAprioriSection(FvObj)
   3869                 self.__GetAprioriSection(FvObj)
   3870 
   3871                 while True:
   3872                     IsInf = self.__GetInfStatement(FvObj)
   3873                     IsFile = self.__GetFileStatement(FvObj)
   3874                     if not IsInf and not IsFile:
   3875                         break
   3876 
   3877                 if not self.__IsToken( "}"):
   3878                     raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3879                 FvImageSectionObj.Fv = FvObj
   3880                 FvImageSectionObj.FvName = None
   3881 
   3882             else:
   3883                 if not self.__IsKeyword("FV"):
   3884                     raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber)
   3885                 FvImageSectionObj.FvFileType = self.__Token
   3886 
   3887                 if self.__GetAlignment():
   3888                     if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3889                         raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3890                     FvImageSectionObj.Alignment = self.__Token
   3891 
   3892                 if self.__IsToken('|'):
   3893                     FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
   3894                 elif self.__GetNextToken():
   3895                     if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   3896                                "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
   3897                         FvImageSectionObj.FvFileName = self.__Token
   3898                     else:
   3899                         self.__UndoToken()
   3900                 else:
   3901                     raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)
   3902 
   3903             Obj.SectionList.append(FvImageSectionObj)
   3904             return True
   3905 
   3906         EfiSectionObj = EfiSection.EfiSection()
   3907         EfiSectionObj.SectionType = SectionName
   3908 
   3909         if not self.__GetNextToken():
   3910             raise Warning("expected file type", self.FileName, self.CurrentLineNumber)
   3911 
   3912         if self.__Token == "STRING":
   3913             if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
   3914                 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3915 
   3916             if not self.__IsToken('='):
   3917                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3918 
   3919             if not self.__GetNextToken():
   3920                 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)
   3921 
   3922             if self.__GetStringData():
   3923                 EfiSectionObj.StringData = self.__Token
   3924 
   3925             if self.__IsKeyword("BUILD_NUM"):
   3926                 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
   3927                     raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3928 
   3929                 if not self.__IsToken("="):
   3930                     raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3931                 if not self.__GetNextToken():
   3932                     raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
   3933                 EfiSectionObj.BuildNum = self.__Token
   3934 
   3935         else:
   3936             EfiSectionObj.FileType = self.__Token
   3937             self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
   3938 
   3939         if self.__IsKeyword("Optional"):
   3940             if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
   3941                 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3942             EfiSectionObj.Optional = True
   3943 
   3944             if self.__IsKeyword("BUILD_NUM"):
   3945                 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
   3946                     raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3947 
   3948                 if not self.__IsToken("="):
   3949                     raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3950                 if not self.__GetNextToken():
   3951                     raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
   3952                 EfiSectionObj.BuildNum = self.__Token
   3953 
   3954         if self.__GetAlignment():
   3955             if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3956                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3957             if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
   3958                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   3959             EfiSectionObj.Alignment = self.__Token
   3960 
   3961         if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
   3962             if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
   3963                 if self.__Token == 'RELOCS_STRIPPED':
   3964                     EfiSectionObj.KeepReloc = False
   3965                 else:
   3966                     EfiSectionObj.KeepReloc = True
   3967                 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
   3968                     raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
   3969             else:
   3970                 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
   3971 
   3972 
   3973         if self.__IsToken('|'):
   3974             EfiSectionObj.FileExtension = self.__GetFileExtension()
   3975         elif self.__GetNextToken():
   3976             if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   3977                        "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
   3978                 
   3979                 if self.__Token.startswith('PCD'):
   3980                     self.__UndoToken()
   3981                     self.__GetNextWord()
   3982                 
   3983                     if self.__Token == 'PCD':
   3984                         if not self.__IsToken( "("):
   3985                             raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
   3986                         PcdPair = self.__GetNextPcdName()
   3987                         if not self.__IsToken( ")"):
   3988                             raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
   3989                         self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
   3990                         
   3991                 EfiSectionObj.FileName = self.__Token        
   3992                             
   3993             else:
   3994                 self.__UndoToken()
   3995         else:
   3996             raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)
   3997 
   3998         Obj.SectionList.append(EfiSectionObj)
   3999         return True
   4000 
   4001     ## __RuleSectionCouldBeOptional() method

   4002     #

   4003     #   Get whether a section could be optional

   4004     #

   4005     #   @param  self        The object pointer

   4006     #   @param  SectionType The section type to check

   4007     #   @retval True        section could be optional

   4008     #   @retval False       section never optional

   4009     #

   4010     def __RuleSectionCouldBeOptional(self, SectionType):
   4011         if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
   4012             return True
   4013         else:
   4014             return False
   4015 
   4016     ## __RuleSectionCouldHaveBuildNum() method

   4017     #

   4018     #   Get whether a section could have build number information

   4019     #

   4020     #   @param  self        The object pointer

   4021     #   @param  SectionType The section type to check

   4022     #   @retval True        section could have build number information

   4023     #   @retval False       section never have build number information

   4024     #

   4025     def __RuleSectionCouldHaveBuildNum(self, SectionType):
   4026         if SectionType in ("VERSION"):
   4027             return True
   4028         else:
   4029             return False
   4030 
   4031     ## __RuleSectionCouldHaveString() method

   4032     #

   4033     #   Get whether a section could have string

   4034     #

   4035     #   @param  self        The object pointer

   4036     #   @param  SectionType The section type to check

   4037     #   @retval True        section could have string

   4038     #   @retval False       section never have string

   4039     #

   4040     def __RuleSectionCouldHaveString(self, SectionType):
   4041         if SectionType in ("UI", "VERSION"):
   4042             return True
   4043         else:
   4044             return False
   4045 
   4046     ## __CheckRuleSectionFileType() method

   4047     #

   4048     #   Get whether a section matches a file type

   4049     #

   4050     #   @param  self        The object pointer

   4051     #   @param  SectionType The section type to check

   4052     #   @param  FileType    The file type to check

   4053     #

   4054     def __CheckRuleSectionFileType(self, SectionType, FileType):
   4055         if SectionType == "COMPAT16":
   4056             if FileType not in ("COMPAT16", "SEC_COMPAT16"):
   4057                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4058         elif SectionType == "PE32":
   4059             if FileType not in ("PE32", "SEC_PE32"):
   4060                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4061         elif SectionType == "PIC":
   4062             if FileType not in ("PIC", "PIC"):
   4063                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4064         elif SectionType == "TE":
   4065             if FileType not in ("TE", "SEC_TE"):
   4066                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4067         elif SectionType == "RAW":
   4068             if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
   4069                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4070         elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
   4071             if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
   4072                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4073         elif SectionType == "UI":
   4074             if FileType not in ("UI", "SEC_UI"):
   4075                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4076         elif SectionType == "VERSION":
   4077             if FileType not in ("VERSION", "SEC_VERSION"):
   4078                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4079         elif SectionType == "PEI_DEPEX":
   4080             if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
   4081                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4082         elif SectionType == "GUID":
   4083             if FileType not in ("PE32", "SEC_GUID"):
   4084                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   4085 
   4086     ## __GetRuleEncapsulationSection() method

   4087     #

   4088     #   Get encapsulation section for Rule

   4089     #

   4090     #   @param  self        The object pointer

   4091     #   @param  Rule        for whom section is got

   4092     #   @retval True        Successfully find section statement

   4093     #   @retval False       Not able to find section statement

   4094     #

   4095     def __GetRuleEncapsulationSection(self, Rule):
   4096 
   4097         if self.__IsKeyword( "COMPRESS"):
   4098             Type = "PI_STD"
   4099             if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
   4100                 Type = self.__Token
   4101 
   4102             if not self.__IsToken("{"):
   4103                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   4104 
   4105             CompressSectionObj = CompressSection.CompressSection()
   4106 
   4107             CompressSectionObj.CompType = Type
   4108             # Recursive sections...

   4109             while True:
   4110                 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
   4111                 IsLeaf = self.__GetEfiSection(CompressSectionObj)
   4112                 if not IsEncapsulate and not IsLeaf:
   4113                     break
   4114 
   4115             if not self.__IsToken( "}"):
   4116                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   4117             Rule.SectionList.append(CompressSectionObj)
   4118 
   4119             return True
   4120 
   4121         elif self.__IsKeyword( "GUIDED"):
   4122             GuidValue = None
   4123             if self.__GetNextGuid():
   4124                 GuidValue = self.__Token
   4125 
   4126             if self.__IsKeyword( "$(NAMED_GUID)"):
   4127                 GuidValue = self.__Token
   4128 
   4129             AttribDict = self.__GetGuidAttrib()
   4130 
   4131             if not self.__IsToken("{"):
   4132                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   4133             GuidSectionObj = GuidSection.GuidSection()
   4134             GuidSectionObj.NameGuid = GuidValue
   4135             GuidSectionObj.SectionType = "GUIDED"
   4136             GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
   4137             GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
   4138             GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
   4139 
   4140             # Efi sections...

   4141             while True:
   4142                 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
   4143                 IsLeaf = self.__GetEfiSection(GuidSectionObj)
   4144                 if not IsEncapsulate and not IsLeaf:
   4145                     break
   4146 
   4147             if not self.__IsToken( "}"):
   4148                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   4149             Rule.SectionList.append(GuidSectionObj)
   4150 
   4151             return True
   4152 
   4153         return False
   4154 
   4155     ## __GetVtf() method

   4156     #

   4157     #   Get VTF section contents and store its data into VTF list of self.Profile

   4158     #

   4159     #   @param  self        The object pointer

   4160     #   @retval True        Successfully find a VTF

   4161     #   @retval False       Not able to find a VTF

   4162     #

   4163     def __GetVtf(self):
   4164 
   4165         if not self.__GetNextToken():
   4166             return False
   4167 
   4168         S = self.__Token.upper()
   4169         if S.startswith("[") and not S.startswith("[VTF."):
   4170             self.SectionParser(S)
   4171             self.__UndoToken()
   4172             return False
   4173 
   4174         self.__UndoToken()
   4175         if not self.__IsToken("[VTF.", True):
   4176             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   4177             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

   4178             #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)

   4179             raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)
   4180 
   4181         if not self.__SkipToToken("."):
   4182             raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
   4183 
   4184         Arch = self.__SkippedChars.rstrip(".").upper()
   4185         if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
   4186             raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
   4187 
   4188         if not self.__GetNextWord():
   4189             raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)
   4190         Name = self.__Token.upper()
   4191 
   4192         VtfObj = Vtf.Vtf()
   4193         VtfObj.UiName = Name
   4194         VtfObj.KeyArch = Arch
   4195 
   4196         if self.__IsToken(","):
   4197             if not self.__GetNextWord():
   4198                 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)
   4199             if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
   4200                 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4201             VtfObj.ArchList = self.__Token.upper()
   4202 
   4203         if not self.__IsToken( "]"):
   4204             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   4205 
   4206         if self.__IsKeyword("IA32_RST_BIN"):
   4207             if not self.__IsToken("="):
   4208                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4209 
   4210             if not self.__GetNextToken():
   4211                 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)
   4212 
   4213             VtfObj.ResetBin = self.__Token
   4214             if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1:
   4215                 #check for file path

   4216                 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4217                 if ErrorCode != 0:
   4218                     EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4219 
   4220         while self.__GetComponentStatement(VtfObj):
   4221             pass
   4222 
   4223         self.Profile.VtfList.append(VtfObj)
   4224         return True
   4225 
   4226     ## __GetComponentStatement() method

   4227     #

   4228     #   Get components in VTF

   4229     #

   4230     #   @param  self        The object pointer

   4231     #   @param  VtfObj         for whom component is got

   4232     #   @retval True        Successfully find a component

   4233     #   @retval False       Not able to find a component

   4234     #

   4235     def __GetComponentStatement(self, VtfObj):
   4236 
   4237         if not self.__IsKeyword("COMP_NAME"):
   4238             return False
   4239 
   4240         if not self.__IsToken("="):
   4241             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4242 
   4243         if not self.__GetNextWord():
   4244             raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)
   4245 
   4246         CompStatementObj = ComponentStatement.ComponentStatement()
   4247         CompStatementObj.CompName = self.__Token
   4248 
   4249         if not self.__IsKeyword("COMP_LOC"):
   4250             raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)
   4251 
   4252         if not self.__IsToken("="):
   4253             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4254 
   4255         CompStatementObj.CompLoc = ""
   4256         if self.__GetNextWord():
   4257             CompStatementObj.CompLoc = self.__Token
   4258             if self.__IsToken('|'):
   4259                 if not self.__GetNextWord():
   4260                     raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)
   4261 
   4262                 if self.__Token not in ("F", "N", "S"):    #, "H", "L", "PH", "PL"): not support

   4263                     raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4264 
   4265                 CompStatementObj.FilePos = self.__Token
   4266         else:
   4267             self.CurrentLineNumber += 1
   4268             self.CurrentOffsetWithinLine = 0
   4269 
   4270         if not self.__IsKeyword("COMP_TYPE"):
   4271             raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)
   4272 
   4273         if not self.__IsToken("="):
   4274             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4275 
   4276         if not self.__GetNextToken():
   4277             raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)
   4278         if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
   4279             if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
   4280                 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
   4281                 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4282         CompStatementObj.CompType = self.__Token
   4283 
   4284         if not self.__IsKeyword("COMP_VER"):
   4285             raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)
   4286 
   4287         if not self.__IsToken("="):
   4288             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4289 
   4290         if not self.__GetNextToken():
   4291             raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)
   4292 
   4293         Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL)
   4294         if Pattern.match(self.__Token) == None:
   4295             raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4296         CompStatementObj.CompVer = self.__Token
   4297 
   4298         if not self.__IsKeyword("COMP_CS"):
   4299             raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)
   4300 
   4301         if not self.__IsToken("="):
   4302             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4303 
   4304         if not self.__GetNextToken():
   4305             raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)
   4306         if self.__Token not in ("1", "0"):
   4307             raise Warning("Unknown  Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4308         CompStatementObj.CompCs = self.__Token
   4309 
   4310 
   4311         if not self.__IsKeyword("COMP_BIN"):
   4312             raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)
   4313 
   4314         if not self.__IsToken("="):
   4315             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4316 
   4317         if not self.__GetNextToken():
   4318             raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)
   4319 
   4320         CompStatementObj.CompBin = self.__Token
   4321         if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1:
   4322             #check for file path

   4323             ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4324             if ErrorCode != 0:
   4325                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4326 
   4327         if not self.__IsKeyword("COMP_SYM"):
   4328             raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)
   4329 
   4330         if not self.__IsToken("="):
   4331             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4332 
   4333         if not self.__GetNextToken():
   4334             raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)
   4335 
   4336         CompStatementObj.CompSym = self.__Token
   4337         if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1:
   4338             #check for file path

   4339             ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4340             if ErrorCode != 0:
   4341                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4342 
   4343         if not self.__IsKeyword("COMP_SIZE"):
   4344             raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)
   4345 
   4346         if not self.__IsToken("="):
   4347             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4348 
   4349         if self.__IsToken("-"):
   4350             CompStatementObj.CompSize = self.__Token
   4351         elif self.__GetNextDecimalNumber():
   4352             CompStatementObj.CompSize = self.__Token
   4353         elif self.__GetNextHexNumber():
   4354             CompStatementObj.CompSize = self.__Token
   4355         else:
   4356             raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4357 
   4358         VtfObj.ComponentStatementList.append(CompStatementObj)
   4359         return True
   4360 
   4361     ## __GetOptionRom() method

   4362     #

   4363     #   Get OptionROM section contents and store its data into OptionROM list of self.Profile

   4364     #

   4365     #   @param  self        The object pointer

   4366     #   @retval True        Successfully find a OptionROM

   4367     #   @retval False       Not able to find a OptionROM

   4368     #

   4369     def __GetOptionRom(self):
   4370 
   4371         if not self.__GetNextToken():
   4372             return False
   4373 
   4374         S = self.__Token.upper()
   4375         if S.startswith("[") and not S.startswith("[OPTIONROM."):
   4376             self.SectionParser(S)
   4377             self.__UndoToken()
   4378             return False
   4379         
   4380         self.__UndoToken()
   4381         if not self.__IsToken("[OptionRom.", True):
   4382             raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4383 
   4384         OptRomName = self.__GetUiName()
   4385 
   4386         if not self.__IsToken( "]"):
   4387             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   4388 
   4389         OptRomObj = OptionRom.OPTIONROM()
   4390         OptRomObj.DriverName = OptRomName
   4391         self.Profile.OptRomDict[OptRomName] = OptRomObj
   4392 
   4393         while True:
   4394             isInf = self.__GetOptRomInfStatement(OptRomObj)
   4395             isFile = self.__GetOptRomFileStatement(OptRomObj)
   4396             if not isInf and not isFile:
   4397                 break
   4398             
   4399         return True
   4400 
   4401     ## __GetOptRomInfStatement() method

   4402     #

   4403     #   Get INF statements

   4404     #

   4405     #   @param  self        The object pointer

   4406     #   @param  Obj         for whom inf statement is got

   4407     #   @retval True        Successfully find inf statement

   4408     #   @retval False       Not able to find inf statement

   4409     #

   4410     def __GetOptRomInfStatement(self, Obj):
   4411 
   4412         if not self.__IsKeyword( "INF"):
   4413             return False
   4414 
   4415         ffsInf = OptRomInfStatement.OptRomInfStatement()
   4416         self.__GetInfOptions( ffsInf)
   4417 
   4418         if not self.__GetNextToken():
   4419             raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
   4420         ffsInf.InfFileName = self.__Token
   4421         if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
   4422             #check for file path

   4423             ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4424             if ErrorCode != 0:
   4425                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4426 
   4427         if not ffsInf.InfFileName in self.Profile.InfList:
   4428             self.Profile.InfList.append(ffsInf.InfFileName)
   4429             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   4430             self.Profile.InfFileLineList.append(FileLineTuple)
   4431             if ffsInf.UseArch:
   4432                 if ffsInf.UseArch not in self.Profile.InfDict:
   4433                     self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
   4434                 else:
   4435                     self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
   4436             else:
   4437                 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)
   4438 
   4439         
   4440         self.__GetOptRomOverrides (ffsInf)
   4441             
   4442         Obj.FfsList.append(ffsInf)
   4443         return True
   4444 
   4445     ## __GetOptRomOverrides() method

   4446     #

   4447     #   Get overrides for OptROM INF & FILE

   4448     #

   4449     #   @param  self        The object pointer

   4450     #   @param  FfsInfObj   for whom overrides is got

   4451     #

   4452     def __GetOptRomOverrides(self, Obj):
   4453         if self.__IsToken('{'):
   4454             Overrides = OptionRom.OverrideAttribs()
   4455             while True:
   4456                 if self.__IsKeyword( "PCI_VENDOR_ID"):
   4457                     if not self.__IsToken( "="):
   4458                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4459                     if not self.__GetNextHexNumber():
   4460                         raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)
   4461                     Overrides.PciVendorId = self.__Token
   4462                     continue
   4463 
   4464                 if self.__IsKeyword( "PCI_CLASS_CODE"):
   4465                     if not self.__IsToken( "="):
   4466                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4467                     if not self.__GetNextHexNumber():
   4468                         raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)
   4469                     Overrides.PciClassCode = self.__Token
   4470                     continue
   4471 
   4472                 if self.__IsKeyword( "PCI_DEVICE_ID"):
   4473                     if not self.__IsToken( "="):
   4474                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4475                     if not self.__GetNextHexNumber():
   4476                         raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)
   4477 
   4478                     Overrides.PciDeviceId = self.__Token
   4479                     continue
   4480 
   4481                 if self.__IsKeyword( "PCI_REVISION"):
   4482                     if not self.__IsToken( "="):
   4483                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4484                     if not self.__GetNextHexNumber():
   4485                         raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)
   4486                     Overrides.PciRevision = self.__Token
   4487                     continue
   4488 
   4489                 if self.__IsKeyword( "PCI_COMPRESS"):
   4490                     if not self.__IsToken( "="):
   4491                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4492                     if not self.__GetNextToken():
   4493                         raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
   4494                     Overrides.NeedCompress = self.__Token.upper() == 'TRUE'
   4495                     continue
   4496 
   4497                 if self.__IsToken( "}"):
   4498                     break
   4499                 else:
   4500                     EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)
   4501 
   4502             Obj.OverrideAttribs = Overrides
   4503             
   4504     ## __GetOptRomFileStatement() method

   4505     #

   4506     #   Get FILE statements

   4507     #

   4508     #   @param  self        The object pointer

   4509     #   @param  Obj         for whom FILE statement is got

   4510     #   @retval True        Successfully find FILE statement

   4511     #   @retval False       Not able to find FILE statement

   4512     #

   4513     def __GetOptRomFileStatement(self, Obj):
   4514 
   4515         if not self.__IsKeyword( "FILE"):
   4516             return False
   4517 
   4518         FfsFileObj = OptRomFileStatement.OptRomFileStatement()
   4519 
   4520         if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"):
   4521             raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
   4522         FfsFileObj.FileType = self.__Token
   4523 
   4524         if not self.__GetNextToken():
   4525             raise Warning("expected File path", self.FileName, self.CurrentLineNumber)
   4526         FfsFileObj.FileName = self.__Token
   4527         if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
   4528             #check for file path

   4529             ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4530             if ErrorCode != 0:
   4531                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4532 
   4533         if FfsFileObj.FileType == 'EFI':
   4534             self.__GetOptRomOverrides(FfsFileObj)
   4535         
   4536         Obj.FfsList.append(FfsFileObj)
   4537 
   4538         return True
   4539 
   4540     ## __GetCapInFd() method

   4541     #

   4542     #   Get Cap list contained in FD

   4543     #

   4544     #   @param  self        The object pointer

   4545     #   @param  FdName      FD name

   4546     #   @retval CapList     List of Capsule in FD

   4547     #

   4548     def __GetCapInFd (self, FdName):
   4549 
   4550         CapList = []
   4551         if FdName.upper() in self.Profile.FdDict.keys():
   4552             FdObj = self.Profile.FdDict[FdName.upper()]
   4553             for elementRegion in FdObj.RegionList:
   4554                 if elementRegion.RegionType == 'CAPSULE':
   4555                     for elementRegionData in elementRegion.RegionDataList:
   4556                         if elementRegionData.endswith(".cap"):
   4557                             continue
   4558                         if elementRegionData != None and elementRegionData.upper() not in CapList:
   4559                             CapList.append(elementRegionData.upper())
   4560         return CapList
   4561 
   4562     ## __GetReferencedFdCapTuple() method

   4563     #

   4564     #   Get FV and FD list referenced by a capsule image

   4565     #

   4566     #   @param  self        The object pointer

   4567     #   @param  CapObj      Capsule section to be searched

   4568     #   @param  RefFdList   referenced FD by section

   4569     #   @param  RefFvList   referenced FV by section

   4570     #

   4571     def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
   4572 
   4573         for CapsuleDataObj in CapObj.CapsuleDataList :
   4574             if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:
   4575                 RefFvList.append (CapsuleDataObj.FvName.upper())
   4576             elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList:
   4577                 RefFdList.append (CapsuleDataObj.FdName.upper())            
   4578             elif CapsuleDataObj.Ffs != None:
   4579                 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):
   4580                     if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
   4581                         RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
   4582                     elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
   4583                         RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
   4584                     else:
   4585                         self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)
   4586 
   4587     ## __GetFvInFd() method

   4588     #

   4589     #   Get FV list contained in FD

   4590     #

   4591     #   @param  self        The object pointer

   4592     #   @param  FdName      FD name

   4593     #   @retval FvList      list of FV in FD

   4594     #

   4595     def __GetFvInFd (self, FdName):
   4596 
   4597         FvList = []
   4598         if FdName.upper() in self.Profile.FdDict.keys():
   4599             FdObj = self.Profile.FdDict[FdName.upper()]
   4600             for elementRegion in FdObj.RegionList:
   4601                 if elementRegion.RegionType == 'FV':
   4602                     for elementRegionData in elementRegion.RegionDataList:
   4603                         if elementRegionData.endswith(".fv"):
   4604                             continue
   4605                         if elementRegionData != None and elementRegionData.upper() not in FvList:
   4606                             FvList.append(elementRegionData.upper())
   4607         return FvList
   4608 
   4609     ## __GetReferencedFdFvTuple() method

   4610     #

   4611     #   Get FD and FV list referenced by a FFS file

   4612     #

   4613     #   @param  self        The object pointer

   4614     #   @param  FfsFile     contains sections to be searched

   4615     #   @param  RefFdList   referenced FD by section

   4616     #   @param  RefFvList   referenced FV by section

   4617     #

   4618     def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
   4619 
   4620         for FfsObj in FvObj.FfsList:
   4621             if isinstance(FfsObj, FfsFileStatement.FileStatement):
   4622                 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
   4623                     RefFvList.append(FfsObj.FvName.upper())
   4624                 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
   4625                     RefFdList.append(FfsObj.FdName.upper())
   4626                 else:
   4627                     self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
   4628 
   4629     ## __GetReferencedFdFvTupleFromSection() method

   4630     #

   4631     #   Get FD and FV list referenced by a FFS section

   4632     #

   4633     #   @param  self        The object pointer

   4634     #   @param  FfsFile     contains sections to be searched

   4635     #   @param  FdList      referenced FD by section

   4636     #   @param  FvList      referenced FV by section

   4637     #

   4638     def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
   4639 
   4640         SectionStack = []
   4641         SectionStack.extend(FfsFile.SectionList)
   4642         while SectionStack != []:
   4643             SectionObj = SectionStack.pop()
   4644             if isinstance(SectionObj, FvImageSection.FvImageSection):
   4645                 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
   4646                     FvList.append(SectionObj.FvName.upper())
   4647                 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
   4648                     FvList.append(SectionObj.Fv.UiFvName.upper())
   4649                     self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
   4650 
   4651             if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
   4652                 SectionStack.extend(SectionObj.SectionList)
   4653 
   4654     ## CycleReferenceCheck() method

   4655     #

   4656     #   Check whether cycle reference exists in FDF

   4657     #

   4658     #   @param  self        The object pointer

   4659     #   @retval True        cycle reference exists

   4660     #   @retval False       Not exists cycle reference

   4661     #

   4662     def CycleReferenceCheck(self):
   4663         #

   4664         # Check the cycle between FV and FD image

   4665         #

   4666         MaxLength = len (self.Profile.FvDict)
   4667         for FvName in self.Profile.FvDict.keys():
   4668             LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
   4669             RefFvStack = []
   4670             RefFvStack.append(FvName)
   4671             FdAnalyzedList = []
   4672             
   4673             Index = 0
   4674             while RefFvStack != [] and Index < MaxLength:
   4675                 Index = Index + 1
   4676                 FvNameFromStack = RefFvStack.pop()
   4677                 if FvNameFromStack.upper() in self.Profile.FvDict.keys():
   4678                     FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
   4679                 else:
   4680                     continue
   4681 
   4682                 RefFdList = []
   4683                 RefFvList = []
   4684                 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
   4685 
   4686                 for RefFdName in RefFdList:
   4687                     if RefFdName in FdAnalyzedList:
   4688                         continue
   4689 
   4690                     LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
   4691                     FvInFdList = self.__GetFvInFd(RefFdName)
   4692                     if FvInFdList != []:
   4693                         for FvNameInFd in FvInFdList:
   4694                             LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
   4695                             if FvNameInFd not in RefFvStack:
   4696                                 RefFvStack.append(FvNameInFd)
   4697 
   4698                             if FvName in RefFvStack or FvNameFromStack in RefFvStack:
   4699                                 EdkLogger.info(LogStr)
   4700                                 return True
   4701                     FdAnalyzedList.append(RefFdName)
   4702 
   4703                 for RefFvName in RefFvList:
   4704                     LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
   4705                     if RefFvName not in RefFvStack:
   4706                         RefFvStack.append(RefFvName)
   4707 
   4708                     if FvName in RefFvStack or FvNameFromStack in RefFvStack:
   4709                         EdkLogger.info(LogStr)
   4710                         return True
   4711 
   4712         #

   4713         # Check the cycle between Capsule and FD image

   4714         #

   4715         MaxLength = len (self.Profile.CapsuleDict)
   4716         for CapName in self.Profile.CapsuleDict.keys():
   4717             #

   4718             # Capsule image to be checked.

   4719             #

   4720             LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
   4721             RefCapStack = []
   4722             RefCapStack.append(CapName)
   4723             FdAnalyzedList = []
   4724             FvAnalyzedList = []
   4725             
   4726             Index = 0
   4727             while RefCapStack != [] and Index < MaxLength:
   4728                 Index = Index + 1
   4729                 CapNameFromStack = RefCapStack.pop()
   4730                 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():
   4731                     CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
   4732                 else:
   4733                     continue
   4734 
   4735                 RefFvList = []
   4736                 RefFdList = []
   4737                 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)
   4738 
   4739                 FvListLength = 0
   4740                 FdListLength = 0
   4741                 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
   4742                     for RefFdName in RefFdList:
   4743                         if RefFdName in FdAnalyzedList:
   4744                             continue
   4745 
   4746                         LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
   4747                         CapInFdList = self.__GetCapInFd(RefFdName)
   4748                         if CapInFdList != []:
   4749                             for CapNameInFd in CapInFdList:
   4750                                 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)
   4751                                 if CapNameInFd not in RefCapStack:
   4752                                     RefCapStack.append(CapNameInFd)
   4753 
   4754                                 if CapName in RefCapStack or CapNameFromStack in RefCapStack:
   4755                                     EdkLogger.info(LogStr)
   4756                                     return True
   4757 
   4758                         FvInFdList = self.__GetFvInFd(RefFdName)
   4759                         if FvInFdList != []:
   4760                             for FvNameInFd in FvInFdList:
   4761                                 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
   4762                                 if FvNameInFd not in RefFvList:
   4763                                     RefFvList.append(FvNameInFd)
   4764 
   4765                         FdAnalyzedList.append(RefFdName)
   4766                     #

   4767                     # the number of the parsed FV and FD image

   4768                     #

   4769                     FvListLength = len (RefFvList)
   4770                     FdListLength = len (RefFdList)
   4771                     for RefFvName in RefFvList:
   4772                         if RefFvName in FvAnalyzedList:
   4773                             continue
   4774                         LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
   4775                         if RefFvName.upper() in self.Profile.FvDict.keys():
   4776                             FvObj = self.Profile.FvDict[RefFvName.upper()]
   4777                         else:
   4778                             continue
   4779                         self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
   4780                         FvAnalyzedList.append(RefFvName)
   4781 
   4782         return False
   4783 
   4784 if __name__ == "__main__":
   4785     import sys
   4786     try:
   4787         test_file = sys.argv[1]
   4788     except IndexError, v:
   4789         print "Usage: %s filename" % sys.argv[0]
   4790         sys.exit(1)
   4791 
   4792     parser = FdfParser(test_file)
   4793     try:
   4794         parser.ParseFile()
   4795         parser.CycleReferenceCheck()
   4796     except Warning, X:
   4797         print str(X)
   4798     else:
   4799         print "Success!"
   4800 
   4801