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

      2 # parse FDF file

      3 #

      4 #  Copyright (c) 2007 - 2015, 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 
     56 from Common.Misc import tdict
     57 
     58 import re
     59 import Common.LongFilePathOs as os
     60 from Common.LongFilePathSupport import OpenLongFilePath as open
     61 
     62 ##define T_CHAR_SPACE                ' '

     63 ##define T_CHAR_NULL                 '\0'

     64 ##define T_CHAR_CR                   '\r'

     65 ##define T_CHAR_TAB                  '\t'

     66 ##define T_CHAR_LF                   '\n'

     67 ##define T_CHAR_SLASH                '/'

     68 ##define T_CHAR_BACKSLASH            '\\'

     69 ##define T_CHAR_DOUBLE_QUOTE         '\"'

     70 ##define T_CHAR_SINGLE_QUOTE         '\''

     71 ##define T_CHAR_STAR                 '*'

     72 ##define T_CHAR_HASH                 '#'

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

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

    880         MacroDict.update(GlobalData.gPlatformPcds)
    881         MacroDict.update(self.__PcdDict)
    882 
    883         # Lowest priority

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

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

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

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

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

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

    920                 #

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

    945     #

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

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

    948     #

    949     #   @param  self        The object pointer

    950     #   @param  String      The string to search

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

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

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

    954     #

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

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

    972     #

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

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

    975     #

    976     #   @param  self        The object pointer

    977     #   @param  Keyword     The string to search

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

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

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

    981     #

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

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

   1012     #

   1013     #   Get next C name from file lines

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

   1015     #

   1016     #   @param  self        The object pointer

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

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

   1019     #

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

   1044     #

   1045     #   Get next token unit before a seperator

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

   1047     #

   1048     #   @param  self        The object pointer

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

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

   1051     #

   1052     def __GetNextToken(self):
   1053         # Skip leading spaces, if exist.

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

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

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

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

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

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

   1074 #            return False

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

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

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

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

   1108     #

   1109     #   Get next token unit before a seperator

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

   1111     #

   1112     #   @param  self        The object pointer

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

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

   1115     #

   1116     def __GetNextGuid(self):
   1117 
   1118         if not self.__GetNextToken():
   1119             return False
   1120         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}')
   1121         if p.match(self.__Token) != None:
   1122             return True
   1123         else:
   1124             self.__UndoToken()
   1125             return False
   1126 
   1127     ## __UndoToken() method

   1128     #

   1129     #   Go back one token unit in file buffer

   1130     #

   1131     #   @param  self        The object pointer

   1132     #

   1133     def __UndoToken(self):
   1134         self.__UndoOneChar()
   1135         while self.__CurrentChar().isspace():
   1136             if not self.__UndoOneChar():
   1137                 self.__GetOneChar()
   1138                 return
   1139 
   1140 
   1141         StartPos = self.CurrentOffsetWithinLine
   1142         CurrentLine = self.CurrentLineNumber
   1143         while CurrentLine == self.CurrentLineNumber:
   1144 
   1145             TempChar = self.__CurrentChar()
   1146             # Try to find the end char that is not a space and not in seperator tuple.

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

   1148             if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:
   1149                 if not self.__UndoOneChar():
   1150                     return
   1151             # if we happen to meet a seperator as the first char, we must proceed to get it.

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

   1153             elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
   1154                 return
   1155             else:
   1156                 break
   1157 
   1158         self.__GetOneChar()
   1159 
   1160     ## __HexDigit() method

   1161     #

   1162     #   Whether char input is a Hex data bit

   1163     #

   1164     #   @param  self        The object pointer

   1165     #   @param  TempChar    The char to test

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

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

   1168     #

   1169     def __HexDigit(self, TempChar):
   1170         if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \
   1171                 or (TempChar >= '0' and TempChar <= '9'):
   1172                     return True
   1173         else:
   1174             return False
   1175 
   1176     def __IsHex(self, HexStr):
   1177         if not HexStr.upper().startswith("0X"):
   1178             return False
   1179         if len(self.__Token) <= 2:
   1180             return False
   1181         charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]
   1182         if len(charList) == 0:
   1183             return True
   1184         else:
   1185             return False
   1186     ## __GetNextHexNumber() method

   1187     #

   1188     #   Get next HEX data before a seperator

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

   1190     #

   1191     #   @param  self        The object pointer

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

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

   1194     #

   1195     def __GetNextHexNumber(self):
   1196         if not self.__GetNextToken():
   1197             return False
   1198         if self.__IsHex(self.__Token):
   1199             return True
   1200         else:
   1201             self.__UndoToken()
   1202             return False
   1203 
   1204     ## __GetNextDecimalNumber() method

   1205     #

   1206     #   Get next decimal data before a seperator

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

   1208     #

   1209     #   @param  self        The object pointer

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

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

   1212     #

   1213     def __GetNextDecimalNumber(self):
   1214         if not self.__GetNextToken():
   1215             return False
   1216         if self.__Token.isdigit():
   1217             return True
   1218         else:
   1219             self.__UndoToken()
   1220             return False
   1221 
   1222     ## __GetNextPcdName() method

   1223     #

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

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

   1226     #

   1227     #   @param  self        The object pointer

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

   1229     #

   1230     def __GetNextPcdName(self):
   1231         if not self.__GetNextWord():
   1232             raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
   1233         pcdTokenSpaceCName = self.__Token
   1234 
   1235         if not self.__IsToken( "."):
   1236             raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
   1237 
   1238         if not self.__GetNextWord():
   1239             raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
   1240         pcdCName = self.__Token
   1241 
   1242         return (pcdCName, pcdTokenSpaceCName)
   1243 
   1244     ## __GetStringData() method

   1245     #

   1246     #   Get string contents quoted in ""

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

   1248     #

   1249     #   @param  self        The object pointer

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

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

   1252     #

   1253     def __GetStringData(self):
   1254         if self.__Token.startswith("\"") or self.__Token.startswith("L\""):
   1255             self.__UndoToken()
   1256             self.__SkipToToken("\"")
   1257             currentLineNumber = self.CurrentLineNumber
   1258 
   1259             if not self.__SkipToToken("\""):
   1260                 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)
   1261             if currentLineNumber != self.CurrentLineNumber:
   1262                 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)
   1263             self.__Token = self.__SkippedChars.rstrip('\"')
   1264             return True
   1265 
   1266         elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):
   1267             self.__UndoToken()
   1268             self.__SkipToToken("\'")
   1269             currentLineNumber = self.CurrentLineNumber
   1270 
   1271             if not self.__SkipToToken("\'"):
   1272                 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)
   1273             if currentLineNumber != self.CurrentLineNumber:
   1274                 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)
   1275             self.__Token = self.__SkippedChars.rstrip('\'')
   1276             return True
   1277 
   1278         else:
   1279             return False
   1280 
   1281     ## __SkipToToken() method

   1282     #

   1283     #   Search forward in file buffer for the string

   1284     #   The skipped chars are put into self.__SkippedChars

   1285     #

   1286     #   @param  self        The object pointer

   1287     #   @param  String      The string to search

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

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

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

   1291     #

   1292     def __SkipToToken(self, String, IgnoreCase = False):
   1293         StartPos = self.GetFileBufferPos()
   1294 
   1295         self.__SkippedChars = ""
   1296         while not self.__EndOfFile():
   1297             index = -1
   1298             if IgnoreCase:
   1299                 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
   1300             else:
   1301                 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
   1302             if index == 0:
   1303                 self.CurrentOffsetWithinLine += len(String)
   1304                 self.__SkippedChars += String
   1305                 return True
   1306             self.__SkippedChars += str(self.__CurrentChar())
   1307             self.__GetOneChar()
   1308 
   1309         self.SetFileBufferPos( StartPos)
   1310         self.__SkippedChars = ""
   1311         return False
   1312 
   1313     ## GetFileBufferPos() method

   1314     #

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

   1316     #

   1317     #   @param  self        The object pointer

   1318     #   @retval Tuple       Line number and offset pair

   1319     #

   1320     def GetFileBufferPos(self):
   1321         return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
   1322 
   1323     ## SetFileBufferPos() method

   1324     #

   1325     #   Restore the file buffer position

   1326     #

   1327     #   @param  self        The object pointer

   1328     #   @param  Pos         The new file buffer position

   1329     #

   1330     def SetFileBufferPos(self, Pos):
   1331         (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos
   1332 
   1333     ## Preprocess() method

   1334     #

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

   1336     #   Exception will be raised if syntax error found

   1337     #

   1338     #   @param  self        The object pointer

   1339     #

   1340     def Preprocess(self):
   1341         self.__StringToList()
   1342         self.PreprocessFile()
   1343         self.PreprocessIncludeFile()
   1344         self.__StringToList()
   1345         self.PreprocessFile()
   1346         self.PreprocessConditionalStatement()
   1347         self.__StringToList()
   1348         for Pos in self.__WipeOffArea:
   1349             self.__ReplaceFragment(Pos[0], Pos[1])
   1350         self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
   1351 
   1352         while self.__GetDefines():
   1353             pass
   1354 
   1355     ## ParseFile() method

   1356     #

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

   1358     #   Exception will be raised if syntax error found

   1359     #

   1360     #   @param  self        The object pointer

   1361     #

   1362     def ParseFile(self):
   1363 
   1364         try:
   1365             self.Preprocess()
   1366             while self.__GetFd():
   1367                 pass
   1368 
   1369             while self.__GetFv():
   1370                 pass
   1371 
   1372             while self.__GetFmp():
   1373                 pass
   1374 
   1375             while self.__GetCapsule():
   1376                 pass
   1377 
   1378             while self.__GetVtf():
   1379                 pass
   1380 
   1381             while self.__GetRule():
   1382                 pass
   1383             
   1384             while self.__GetOptionRom():
   1385                 pass
   1386 
   1387         except Warning, X:
   1388             self.__UndoToken()
   1389             #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \

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

   1391             Profile = GetParentAtLine(X.OriginalLineNumber)
   1392             if Profile != None:
   1393                 X.Message += ' near line %d, column %d: %s' \
   1394                 % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])
   1395             else:
   1396                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1397                 X.Message += ' near line %d, column %d: %s' \
   1398                 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'))
   1399             raise
   1400 
   1401     ## __GetDefines() method

   1402     #

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

   1404     #

   1405     #   @param  self        The object pointer

   1406     #   @retval True        Successfully find a Defines

   1407     #   @retval False       Not able to find a Defines

   1408     #

   1409     def __GetDefines(self):
   1410 
   1411         if not self.__GetNextToken():
   1412             return False
   1413 
   1414         S = self.__Token.upper()
   1415         if S.startswith("[") and not S.startswith("[DEFINES"):
   1416             if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
   1417                 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
   1418                 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
   1419             self.__UndoToken()
   1420             return False
   1421 
   1422         self.__UndoToken()
   1423         if not self.__IsToken("[DEFINES", True):
   1424             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1425             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

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

   1427             raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)
   1428 
   1429         if not self.__IsToken( "]"):
   1430             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   1431 
   1432         while self.__GetNextWord():
   1433             # handle the SET statement

   1434             if self.__Token == 'SET':
   1435                 self.__UndoToken()
   1436                 self.__GetSetStatement(None)
   1437                 continue
   1438             
   1439             Macro = self.__Token
   1440             
   1441             if not self.__IsToken("="):
   1442                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1443             if not self.__GetNextToken() or self.__Token.startswith('['):
   1444                 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
   1445             Value = self.__Token
   1446 
   1447         return False
   1448 
   1449     ## __GetFd() method

   1450     #

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

   1452     #

   1453     #   @param  self        The object pointer

   1454     #   @retval True        Successfully find a FD

   1455     #   @retval False       Not able to find a FD

   1456     #

   1457     def __GetFd(self):
   1458 
   1459         if not self.__GetNextToken():
   1460             return False
   1461 
   1462         S = self.__Token.upper()
   1463         if S.startswith("[") and not S.startswith("[FD."):
   1464             if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
   1465                 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
   1466                 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
   1467             self.__UndoToken()
   1468             return False
   1469 
   1470         self.__UndoToken()
   1471         if not self.__IsToken("[FD.", True):
   1472             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1473             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

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

   1475             raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)
   1476 
   1477         FdName = self.__GetUiName()
   1478         if FdName == "":
   1479             if len (self.Profile.FdDict) == 0:
   1480                 FdName = GenFdsGlobalVariable.PlatformName
   1481                 if FdName == "" and GlobalData.gActivePlatform:
   1482                     FdName = GlobalData.gActivePlatform.PlatformName
   1483                 self.Profile.FdNameNotSet = True
   1484             else:
   1485                 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)
   1486         self.CurrentFdName = FdName.upper()
   1487         
   1488         if self.CurrentFdName in self.Profile.FdDict:
   1489             raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)
   1490 
   1491         if not self.__IsToken( "]"):
   1492             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   1493 
   1494         FdObj = Fd.FD()
   1495         FdObj.FdUiName = self.CurrentFdName
   1496         self.Profile.FdDict[self.CurrentFdName] = FdObj
   1497 
   1498         if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:
   1499             raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)
   1500 
   1501         Status = self.__GetCreateFile(FdObj)
   1502         if not Status:
   1503             raise Warning("FD name error", self.FileName, self.CurrentLineNumber)
   1504 
   1505         while self.__GetTokenStatements(FdObj):
   1506             pass
   1507         for Attr in ("BaseAddress", "Size", "ErasePolarity"):
   1508             if getattr(FdObj, Attr) == None:
   1509                 self.__GetNextToken()
   1510                 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)
   1511 
   1512         if not FdObj.BlockSizeList:
   1513             FdObj.BlockSizeList.append((1, FdObj.Size, None))
   1514 
   1515         self.__GetDefineStatements(FdObj)
   1516 
   1517         self.__GetSetStatements(FdObj)
   1518 
   1519         if not self.__GetRegionLayout(FdObj):
   1520             raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)
   1521 
   1522         while self.__GetRegionLayout(FdObj):
   1523             pass
   1524         return True
   1525 
   1526     ## __GetUiName() method

   1527     #

   1528     #   Return the UI name of a section

   1529     #

   1530     #   @param  self        The object pointer

   1531     #   @retval FdName      UI name

   1532     #

   1533     def __GetUiName(self):
   1534         Name = ""
   1535         if self.__GetNextWord():
   1536             Name = self.__Token
   1537 
   1538         return Name
   1539 
   1540     ## __GetCreateFile() method

   1541     #

   1542     #   Return the output file name of object

   1543     #

   1544     #   @param  self        The object pointer

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

   1546     #   @retval FdName      UI name

   1547     #

   1548     def __GetCreateFile(self, Obj):
   1549 
   1550         if self.__IsKeyword( "CREATE_FILE"):
   1551             if not self.__IsToken( "="):
   1552                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1553 
   1554             if not self.__GetNextToken():
   1555                 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
   1556 
   1557             FileName = self.__Token
   1558             Obj.CreateFileName = FileName
   1559 
   1560         return True
   1561 
   1562     ## __GetTokenStatements() method

   1563     #

   1564     #   Get token statements

   1565     #

   1566     #   @param  self        The object pointer

   1567     #   @param  Obj         for whom token statement is got

   1568     #

   1569     def __GetTokenStatements(self, Obj):
   1570         if self.__IsKeyword( "BaseAddress"):
   1571             if not self.__IsToken( "="):
   1572                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1573     
   1574             if not self.__GetNextHexNumber():
   1575                 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
   1576     
   1577             Obj.BaseAddress = self.__Token
   1578     
   1579             if self.__IsToken( "|"):
   1580                 pcdPair = self.__GetNextPcdName()
   1581                 Obj.BaseAddressPcd = pcdPair
   1582                 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
   1583                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1584                 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
   1585             return True
   1586 
   1587         if self.__IsKeyword( "Size"):
   1588             if not self.__IsToken( "="):
   1589                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1590     
   1591             if not self.__GetNextHexNumber():
   1592                 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
   1593 
   1594             Size = self.__Token
   1595             if self.__IsToken( "|"):
   1596                 pcdPair = self.__GetNextPcdName()
   1597                 Obj.SizePcd = pcdPair
   1598                 self.Profile.PcdDict[pcdPair] = Size
   1599                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1600                 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
   1601             Obj.Size = long(Size, 0)
   1602             return True
   1603 
   1604         if self.__IsKeyword( "ErasePolarity"):
   1605             if not self.__IsToken( "="):
   1606                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1607     
   1608             if not self.__GetNextToken():
   1609                 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
   1610     
   1611             if self.__Token != "1" and self.__Token != "0":
   1612                 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
   1613     
   1614             Obj.ErasePolarity = self.__Token
   1615             return True
   1616 
   1617         return self.__GetBlockStatements(Obj)
   1618 
   1619     ## __GetAddressStatements() method

   1620     #

   1621     #   Get address statements

   1622     #

   1623     #   @param  self        The object pointer

   1624     #   @param  Obj         for whom address statement is got

   1625     #   @retval True        Successfully find

   1626     #   @retval False       Not able to find

   1627     #

   1628     def __GetAddressStatements(self, Obj):
   1629 
   1630         if self.__IsKeyword("BsBaseAddress"):
   1631             if not self.__IsToken( "="):
   1632                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1633 
   1634             if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
   1635                 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
   1636 
   1637             BsAddress = long(self.__Token, 0)
   1638             Obj.BsBaseAddress = BsAddress
   1639 
   1640         if self.__IsKeyword("RtBaseAddress"):
   1641             if not self.__IsToken( "="):
   1642                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1643 
   1644             if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
   1645                 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
   1646 
   1647             RtAddress = long(self.__Token, 0)
   1648             Obj.RtBaseAddress = RtAddress
   1649 
   1650     ## __GetBlockStatements() method

   1651     #

   1652     #   Get block statements

   1653     #

   1654     #   @param  self        The object pointer

   1655     #   @param  Obj         for whom block statement is got

   1656     #

   1657     def __GetBlockStatements(self, Obj):
   1658         IsBlock = False
   1659         while self.__GetBlockStatement(Obj):
   1660             IsBlock = True
   1661         
   1662             Item = Obj.BlockSizeList[-1]
   1663             if Item[0] == None or Item[1] == None:
   1664                 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)
   1665         return IsBlock
   1666 
   1667     ## __GetBlockStatement() method

   1668     #

   1669     #   Get block statement

   1670     #

   1671     #   @param  self        The object pointer

   1672     #   @param  Obj         for whom block statement is got

   1673     #   @retval True        Successfully find

   1674     #   @retval False       Not able to find

   1675     #

   1676     def __GetBlockStatement(self, Obj):
   1677         if not self.__IsKeyword( "BlockSize"):
   1678             return False
   1679 
   1680         if not self.__IsToken( "="):
   1681             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1682 
   1683         if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
   1684             raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)
   1685 
   1686         BlockSize = self.__Token
   1687         BlockSizePcd = None
   1688         if self.__IsToken( "|"):
   1689             PcdPair = self.__GetNextPcdName()
   1690             BlockSizePcd = PcdPair
   1691             self.Profile.PcdDict[PcdPair] = BlockSize
   1692             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1693             self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
   1694         BlockSize = long(BlockSize, 0)
   1695 
   1696         BlockNumber = None
   1697         if self.__IsKeyword( "NumBlocks"):
   1698             if not self.__IsToken( "="):
   1699                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1700 
   1701             if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
   1702                 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)
   1703 
   1704             BlockNumber = long(self.__Token, 0)
   1705 
   1706         Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
   1707         return True
   1708 
   1709     ## __GetDefineStatements() method

   1710     #

   1711     #   Get define statements

   1712     #

   1713     #   @param  self        The object pointer

   1714     #   @param  Obj         for whom define statement is got

   1715     #   @retval True        Successfully find

   1716     #   @retval False       Not able to find

   1717     #

   1718     def __GetDefineStatements(self, Obj):
   1719         while self.__GetDefineStatement( Obj):
   1720             pass
   1721 
   1722     ## __GetDefineStatement() method

   1723     #

   1724     #   Get define statement

   1725     #

   1726     #   @param  self        The object pointer

   1727     #   @param  Obj         for whom define statement is got

   1728     #   @retval True        Successfully find

   1729     #   @retval False       Not able to find

   1730     #

   1731     def __GetDefineStatement(self, Obj):
   1732         if self.__IsKeyword("DEFINE"):
   1733             self.__GetNextToken()
   1734             Macro = self.__Token
   1735             if not self.__IsToken( "="):
   1736                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1737 
   1738             if not self.__GetNextToken():
   1739                 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
   1740 
   1741             Value = self.__Token
   1742             Macro = '$(' + Macro + ')'
   1743             Obj.DefineVarDict[Macro] = Value
   1744             return True
   1745 
   1746         return False
   1747 
   1748     ## __GetSetStatements() method

   1749     #

   1750     #   Get set statements

   1751     #

   1752     #   @param  self        The object pointer

   1753     #   @param  Obj         for whom set statement is got

   1754     #   @retval True        Successfully find

   1755     #   @retval False       Not able to find

   1756     #

   1757     def __GetSetStatements(self, Obj):
   1758         while self.__GetSetStatement(Obj):
   1759             pass
   1760 
   1761     ## __GetSetStatement() method

   1762     #

   1763     #   Get set statement

   1764     #

   1765     #   @param  self        The object pointer

   1766     #   @param  Obj         for whom set statement is got

   1767     #   @retval True        Successfully find

   1768     #   @retval False       Not able to find

   1769     #

   1770     def __GetSetStatement(self, Obj):
   1771         if self.__IsKeyword("SET"):
   1772             PcdPair = self.__GetNextPcdName()
   1773 
   1774             if not self.__IsToken( "="):
   1775                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1776 
   1777             Value = self.__GetExpression()
   1778             Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
   1779 
   1780             if Obj:
   1781                 Obj.SetVarDict[PcdPair] = Value
   1782             self.Profile.PcdDict[PcdPair] = Value
   1783             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1784             self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
   1785             return True
   1786 
   1787         return False
   1788 
   1789     ## __CalcRegionExpr(self)

   1790     #

   1791     #   Calculate expression for offset or size of a region

   1792     #

   1793     #   @return: None if invalid expression

   1794     #            Calculated number if successfully

   1795     #

   1796     def __CalcRegionExpr(self):
   1797         StartPos = self.GetFileBufferPos()
   1798         Expr = ''
   1799         PairCount = 0
   1800         while not self.__EndOfFile():
   1801             CurCh = self.__CurrentChar()
   1802             if CurCh == '(':
   1803                 PairCount += 1
   1804             elif CurCh == ')':
   1805                 PairCount -= 1
   1806 
   1807             if CurCh in '|\r\n' and PairCount == 0:
   1808                 break
   1809             Expr += CurCh
   1810             self.__GetOneChar()
   1811         try:
   1812             return long(
   1813                 ValueExpression(Expr,
   1814                                 self.__CollectMacroPcd()
   1815                                 )(True),0)
   1816         except Exception:
   1817             self.SetFileBufferPos(StartPos)
   1818             return None
   1819 
   1820     ## __GetRegionLayout() method

   1821     #

   1822     #   Get region layout for FD

   1823     #

   1824     #   @param  self        The object pointer

   1825     #   @param  Fd          for whom region is got

   1826     #   @retval True        Successfully find

   1827     #   @retval False       Not able to find

   1828     #

   1829     def __GetRegionLayout(self, Fd):
   1830         Offset = self.__CalcRegionExpr() 
   1831         if Offset == None:
   1832             return False
   1833 
   1834         RegionObj = Region.Region()
   1835         RegionObj.Offset = Offset
   1836         Fd.RegionList.append(RegionObj)
   1837 
   1838         if not self.__IsToken( "|"):
   1839             raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)
   1840 
   1841         Size = self.__CalcRegionExpr()
   1842         if Size == None:
   1843             raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)
   1844         RegionObj.Size = Size
   1845 
   1846         if not self.__GetNextWord():
   1847             return True
   1848 
   1849         if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
   1850             #

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

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

   1853             #    PcdOffset[|PcdSize] or OffsetPcdExpression|Size

   1854             #

   1855             self.__UndoToken()
   1856             IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or
   1857                            RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))
   1858             if IsRegionPcd:
   1859                 RegionObj.PcdOffset = self.__GetNextPcdName()
   1860                 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
   1861                 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset
   1862                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1863                 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
   1864                 if self.__IsToken( "|"):
   1865                     RegionObj.PcdSize = self.__GetNextPcdName()
   1866                     self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
   1867                     self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size
   1868                     FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   1869                     self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
   1870 
   1871             if not self.__GetNextWord():
   1872                 return True
   1873 
   1874         if self.__Token == "SET":
   1875             self.__UndoToken()
   1876             self.__GetSetStatements( RegionObj)
   1877             if not self.__GetNextWord():
   1878                 return True
   1879 
   1880         elif self.__Token == "FV":
   1881             self.__UndoToken()
   1882             self.__GetRegionFvType( RegionObj)
   1883 
   1884         elif self.__Token == "CAPSULE":
   1885             self.__UndoToken()
   1886             self.__GetRegionCapType( RegionObj)
   1887 
   1888         elif self.__Token == "FILE":
   1889             self.__UndoToken()
   1890             self.__GetRegionFileType(RegionObj)
   1891 
   1892         elif self.__Token == "INF":
   1893             self.__UndoToken()
   1894             RegionObj.RegionType = "INF"
   1895             while self.__IsKeyword("INF"):
   1896                 self.__UndoToken()
   1897                 ffsInf = self.__ParseInfStatement()
   1898                 if not ffsInf:
   1899                     break
   1900                 RegionObj.RegionDataList.append(ffsInf)
   1901 
   1902         elif self.__Token == "DATA":
   1903             self.__UndoToken()
   1904             self.__GetRegionDataType(RegionObj)
   1905         else:
   1906             self.__UndoToken()
   1907             if self.__GetRegionLayout(Fd):
   1908                 return True
   1909             raise Warning("A valid region type was not found. "
   1910                           "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
   1911                           self.FileName, self.CurrentLineNumber)
   1912 
   1913         return True
   1914 
   1915     ## __GetRegionFvType() method

   1916     #

   1917     #   Get region fv data for region

   1918     #

   1919     #   @param  self        The object pointer

   1920     #   @param  RegionObj   for whom region data is got

   1921     #

   1922     def __GetRegionFvType(self, RegionObj):
   1923 
   1924         if not self.__IsKeyword( "FV"):
   1925             raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)
   1926 
   1927         if not self.__IsToken( "="):
   1928             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1929 
   1930         if not self.__GetNextToken():
   1931             raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
   1932 
   1933         RegionObj.RegionType = "FV"
   1934         RegionObj.RegionDataList.append(self.__Token)
   1935 
   1936         while self.__IsKeyword( "FV"):
   1937 
   1938             if not self.__IsToken( "="):
   1939                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1940 
   1941             if not self.__GetNextToken():
   1942                 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
   1943 
   1944             RegionObj.RegionDataList.append(self.__Token)
   1945 
   1946     ## __GetRegionCapType() method

   1947     #

   1948     #   Get region capsule data for region

   1949     #

   1950     #   @param  self        The object pointer

   1951     #   @param  RegionObj   for whom region data is got

   1952     #

   1953     def __GetRegionCapType(self, RegionObj):
   1954 
   1955         if not self.__IsKeyword("CAPSULE"):
   1956             raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)
   1957 
   1958         if not self.__IsToken("="):
   1959             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1960 
   1961         if not self.__GetNextToken():
   1962             raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
   1963 
   1964         RegionObj.RegionType = "CAPSULE"
   1965         RegionObj.RegionDataList.append(self.__Token)
   1966 
   1967         while self.__IsKeyword("CAPSULE"):
   1968 
   1969             if not self.__IsToken("="):
   1970                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1971 
   1972             if not self.__GetNextToken():
   1973                 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
   1974 
   1975             RegionObj.RegionDataList.append(self.__Token)
   1976 
   1977     ## __GetRegionFileType() method

   1978     #

   1979     #   Get region file data for region

   1980     #

   1981     #   @param  self        The object pointer

   1982     #   @param  RegionObj   for whom region data is got

   1983     #

   1984     def __GetRegionFileType(self, RegionObj):
   1985 
   1986         if not self.__IsKeyword( "FILE"):
   1987             raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)
   1988 
   1989         if not self.__IsToken( "="):
   1990             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   1991 
   1992         if not self.__GetNextToken():
   1993             raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
   1994 
   1995         RegionObj.RegionType = "FILE"
   1996         RegionObj.RegionDataList.append( self.__Token)
   1997 
   1998         while self.__IsKeyword( "FILE"):
   1999 
   2000             if not self.__IsToken( "="):
   2001                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2002 
   2003             if not self.__GetNextToken():
   2004                 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)
   2005 
   2006             RegionObj.RegionDataList.append(self.__Token)
   2007 
   2008     ## __GetRegionDataType() method

   2009     #

   2010     #   Get region array data for region

   2011     #

   2012     #   @param  self        The object pointer

   2013     #   @param  RegionObj   for whom region data is got

   2014     #

   2015     def __GetRegionDataType(self, RegionObj):
   2016 
   2017         if not self.__IsKeyword( "DATA"):
   2018             raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)
   2019 
   2020         if not self.__IsToken( "="):
   2021             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2022 
   2023         if not self.__IsToken( "{"):
   2024             raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2025 
   2026         if not self.__GetNextHexNumber():
   2027             raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
   2028 
   2029         if len(self.__Token) > 18:
   2030             raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
   2031 
   2032         # convert hex string value to byte hex string array

   2033         AllString = self.__Token
   2034         AllStrLen = len (AllString)
   2035         DataString = ""
   2036         while AllStrLen > 4:
   2037             DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
   2038             AllStrLen  = AllStrLen - 2
   2039         DataString = DataString + AllString[:AllStrLen] + ","
   2040 
   2041         # byte value array

   2042         if len (self.__Token) <= 4:
   2043             while self.__IsToken(","):
   2044                 if not self.__GetNextHexNumber():
   2045                     raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
   2046                 if len(self.__Token) > 4:
   2047                     raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
   2048                 DataString += self.__Token
   2049                 DataString += ","
   2050 
   2051         if not self.__IsToken( "}"):
   2052             raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2053 
   2054         DataString = DataString.rstrip(",")
   2055         RegionObj.RegionType = "DATA"
   2056         RegionObj.RegionDataList.append( DataString)
   2057 
   2058         while self.__IsKeyword( "DATA"):
   2059 
   2060             if not self.__IsToken( "="):
   2061                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2062 
   2063             if not self.__IsToken( "{"):
   2064                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2065 
   2066             if not self.__GetNextHexNumber():
   2067                 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
   2068 
   2069             if len(self.__Token) > 18:
   2070                 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
   2071 
   2072             # convert hex string value to byte hex string array

   2073             AllString = self.__Token
   2074             AllStrLen = len (AllString)
   2075             DataString = ""
   2076             while AllStrLen > 4:
   2077                 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
   2078                 AllStrLen  = AllStrLen - 2
   2079             DataString = DataString + AllString[:AllStrLen] + ","
   2080 
   2081             # byte value array

   2082             if len (self.__Token) <= 4:
   2083                 while self.__IsToken(","):
   2084                     if not self.__GetNextHexNumber():
   2085                         raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
   2086                     if len(self.__Token) > 4:
   2087                         raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
   2088                     DataString += self.__Token
   2089                     DataString += ","
   2090 
   2091             if not self.__IsToken( "}"):
   2092                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2093 
   2094             DataString = DataString.rstrip(",")
   2095             RegionObj.RegionDataList.append( DataString)
   2096 
   2097     ## __GetFv() method

   2098     #

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

   2100     #

   2101     #   @param  self        The object pointer

   2102     #   @retval True        Successfully find a FV

   2103     #   @retval False       Not able to find a FV

   2104     #

   2105     def __GetFv(self):
   2106         if not self.__GetNextToken():
   2107             return False
   2108 
   2109         S = self.__Token.upper()
   2110         if S.startswith("[") and not S.startswith("[FV."):
   2111             if not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
   2112                 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
   2113                 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
   2114             self.__UndoToken()
   2115             return False
   2116 
   2117         self.__UndoToken()
   2118         if not self.__IsToken("[FV.", True):
   2119             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   2120             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

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

   2122             raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2123 
   2124         FvName = self.__GetUiName()
   2125         self.CurrentFvName = FvName.upper()
   2126 
   2127         if not self.__IsToken( "]"):
   2128             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   2129 
   2130         FvObj = Fv.FV()
   2131         FvObj.UiFvName = self.CurrentFvName
   2132         self.Profile.FvDict[self.CurrentFvName] = FvObj
   2133 
   2134         Status = self.__GetCreateFile(FvObj)
   2135         if not Status:
   2136             raise Warning("FV name error", self.FileName, self.CurrentLineNumber)
   2137 
   2138         self.__GetDefineStatements(FvObj)
   2139 
   2140         self.__GetAddressStatements(FvObj)
   2141 
   2142         FvObj.FvExtEntryTypeValue = []
   2143         FvObj.FvExtEntryType = []
   2144         FvObj.FvExtEntryData = []
   2145         while True:
   2146             self.__GetSetStatements(FvObj)
   2147 
   2148             if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or 
   2149                 self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or 
   2150                 self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or 
   2151                 self.__GetFvExtEntryStatement(FvObj) or self.__GetFvNameString(FvObj)):
   2152                 break
   2153 
   2154         if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:
   2155             raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)
   2156 
   2157         self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
   2158         self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
   2159 
   2160         while True:
   2161             isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
   2162             isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
   2163             if not isInf and not isFile:
   2164                 break
   2165 
   2166         return True
   2167 
   2168     ## __GetFvAlignment() method

   2169     #

   2170     #   Get alignment for FV

   2171     #

   2172     #   @param  self        The object pointer

   2173     #   @param  Obj         for whom alignment is got

   2174     #   @retval True        Successfully find a alignment statement

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

   2176     #

   2177     def __GetFvAlignment(self, Obj):
   2178 
   2179         if not self.__IsKeyword( "FvAlignment"):
   2180             return False
   2181 
   2182         if not self.__IsToken( "="):
   2183             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2184 
   2185         if not self.__GetNextToken():
   2186             raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
   2187 
   2188         if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
   2189                                         "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
   2190                                         "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
   2191                                         "1G", "2G"):
   2192             raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2193         Obj.FvAlignment = self.__Token
   2194         return True
   2195     
   2196     ## __GetFvBaseAddress() method

   2197     #

   2198     #   Get BaseAddress for FV

   2199     #

   2200     #   @param  self        The object pointer

   2201     #   @param  Obj         for whom FvBaseAddress is got

   2202     #   @retval True        Successfully find a FvBaseAddress statement

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

   2204     #

   2205     def __GetFvBaseAddress(self, Obj):
   2206 
   2207         if not self.__IsKeyword("FvBaseAddress"):
   2208             return False
   2209 
   2210         if not self.__IsToken( "="):
   2211             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2212 
   2213         if not self.__GetNextToken():
   2214             raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)
   2215 
   2216         IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')
   2217 
   2218         if not IsValidBaseAddrValue.match(self.__Token.upper()):
   2219             raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2220         Obj.FvBaseAddress = self.__Token
   2221         return True  
   2222       
   2223     ## __GetFvForceRebase() method

   2224     #

   2225     #   Get FvForceRebase for FV

   2226     #

   2227     #   @param  self        The object pointer

   2228     #   @param  Obj         for whom FvForceRebase is got

   2229     #   @retval True        Successfully find a FvForceRebase statement

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

   2231     #

   2232     def __GetFvForceRebase(self, Obj):
   2233 
   2234         if not self.__IsKeyword("FvForceRebase"):
   2235             return False
   2236 
   2237         if not self.__IsToken( "="):
   2238             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2239 
   2240         if not self.__GetNextToken():
   2241             raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)
   2242 
   2243         if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
   2244             raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2245         
   2246         if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:
   2247             Obj.FvForceRebase = True
   2248         elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:
   2249             Obj.FvForceRebase = False
   2250         else:
   2251             Obj.FvForceRebase = None
   2252            
   2253         return True
   2254 
   2255 
   2256     ## __GetFvAttributes() method

   2257     #

   2258     #   Get attributes for FV

   2259     #

   2260     #   @param  self        The object pointer

   2261     #   @param  Obj         for whom attribute is got

   2262     #   @retval None

   2263     #

   2264     def __GetFvAttributes(self, FvObj):
   2265         IsWordToken = False
   2266         while self.__GetNextWord():
   2267             IsWordToken = True
   2268             name = self.__Token
   2269             if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
   2270                            "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
   2271                            "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
   2272                            "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
   2273                            "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
   2274                            "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):
   2275                 self.__UndoToken()
   2276                 return False
   2277 
   2278             if not self.__IsToken( "="):
   2279                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2280 
   2281             if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
   2282                 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
   2283 
   2284             FvObj.FvAttributeDict[name] = self.__Token
   2285 
   2286         return IsWordToken
   2287     
   2288     ## __GetFvNameGuid() method

   2289     #

   2290     #   Get FV GUID for FV

   2291     #

   2292     #   @param  self        The object pointer

   2293     #   @param  Obj         for whom GUID is got

   2294     #   @retval None

   2295     #

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

   2400     #

   2401     #   Get token statements

   2402     #

   2403     #   @param  self        The object pointer

   2404     #   @param  FvObj       for whom apriori is got

   2405     #   @param  MacroDict   dictionary used to replace macro

   2406     #   @retval True        Successfully find apriori statement

   2407     #   @retval False       Not able to find apriori statement

   2408     #

   2409     def __GetAprioriSection(self, FvObj, MacroDict = {}):
   2410 
   2411         if not self.__IsKeyword( "APRIORI"):
   2412             return False
   2413 
   2414         if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):
   2415             raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)
   2416         AprType = self.__Token
   2417 
   2418         if not self.__IsToken( "{"):
   2419             raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2420 
   2421         AprSectionObj = AprioriSection.AprioriSection()
   2422         AprSectionObj.AprioriType = AprType
   2423 
   2424         self.__GetDefineStatements(AprSectionObj)
   2425         MacroDict.update(AprSectionObj.DefineVarDict)
   2426 
   2427         while True:
   2428             IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)
   2429             IsFile = self.__GetFileStatement( AprSectionObj)
   2430             if not IsInf and not IsFile:
   2431                 break
   2432 
   2433         if not self.__IsToken( "}"):
   2434             raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2435 
   2436         FvObj.AprioriSectionList.append(AprSectionObj)
   2437         return True
   2438 
   2439     def __ParseInfStatement(self):
   2440         if not self.__IsKeyword("INF"):
   2441             return None
   2442 
   2443         ffsInf = FfsInfStatement.FfsInfStatement()
   2444         self.__GetInfOptions(ffsInf)
   2445 
   2446         if not self.__GetNextToken():
   2447             raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
   2448         ffsInf.InfFileName = self.__Token
   2449 
   2450         ffsInf.CurrentLineNum = self.CurrentLineNumber
   2451         ffsInf.CurrentLineContent = self.__CurrentLine()
   2452 
   2453         #Replace $(SAPCE) with real space

   2454         ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')
   2455 
   2456         if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
   2457             #do case sensitive check for file path

   2458             ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   2459             if ErrorCode != 0:
   2460                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   2461 
   2462         if not ffsInf.InfFileName in self.Profile.InfList:
   2463             self.Profile.InfList.append(ffsInf.InfFileName)
   2464             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   2465             self.Profile.InfFileLineList.append(FileLineTuple)
   2466 
   2467         if self.__IsToken('|'):
   2468             if self.__IsKeyword('RELOCS_STRIPPED'):
   2469                 ffsInf.KeepReloc = False
   2470             elif self.__IsKeyword('RELOCS_RETAINED'):
   2471                 ffsInf.KeepReloc = True
   2472             else:
   2473                 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2474         return ffsInf
   2475 
   2476     ## __GetInfStatement() method

   2477     #

   2478     #   Get INF statements

   2479     #

   2480     #   @param  self        The object pointer

   2481     #   @param  Obj         for whom inf statement is got

   2482     #   @param  MacroDict   dictionary used to replace macro

   2483     #   @retval True        Successfully find inf statement

   2484     #   @retval False       Not able to find inf statement

   2485     #

   2486     def __GetInfStatement(self, Obj, ForCapsule=False, MacroDict={}):
   2487         ffsInf = self.__ParseInfStatement()
   2488         if not ffsInf:
   2489             return False
   2490 
   2491         if ForCapsule:
   2492             capsuleFfs = CapsuleData.CapsuleFfs()
   2493             capsuleFfs.Ffs = ffsInf
   2494             Obj.CapsuleDataList.append(capsuleFfs)
   2495         else:
   2496             Obj.FfsList.append(ffsInf)
   2497         return True
   2498 
   2499     ## __GetInfOptions() method

   2500     #

   2501     #   Get options for INF

   2502     #

   2503     #   @param  self        The object pointer

   2504     #   @param  FfsInfObj   for whom option is got

   2505     #

   2506     def __GetInfOptions(self, FfsInfObj):
   2507         if self.__IsKeyword("FILE_GUID"):
   2508             if not self.__IsToken("="):
   2509                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2510             if not self.__GetNextGuid():
   2511                 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)
   2512             FfsInfObj.OverrideGuid = self.__Token
   2513 
   2514         if self.__IsKeyword( "RuleOverride"):
   2515             if not self.__IsToken( "="):
   2516                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2517             if not self.__GetNextToken():
   2518                 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)
   2519             FfsInfObj.Rule = self.__Token
   2520 
   2521         if self.__IsKeyword( "VERSION"):
   2522             if not self.__IsToken( "="):
   2523                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2524             if not self.__GetNextToken():
   2525                 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)
   2526 
   2527             if self.__GetStringData():
   2528                 FfsInfObj.Version = self.__Token
   2529 
   2530         if self.__IsKeyword( "UI"):
   2531             if not self.__IsToken( "="):
   2532                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2533             if not self.__GetNextToken():
   2534                 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)
   2535 
   2536             if self.__GetStringData():
   2537                 FfsInfObj.Ui = self.__Token
   2538 
   2539         if self.__IsKeyword( "USE"):
   2540             if not self.__IsToken( "="):
   2541                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2542             if not self.__GetNextToken():
   2543                 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)
   2544             FfsInfObj.UseArch = self.__Token
   2545 
   2546                 
   2547         if self.__GetNextToken():
   2548             p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
   2549             if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):
   2550                 FfsInfObj.KeyStringList.append(self.__Token)
   2551                 if not self.__IsToken(","):
   2552                     return
   2553             else:
   2554                 self.__UndoToken()
   2555                 return
   2556 
   2557             while self.__GetNextToken():
   2558                 if not p.match(self.__Token):
   2559                     raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
   2560                 FfsInfObj.KeyStringList.append(self.__Token)
   2561 
   2562                 if not self.__IsToken(","):
   2563                     break
   2564 
   2565     ## __GetFileStatement() method

   2566     #

   2567     #   Get FILE statements

   2568     #

   2569     #   @param  self        The object pointer

   2570     #   @param  Obj         for whom FILE statement is got

   2571     #   @param  MacroDict   dictionary used to replace macro

   2572     #   @retval True        Successfully find FILE statement

   2573     #   @retval False       Not able to find FILE statement

   2574     #

   2575     def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):
   2576 
   2577         if not self.__IsKeyword( "FILE"):
   2578             return False
   2579 
   2580         if not self.__GetNextWord():
   2581             raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
   2582 
   2583         if ForCapsule and self.__Token == 'DATA':
   2584             self.__UndoToken()
   2585             self.__UndoToken()
   2586             return False
   2587         
   2588         FfsFileObj = FfsFileStatement.FileStatement()
   2589         FfsFileObj.FvFileType = self.__Token
   2590 
   2591         if not self.__IsToken( "="):
   2592             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2593 
   2594         if not self.__GetNextGuid():
   2595             if not self.__GetNextWord():
   2596                 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
   2597             if self.__Token == 'PCD':
   2598                 if not self.__IsToken( "("):
   2599                     raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
   2600                 PcdPair = self.__GetNextPcdName()
   2601                 if not self.__IsToken( ")"):
   2602                     raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
   2603                 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
   2604                 
   2605         FfsFileObj.NameGuid = self.__Token
   2606         
   2607         self.__GetFilePart( FfsFileObj, MacroDict.copy())
   2608 
   2609         if ForCapsule:
   2610             capsuleFfs = CapsuleData.CapsuleFfs()
   2611             capsuleFfs.Ffs = FfsFileObj
   2612             Obj.CapsuleDataList.append(capsuleFfs)
   2613         else:
   2614             Obj.FfsList.append(FfsFileObj)
   2615 
   2616         return True
   2617 
   2618     ## __FileCouldHaveRelocFlag() method

   2619     #

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

   2621     #

   2622     #   @param  self        The object pointer

   2623     #   @param  FileType    The file type to check with

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

   2625     #   @retval False       No way to have it

   2626     #

   2627 
   2628     def __FileCouldHaveRelocFlag (self, FileType):
   2629         if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
   2630             return True
   2631         else:
   2632             return False
   2633 
   2634     ## __SectionCouldHaveRelocFlag() method

   2635     #

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

   2637     #

   2638     #   @param  self        The object pointer

   2639     #   @param  SectionType The section type to check with

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

   2641     #   @retval False       No way to have it

   2642     #

   2643 
   2644     def __SectionCouldHaveRelocFlag (self, SectionType):
   2645         if SectionType in ('TE', 'PE32'):
   2646             return True
   2647         else:
   2648             return False
   2649 
   2650     ## __GetFilePart() method

   2651     #

   2652     #   Get components for FILE statement

   2653     #

   2654     #   @param  self        The object pointer

   2655     #   @param  FfsFileObj   for whom component is got

   2656     #   @param  MacroDict   dictionary used to replace macro

   2657     #

   2658     def __GetFilePart(self, FfsFileObj, MacroDict = {}):
   2659 
   2660         self.__GetFileOpts( FfsFileObj)
   2661 
   2662         if not self.__IsToken("{"):
   2663             if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
   2664                 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
   2665                     if self.__Token == 'RELOCS_STRIPPED':
   2666                         FfsFileObj.KeepReloc = False
   2667                     else:
   2668                         FfsFileObj.KeepReloc = True
   2669                 else:
   2670                     raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   2671 
   2672             if not self.__IsToken("{"):
   2673                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2674 
   2675         if not self.__GetNextToken():
   2676             raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)
   2677 
   2678         if self.__Token == "FV":
   2679             if not self.__IsToken( "="):
   2680                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2681             if not self.__GetNextToken():
   2682                 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
   2683             FfsFileObj.FvName = self.__Token
   2684 
   2685         elif self.__Token == "FD":
   2686             if not self.__IsToken( "="):
   2687                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2688             if not self.__GetNextToken():
   2689                 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
   2690             FfsFileObj.FdName = self.__Token
   2691 
   2692         elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):
   2693             self.__UndoToken()
   2694             self.__GetSectionData( FfsFileObj, MacroDict)
   2695         else:
   2696             FfsFileObj.CurrentLineNum = self.CurrentLineNumber
   2697             FfsFileObj.CurrentLineContent = self.__CurrentLine()
   2698             FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')
   2699             self.__VerifyFile(FfsFileObj.FileName)
   2700 
   2701         if not self.__IsToken( "}"):
   2702             raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2703 
   2704     ## __GetFileOpts() method

   2705     #

   2706     #   Get options for FILE statement

   2707     #

   2708     #   @param  self        The object pointer

   2709     #   @param  FfsFileObj   for whom options is got

   2710     #

   2711     def __GetFileOpts(self, FfsFileObj):
   2712 
   2713         if self.__GetNextToken():
   2714             Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
   2715             if Pattern.match(self.__Token):
   2716                 FfsFileObj.KeyStringList.append(self.__Token)
   2717                 if self.__IsToken(","):
   2718                     while self.__GetNextToken():
   2719                         if not Pattern.match(self.__Token):
   2720                             raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
   2721                         FfsFileObj.KeyStringList.append(self.__Token)
   2722 
   2723                         if not self.__IsToken(","):
   2724                             break
   2725 
   2726             else:
   2727                 self.__UndoToken()
   2728 
   2729         if self.__IsKeyword( "FIXED", True):
   2730             FfsFileObj.Fixed = True
   2731 
   2732         if self.__IsKeyword( "CHECKSUM", True):
   2733             FfsFileObj.CheckSum = True
   2734 
   2735         if self.__GetAlignment():
   2736             if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   2737                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2738             #For FFS, Auto is default option same to ""

   2739             if not self.__Token == "Auto":
   2740                 FfsFileObj.Alignment = self.__Token
   2741 
   2742     ## __GetAlignment() method

   2743     #

   2744     #   Return the alignment value

   2745     #

   2746     #   @param  self        The object pointer

   2747     #   @retval True        Successfully find alignment

   2748     #   @retval False       Not able to find alignment

   2749     #

   2750     def __GetAlignment(self):
   2751         if self.__IsKeyword( "Align", True):
   2752             if not self.__IsToken( "="):
   2753                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2754 
   2755             if not self.__GetNextToken():
   2756                 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
   2757             return True
   2758 
   2759         return False
   2760 
   2761     ## __GetFilePart() method

   2762     #

   2763     #   Get section data for FILE statement

   2764     #

   2765     #   @param  self        The object pointer

   2766     #   @param  FfsFileObj   for whom section is got

   2767     #   @param  MacroDict   dictionary used to replace macro

   2768     #

   2769     def __GetSectionData(self, FfsFileObj, MacroDict = {}):
   2770         Dict = {}
   2771         Dict.update(MacroDict)
   2772 
   2773         self.__GetDefineStatements(FfsFileObj)
   2774 
   2775         Dict.update(FfsFileObj.DefineVarDict)
   2776         self.__GetAprioriSection(FfsFileObj, Dict.copy())
   2777         self.__GetAprioriSection(FfsFileObj, Dict.copy())
   2778 
   2779         while True:
   2780             IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)
   2781             IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)
   2782             if not IsLeafSection and not IsEncapSection:
   2783                 break
   2784 
   2785     ## __GetLeafSection() method

   2786     #

   2787     #   Get leaf section for Obj

   2788     #

   2789     #   @param  self        The object pointer

   2790     #   @param  Obj         for whom leaf section is got

   2791     #   @param  MacroDict   dictionary used to replace macro

   2792     #   @retval True        Successfully find section statement

   2793     #   @retval False       Not able to find section statement

   2794     #

   2795     def __GetLeafSection(self, Obj, MacroDict = {}):
   2796 
   2797         OldPos = self.GetFileBufferPos()
   2798 
   2799         if not self.__IsKeyword( "SECTION"):
   2800             if len(Obj.SectionList) == 0:
   2801                 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
   2802             else:
   2803                 return False
   2804 
   2805         AlignValue = None
   2806         if self.__GetAlignment():
   2807             if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   2808                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2809             AlignValue = self.__Token
   2810 
   2811         BuildNum = None
   2812         if self.__IsKeyword( "BUILD_NUM"):
   2813             if not self.__IsToken( "="):
   2814                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2815 
   2816             if not self.__GetNextToken():
   2817                 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)
   2818 
   2819             BuildNum = self.__Token
   2820 
   2821         if self.__IsKeyword( "VERSION"):
   2822             if AlignValue == 'Auto':
   2823                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2824             if not self.__IsToken( "="):
   2825                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2826             if not self.__GetNextToken():
   2827                 raise Warning("expected version", self.FileName, self.CurrentLineNumber)
   2828             VerSectionObj = VerSection.VerSection()
   2829             VerSectionObj.Alignment = AlignValue
   2830             VerSectionObj.BuildNum = BuildNum
   2831             if self.__GetStringData():
   2832                 VerSectionObj.StringData = self.__Token
   2833             else:
   2834                 VerSectionObj.FileName = self.__Token
   2835             Obj.SectionList.append(VerSectionObj)
   2836             
   2837         elif self.__IsKeyword( "UI"):
   2838             if AlignValue == 'Auto':
   2839                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2840             if not self.__IsToken( "="):
   2841                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2842             if not self.__GetNextToken():
   2843                 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)
   2844             UiSectionObj = UiSection.UiSection()
   2845             UiSectionObj.Alignment = AlignValue
   2846             if self.__GetStringData():
   2847                 UiSectionObj.StringData = self.__Token
   2848             else:
   2849                 UiSectionObj.FileName = self.__Token
   2850             Obj.SectionList.append(UiSectionObj)
   2851 
   2852         elif self.__IsKeyword( "FV_IMAGE"):
   2853             if AlignValue == 'Auto':
   2854                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2855             if not self.__IsToken( "="):
   2856                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2857             if not self.__GetNextToken():
   2858                 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)
   2859 
   2860             FvName = self.__Token
   2861             FvObj = None
   2862 
   2863             if self.__IsToken( "{"):
   2864                 FvObj = Fv.FV()
   2865                 FvObj.UiFvName = FvName.upper()
   2866                 self.__GetDefineStatements(FvObj)
   2867                 MacroDict.update(FvObj.DefineVarDict)
   2868                 self.__GetBlockStatement(FvObj)
   2869                 self.__GetSetStatements(FvObj)
   2870                 self.__GetFvAlignment(FvObj)
   2871                 self.__GetFvAttributes(FvObj)
   2872                 self.__GetAprioriSection(FvObj, MacroDict.copy())
   2873                 self.__GetAprioriSection(FvObj, MacroDict.copy())
   2874 
   2875                 while True:
   2876                     IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
   2877                     IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
   2878                     if not IsInf and not IsFile:
   2879                         break
   2880 
   2881                 if not self.__IsToken( "}"):
   2882                     raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   2883 
   2884             FvImageSectionObj = FvImageSection.FvImageSection()
   2885             FvImageSectionObj.Alignment = AlignValue
   2886             if FvObj != None:
   2887                 FvImageSectionObj.Fv = FvObj
   2888                 FvImageSectionObj.FvName = None
   2889             else:
   2890                 FvImageSectionObj.FvName = FvName.upper()
   2891                 FvImageSectionObj.FvFileName = FvName
   2892 
   2893             Obj.SectionList.append(FvImageSectionObj)
   2894 
   2895         elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
   2896             if AlignValue == 'Auto':
   2897                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2898             DepexSectionObj = DepexSection.DepexSection()
   2899             DepexSectionObj.Alignment = AlignValue
   2900             DepexSectionObj.DepexType = self.__Token
   2901 
   2902             if not self.__IsToken( "="):
   2903                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   2904             if not self.__IsToken( "{"):
   2905                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2906             if not self.__SkipToToken( "}"):
   2907                 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)
   2908 
   2909             DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
   2910             Obj.SectionList.append(DepexSectionObj)
   2911 
   2912         else:
   2913             if not self.__GetNextWord():
   2914                 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)
   2915 
   2916             # Encapsulation section appear, UndoToken and return

   2917             if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
   2918                 self.SetFileBufferPos(OldPos)
   2919                 return False
   2920 
   2921             if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   2922                                "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
   2923                 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   2924             if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
   2925                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   2926 
   2927             # DataSection

   2928             DataSectionObj = DataSection.DataSection()
   2929             DataSectionObj.Alignment = AlignValue
   2930             DataSectionObj.SecType = self.__Token
   2931 
   2932             if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
   2933                 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
   2934                     if self.__Token == 'RELOCS_STRIPPED':
   2935                         DataSectionObj.KeepReloc = False
   2936                     else:
   2937                         DataSectionObj.KeepReloc = True
   2938                 else:
   2939                     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)
   2940 
   2941             if self.__IsToken("="):
   2942                 if not self.__GetNextToken():
   2943                     raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)
   2944                 DataSectionObj.SectFileName = self.__Token
   2945                 self.__VerifyFile(DataSectionObj.SectFileName)
   2946             else:
   2947                 if not self.__GetCglSection(DataSectionObj):
   2948                     return False
   2949 
   2950             Obj.SectionList.append(DataSectionObj)
   2951 
   2952         return True
   2953 
   2954     ## __VerifyFile

   2955     #

   2956     #    Check if file exists or not:

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

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

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

   2960     #

   2961     def __VerifyFile(self, FileName):
   2962         if FileName.replace('$(WORKSPACE)', '').find('$') != -1:
   2963             return
   2964         if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName:
   2965             ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   2966             if ErrorCode != 0:
   2967                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   2968 
   2969     ## __GetCglSection() method

   2970     #

   2971     #   Get compressed or GUIDed section for Obj

   2972     #

   2973     #   @param  self        The object pointer

   2974     #   @param  Obj         for whom leaf section is got

   2975     #   @param  AlignValue  alignment value for complex section

   2976     #   @retval True        Successfully find section statement

   2977     #   @retval False       Not able to find section statement

   2978     #

   2979     def __GetCglSection(self, Obj, AlignValue = None):
   2980 
   2981         if self.__IsKeyword( "COMPRESS"):
   2982             type = "PI_STD"
   2983             if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
   2984                 type = self.__Token
   2985 
   2986             if not self.__IsToken("{"):
   2987                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   2988 
   2989             CompressSectionObj = CompressSection.CompressSection()
   2990             CompressSectionObj.Alignment = AlignValue
   2991             CompressSectionObj.CompType = type
   2992             # Recursive sections...

   2993             while True:
   2994                 IsLeafSection = self.__GetLeafSection(CompressSectionObj)
   2995                 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
   2996                 if not IsLeafSection and not IsEncapSection:
   2997                     break
   2998 
   2999 
   3000             if not self.__IsToken( "}"):
   3001                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3002             Obj.SectionList.append(CompressSectionObj)
   3003 
   3004 #            else:

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

   3006 
   3007             return True
   3008 
   3009         elif self.__IsKeyword( "GUIDED"):
   3010             GuidValue = None
   3011             if self.__GetNextGuid():
   3012                 GuidValue = self.__Token
   3013 
   3014             AttribDict = self.__GetGuidAttrib()
   3015             if not self.__IsToken("{"):
   3016                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   3017             GuidSectionObj = GuidSection.GuidSection()
   3018             GuidSectionObj.Alignment = AlignValue
   3019             GuidSectionObj.NameGuid = GuidValue
   3020             GuidSectionObj.SectionType = "GUIDED"
   3021             GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
   3022             GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
   3023             GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
   3024             # Recursive sections...

   3025             while True:
   3026                 IsLeafSection = self.__GetLeafSection(GuidSectionObj)
   3027                 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
   3028                 if not IsLeafSection and not IsEncapSection:
   3029                     break
   3030 
   3031             if not self.__IsToken( "}"):
   3032                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3033             Obj.SectionList.append(GuidSectionObj)
   3034 
   3035             return True
   3036 
   3037         return False
   3038 
   3039     ## __GetGuidAttri() method

   3040     #

   3041     #   Get attributes for GUID section

   3042     #

   3043     #   @param  self        The object pointer

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

   3045     #

   3046     def __GetGuidAttrib(self):
   3047 
   3048         AttribDict = {}
   3049         AttribDict["PROCESSING_REQUIRED"] = "NONE"
   3050         AttribDict["AUTH_STATUS_VALID"] = "NONE"
   3051         AttribDict["EXTRA_HEADER_SIZE"] = -1
   3052         while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \
   3053             or self.__IsKeyword("EXTRA_HEADER_SIZE"):
   3054             AttribKey = self.__Token
   3055 
   3056             if not self.__IsToken("="):
   3057                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3058 
   3059             if not self.__GetNextToken():
   3060                 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)
   3061             elif AttribKey == "EXTRA_HEADER_SIZE":
   3062                 Base = 10
   3063                 if self.__Token[0:2].upper() == "0X":
   3064                     Base = 16
   3065                 try:
   3066                     AttribDict[AttribKey] = int(self.__Token, Base)
   3067                     continue
   3068                 except ValueError:
   3069                     raise Warning("expected Number", self.FileName, self.CurrentLineNumber)
   3070             elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
   3071                 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
   3072             AttribDict[AttribKey] = self.__Token
   3073 
   3074         return AttribDict
   3075 
   3076     ## __GetEncapsulationSec() method

   3077     #

   3078     #   Get encapsulation section for FILE

   3079     #

   3080     #   @param  self        The object pointer

   3081     #   @param  FfsFile     for whom section is got

   3082     #   @retval True        Successfully find section statement

   3083     #   @retval False       Not able to find section statement

   3084     #

   3085     def __GetEncapsulationSec(self, FfsFileObj):
   3086 
   3087         OldPos = self.GetFileBufferPos()
   3088         if not self.__IsKeyword( "SECTION"):
   3089             if len(FfsFileObj.SectionList) == 0:
   3090                 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
   3091             else:
   3092                 return False
   3093 
   3094         AlignValue = None
   3095         if self.__GetAlignment():
   3096             if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3097                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3098             AlignValue = self.__Token
   3099 
   3100         if not self.__GetCglSection(FfsFileObj, AlignValue):
   3101             self.SetFileBufferPos(OldPos)
   3102             return False
   3103         else:
   3104             return True
   3105 
   3106     def __GetFmp(self):
   3107         if not self.__GetNextToken():
   3108             return False
   3109         S = self.__Token.upper()
   3110         if not S.startswith("[FMPPAYLOAD."):
   3111             if not S.startswith("[CAPSULE.") and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
   3112                 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [FmpPayload.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
   3113             self.__UndoToken()
   3114             return False
   3115 
   3116         self.__UndoToken()
   3117         self.__SkipToToken("[FMPPAYLOAD.", True)
   3118         FmpUiName = self.__GetUiName().upper()
   3119         if FmpUiName in self.Profile.FmpPayloadDict:
   3120             raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)
   3121 
   3122         FmpData = CapsuleData.CapsulePayload()
   3123         FmpData.UiName = FmpUiName
   3124 
   3125         if not self.__IsToken( "]"):
   3126             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   3127 
   3128         if not self.__GetNextToken():
   3129             raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)
   3130         FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']
   3131         while self.__Token in FmpKeyList:
   3132             Name = self.__Token
   3133             FmpKeyList.remove(Name)
   3134             if not self.__IsToken("="):
   3135                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3136             if Name == 'IMAGE_TYPE_ID':
   3137                 if not self.__GetNextGuid():
   3138                     raise Warning("expected GUID value for IMAGE_TYPE_ID", self.FileName, self.CurrentLineNumber)
   3139                 FmpData.ImageTypeId = self.__Token
   3140             else:
   3141                 if not self.__GetNextToken():
   3142                     raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)
   3143                 Value = self.__Token
   3144                 if Name == 'IMAGE_HEADER_INIT_VERSION':
   3145                     FmpData.Version = Value
   3146                 elif Name == 'IMAGE_INDEX':
   3147                     FmpData.ImageIndex = Value
   3148                 elif Name == 'HARDWARE_INSTANCE':
   3149                     FmpData.HardwareInstance = Value
   3150             if not self.__GetNextToken():
   3151                 break
   3152         else:
   3153             self.__UndoToken()
   3154 
   3155         if FmpKeyList:
   3156             raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)
   3157         ImageFile = self.__ParseRawFileStatement()
   3158         if not ImageFile:
   3159             raise Warning("Missing image file in FMP payload section", self.FileName, self.CurrentLineNumber)
   3160         FmpData.ImageFile = ImageFile
   3161         VendorCodeFile = self.__ParseRawFileStatement()
   3162         if VendorCodeFile:
   3163             FmpData.VendorCodeFile = VendorCodeFile
   3164         self.Profile.FmpPayloadDict[FmpUiName] = FmpData
   3165         return True
   3166 
   3167     ## __GetCapsule() method

   3168     #

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

   3170     #

   3171     #   @param  self        The object pointer

   3172     #   @retval True        Successfully find a capsule

   3173     #   @retval False       Not able to find a capsule

   3174     #

   3175     def __GetCapsule(self):
   3176 
   3177         if not self.__GetNextToken():
   3178             return False
   3179 
   3180         S = self.__Token.upper()
   3181         if S.startswith("[") and not S.startswith("[CAPSULE."):
   3182             if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
   3183                 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
   3184             self.__UndoToken()
   3185             return False
   3186 
   3187         self.__UndoToken()
   3188         if not self.__IsToken("[CAPSULE.", True):
   3189             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   3190             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

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

   3192             raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)
   3193 
   3194         CapsuleObj = Capsule.Capsule()
   3195 
   3196         CapsuleName = self.__GetUiName()
   3197         if not CapsuleName:
   3198             raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)
   3199 
   3200         CapsuleObj.UiCapsuleName = CapsuleName.upper()
   3201 
   3202         if not self.__IsToken( "]"):
   3203             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   3204 
   3205         if self.__IsKeyword("CREATE_FILE"):
   3206             if not self.__IsToken( "="):
   3207                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3208 
   3209             if not self.__GetNextToken():
   3210                 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
   3211 
   3212             CapsuleObj.CreateFile = self.__Token
   3213 
   3214         self.__GetCapsuleStatements(CapsuleObj)
   3215         self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
   3216         return True
   3217 
   3218     ## __GetCapsuleStatements() method

   3219     #

   3220     #   Get statements for capsule

   3221     #

   3222     #   @param  self        The object pointer

   3223     #   @param  Obj         for whom statements are got

   3224     #

   3225     def __GetCapsuleStatements(self, Obj):
   3226         self.__GetCapsuleTokens(Obj)
   3227         self.__GetDefineStatements(Obj)
   3228         self.__GetSetStatements(Obj)
   3229         self.__GetCapsuleData(Obj)
   3230 
   3231     ## __GetCapsuleTokens() method

   3232     #

   3233     #   Get token statements for capsule

   3234     #

   3235     #   @param  self        The object pointer

   3236     #   @param  Obj         for whom token statements are got

   3237     #

   3238     def __GetCapsuleTokens(self, Obj):
   3239         if not self.__GetNextToken():
   3240             return False
   3241         while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):
   3242             Name = self.__Token.strip()
   3243             if not self.__IsToken("="):
   3244                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3245             if not self.__GetNextToken():
   3246                 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
   3247             if Name == 'CAPSULE_FLAGS':
   3248                 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
   3249                     raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
   3250                 Value = self.__Token.strip()
   3251                 while self.__IsToken(","):
   3252                     Value += ','
   3253                     if not self.__GetNextToken():
   3254                         raise Warning("expected value", self.FileName, self.CurrentLineNumber)
   3255                     if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
   3256                         raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
   3257                     Value += self.__Token.strip()
   3258             elif Name == 'OEM_CAPSULE_FLAGS':
   3259                 Value = self.__Token.strip()
   3260                 if not Value.upper().startswith('0X'):
   3261                     raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
   3262                 try:
   3263                     Value = int(Value, 0)
   3264                 except ValueError:
   3265                     raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
   3266                 if not 0x0000 <= Value <= 0xFFFF:
   3267                     raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
   3268                 Value = self.__Token.strip()
   3269             else:
   3270                 Value = self.__Token.strip()
   3271             Obj.TokensDict[Name] = Value  
   3272             if not self.__GetNextToken():
   3273                 return False
   3274         self.__UndoToken()
   3275 
   3276     ## __GetCapsuleData() method

   3277     #

   3278     #   Get capsule data for capsule

   3279     #

   3280     #   @param  self        The object pointer

   3281     #   @param  Obj         for whom capsule data are got

   3282     #

   3283     def __GetCapsuleData(self, Obj):
   3284 
   3285         while True:
   3286             IsInf = self.__GetInfStatement(Obj, True)
   3287             IsFile = self.__GetFileStatement(Obj, True)
   3288             IsFv = self.__GetFvStatement(Obj)
   3289             IsFd = self.__GetFdStatement(Obj)
   3290             IsAnyFile = self.__GetAnyFileStatement(Obj)
   3291             IsAfile = self.__GetAfileStatement(Obj)
   3292             IsFmp = self.__GetFmpStatement(Obj)
   3293             if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):
   3294                 break
   3295 
   3296     ## __GetFvStatement() method

   3297     #

   3298     #   Get FV for capsule

   3299     #

   3300     #   @param  self        The object pointer

   3301     #   @param  CapsuleObj  for whom FV is got

   3302     #   @retval True        Successfully find a FV statement

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

   3304     #

   3305     def __GetFvStatement(self, CapsuleObj):
   3306 
   3307         if not self.__IsKeyword("FV"):
   3308             return False
   3309 
   3310         if not self.__IsToken("="):
   3311             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3312 
   3313         if not self.__GetNextToken():
   3314             raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
   3315 
   3316         if self.__Token.upper() not in self.Profile.FvDict.keys():
   3317             raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)
   3318 
   3319         CapsuleFv = CapsuleData.CapsuleFv()
   3320         CapsuleFv.FvName = self.__Token
   3321         CapsuleObj.CapsuleDataList.append(CapsuleFv)
   3322         return True
   3323 
   3324     ## __GetFdStatement() method

   3325     #

   3326     #   Get FD for capsule

   3327     #

   3328     #   @param  self        The object pointer

   3329     #   @param  CapsuleObj  for whom FD is got

   3330     #   @retval True        Successfully find a FD statement

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

   3332     #

   3333     def __GetFdStatement(self, CapsuleObj):
   3334 
   3335         if not self.__IsKeyword("FD"):
   3336             return False
   3337 
   3338         if not self.__IsToken("="):
   3339             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3340 
   3341         if not self.__GetNextToken():
   3342             raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
   3343 
   3344         if self.__Token.upper() not in self.Profile.FdDict.keys():
   3345             raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)
   3346 
   3347         CapsuleFd = CapsuleData.CapsuleFd()
   3348         CapsuleFd.FdName = self.__Token
   3349         CapsuleObj.CapsuleDataList.append(CapsuleFd)
   3350         return True
   3351 
   3352     def __GetFmpStatement(self, CapsuleObj):
   3353         if not self.__IsKeyword("FMP"):
   3354             return False
   3355 
   3356         if not self.__IsKeyword("PAYLOAD"):
   3357             self.__UndoToken()
   3358             return False
   3359 
   3360         if not self.__IsToken("="):
   3361             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3362 
   3363         if not self.__GetNextToken():
   3364             raise Warning("expected payload name after FMP PAYLOAD =", self.FileName, self.CurrentLineNumber)
   3365         Payload = self.__Token.upper()
   3366         if Payload not in self.Profile.FmpPayloadDict:
   3367             raise Warning("This FMP Payload does not exist: %s" % self.__Token, self.FileName, self.CurrentLineNumber)
   3368         CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])
   3369         return True
   3370 
   3371     def __ParseRawFileStatement(self):
   3372         if not self.__IsKeyword("FILE"):
   3373             return None
   3374 
   3375         if not self.__IsKeyword("DATA"):
   3376             self.__UndoToken()
   3377             return None
   3378 
   3379         if not self.__IsToken("="):
   3380             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3381 
   3382         if not self.__GetNextToken():
   3383             raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
   3384         
   3385         AnyFileName = self.__Token
   3386         AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName)
   3387         if not os.path.exists(AnyFileName):
   3388             raise Warning("File %s not exists"%AnyFileName, self.FileName, self.CurrentLineNumber)
   3389         return AnyFileName
   3390 
   3391     ## __GetAnyFileStatement() method

   3392     #

   3393     #   Get AnyFile for capsule

   3394     #

   3395     #   @param  self        The object pointer

   3396     #   @param  CapsuleObj  for whom AnyFile is got

   3397     #   @retval True        Successfully find a Anyfile statement

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

   3399     #

   3400     def __GetAnyFileStatement(self, CapsuleObj):
   3401         AnyFileName = self.__ParseRawFileStatement()
   3402         if not AnyFileName:
   3403             return False
   3404 
   3405         CapsuleAnyFile = CapsuleData.CapsuleAnyFile()
   3406         CapsuleAnyFile.FileName = AnyFileName
   3407         CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)
   3408         return True
   3409     
   3410     ## __GetAfileStatement() method

   3411     #

   3412     #   Get Afile for capsule

   3413     #

   3414     #   @param  self        The object pointer

   3415     #   @param  CapsuleObj  for whom Afile is got

   3416     #   @retval True        Successfully find a Afile statement

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

   3418     #

   3419     def __GetAfileStatement(self, CapsuleObj):
   3420 
   3421         if not self.__IsKeyword("APPEND"):
   3422             return False
   3423 
   3424         if not self.__IsToken("="):
   3425             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3426 
   3427         if not self.__GetNextToken():
   3428             raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)
   3429         
   3430         AfileName = self.__Token
   3431         AfileBaseName = os.path.basename(AfileName)
   3432         
   3433         if os.path.splitext(AfileBaseName)[1]  not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:
   3434             raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \
   3435                           self.FileName, self.CurrentLineNumber)
   3436         
   3437         if not os.path.isabs(AfileName):
   3438             AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)
   3439             self.__VerifyFile(AfileName)
   3440         else:
   3441             if not os.path.exists(AfileName):
   3442                 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)
   3443             else:
   3444                 pass
   3445 
   3446         CapsuleAfile = CapsuleData.CapsuleAfile()
   3447         CapsuleAfile.FileName = AfileName
   3448         CapsuleObj.CapsuleDataList.append(CapsuleAfile)
   3449         return True
   3450 
   3451     ## __GetRule() method

   3452     #

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

   3454     #

   3455     #   @param  self        The object pointer

   3456     #   @retval True        Successfully find a Rule

   3457     #   @retval False       Not able to find a Rule

   3458     #

   3459     def __GetRule(self):
   3460 
   3461         if not self.__GetNextToken():
   3462             return False
   3463 
   3464         S = self.__Token.upper()
   3465         if S.startswith("[") and not S.startswith("[RULE."):
   3466             if not S.startswith("[OPTIONROM."):
   3467                 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
   3468             self.__UndoToken()
   3469             return False
   3470         self.__UndoToken()
   3471         if not self.__IsToken("[Rule.", True):
   3472             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   3473             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

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

   3475             raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber)
   3476 
   3477         if not self.__SkipToToken("."):
   3478             raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
   3479 
   3480         Arch = self.__SkippedChars.rstrip(".")
   3481         if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
   3482             raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
   3483 
   3484         ModuleType = self.__GetModuleType()
   3485 
   3486         TemplateName = ""
   3487         if self.__IsToken("."):
   3488             if not self.__GetNextWord():
   3489                 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)
   3490             TemplateName = self.__Token
   3491 
   3492         if not self.__IsToken( "]"):
   3493             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   3494 
   3495         RuleObj = self.__GetRuleFileStatements()
   3496         RuleObj.Arch = Arch.upper()
   3497         RuleObj.ModuleType = ModuleType
   3498         RuleObj.TemplateName = TemplateName
   3499         if TemplateName == '' :
   3500             self.Profile.RuleDict['RULE'             + \
   3501                               '.'                    + \
   3502                               Arch.upper()           + \
   3503                               '.'                    + \
   3504                               ModuleType.upper()     ] = RuleObj
   3505         else :
   3506             self.Profile.RuleDict['RULE'             + \
   3507                               '.'                    + \
   3508                               Arch.upper()           + \
   3509                               '.'                    + \
   3510                               ModuleType.upper()     + \
   3511                               '.'                    + \
   3512                               TemplateName.upper() ] = RuleObj
   3513 #        self.Profile.RuleList.append(rule)

   3514         return True
   3515 
   3516     ## __GetModuleType() method

   3517     #

   3518     #   Return the module type

   3519     #

   3520     #   @param  self        The object pointer

   3521     #   @retval string      module type

   3522     #

   3523     def __GetModuleType(self):
   3524 
   3525         if not self.__GetNextWord():
   3526             raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)
   3527         if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
   3528                              "DXE_DRIVER", "DXE_SAL_DRIVER", \
   3529                              "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
   3530                              "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
   3531                              "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
   3532                              "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
   3533             raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3534         return self.__Token
   3535 
   3536     ## __GetFileExtension() method

   3537     #

   3538     #   Return the file extension

   3539     #

   3540     #   @param  self        The object pointer

   3541     #   @retval string      file name extension

   3542     #

   3543     def __GetFileExtension(self):
   3544         if not self.__IsToken("."):
   3545                 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
   3546 
   3547         Ext = ""
   3548         if self.__GetNextToken():
   3549             Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
   3550             if Pattern.match(self.__Token):
   3551                 Ext = self.__Token
   3552                 return '.' + Ext
   3553             else:
   3554                 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3555 
   3556         else:
   3557             raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)
   3558 
   3559     ## __GetRuleFileStatement() method

   3560     #

   3561     #   Get rule contents

   3562     #

   3563     #   @param  self        The object pointer

   3564     #   @retval Rule        Rule object

   3565     #

   3566     def __GetRuleFileStatements(self):
   3567 
   3568         if not self.__IsKeyword("FILE"):
   3569             raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)
   3570 
   3571         if not self.__GetNextWord():
   3572             raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
   3573 
   3574         Type = self.__Token.strip().upper()
   3575         if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
   3576                              "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
   3577             raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3578 
   3579         if not self.__IsToken("="):
   3580             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3581 
   3582         if not self.__IsKeyword("$(NAMED_GUID)"):
   3583             if not self.__GetNextWord():
   3584                 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
   3585             if self.__Token == 'PCD':
   3586                 if not self.__IsToken( "("):
   3587                     raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
   3588                 PcdPair = self.__GetNextPcdName()
   3589                 if not self.__IsToken( ")"):
   3590                     raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
   3591                 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
   3592             
   3593         NameGuid = self.__Token
   3594 
   3595         KeepReloc = None
   3596         if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
   3597             if self.__FileCouldHaveRelocFlag(Type):
   3598                 if self.__Token == 'RELOCS_STRIPPED':
   3599                     KeepReloc = False
   3600                 else:
   3601                     KeepReloc = True
   3602             else:
   3603                 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3604 
   3605         KeyStringList = []
   3606         if self.__GetNextToken():
   3607             Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
   3608             if Pattern.match(self.__Token):
   3609                 KeyStringList.append(self.__Token)
   3610                 if self.__IsToken(","):
   3611                     while self.__GetNextToken():
   3612                         if not Pattern.match(self.__Token):
   3613                             raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
   3614                         KeyStringList.append(self.__Token)
   3615 
   3616                         if not self.__IsToken(","):
   3617                             break
   3618 
   3619             else:
   3620                 self.__UndoToken()
   3621 
   3622 
   3623         Fixed = False
   3624         if self.__IsKeyword("Fixed", True):
   3625             Fixed = True
   3626 
   3627         CheckSum = False
   3628         if self.__IsKeyword("CheckSum", True):
   3629             CheckSum = True
   3630 
   3631         AlignValue = ""
   3632         if self.__GetAlignment():
   3633             if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3634                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3635             #For FFS, Auto is default option same to ""

   3636             if not self.__Token == "Auto":
   3637                 AlignValue = self.__Token
   3638 
   3639         if self.__IsToken("{"):
   3640             # Complex file rule expected

   3641             Rule = RuleComplexFile.RuleComplexFile()
   3642             Rule.FvFileType = Type
   3643             Rule.NameGuid = NameGuid
   3644             Rule.Alignment = AlignValue
   3645             Rule.CheckSum = CheckSum
   3646             Rule.Fixed = Fixed
   3647             Rule.KeyStringList = KeyStringList
   3648             if KeepReloc != None:
   3649                 Rule.KeepReloc = KeepReloc
   3650 
   3651             while True:
   3652                 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
   3653                 IsLeaf = self.__GetEfiSection(Rule)
   3654                 if not IsEncapsulate and not IsLeaf:
   3655                     break
   3656 
   3657             if not self.__IsToken("}"):
   3658                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3659 
   3660             return Rule
   3661 
   3662         else:
   3663             # Simple file rule expected

   3664             if not self.__GetNextWord():
   3665                 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)
   3666 
   3667             SectionName = self.__Token
   3668 
   3669             if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   3670                                     "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
   3671                 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
   3672 
   3673 
   3674             if self.__IsKeyword("Fixed", True):
   3675                 Fixed = True
   3676 
   3677             if self.__IsKeyword("CheckSum", True):
   3678                 CheckSum = True
   3679 
   3680             SectAlignment = ""
   3681             if self.__GetAlignment():
   3682                 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3683                     raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3684                 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
   3685                     raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   3686                 SectAlignment = self.__Token
   3687 
   3688             Ext = None
   3689             if self.__IsToken('|'):
   3690                 Ext = self.__GetFileExtension()
   3691             elif not self.__GetNextToken():
   3692                 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
   3693 
   3694             Rule = RuleSimpleFile.RuleSimpleFile()
   3695             Rule.SectionType = SectionName
   3696             Rule.FvFileType = Type
   3697             Rule.NameGuid = NameGuid
   3698             Rule.Alignment = AlignValue
   3699             Rule.SectAlignment = SectAlignment
   3700             Rule.CheckSum = CheckSum
   3701             Rule.Fixed = Fixed
   3702             Rule.KeyStringList = KeyStringList
   3703             if KeepReloc != None:
   3704                 Rule.KeepReloc = KeepReloc
   3705             Rule.FileExtension = Ext
   3706             Rule.FileName = self.__Token
   3707             return Rule
   3708 
   3709     ## __GetEfiSection() method

   3710     #

   3711     #   Get section list for Rule

   3712     #

   3713     #   @param  self        The object pointer

   3714     #   @param  Obj         for whom section is got

   3715     #   @retval True        Successfully find section statement

   3716     #   @retval False       Not able to find section statement

   3717     #

   3718     def __GetEfiSection(self, Obj):
   3719 
   3720         OldPos = self.GetFileBufferPos()
   3721         if not self.__GetNextWord():
   3722             return False
   3723         SectionName = self.__Token
   3724 
   3725         if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   3726                                "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
   3727             self.__UndoToken()
   3728             return False
   3729 
   3730         if SectionName == "FV_IMAGE":
   3731             FvImageSectionObj = FvImageSection.FvImageSection()
   3732             if self.__IsKeyword("FV_IMAGE"):
   3733                 pass
   3734             if self.__IsToken( "{"):
   3735                 FvObj = Fv.FV()
   3736                 self.__GetDefineStatements(FvObj)
   3737                 self.__GetBlockStatement(FvObj)
   3738                 self.__GetSetStatements(FvObj)
   3739                 self.__GetFvAlignment(FvObj)
   3740                 self.__GetFvAttributes(FvObj)
   3741                 self.__GetAprioriSection(FvObj)
   3742                 self.__GetAprioriSection(FvObj)
   3743 
   3744                 while True:
   3745                     IsInf = self.__GetInfStatement(FvObj)
   3746                     IsFile = self.__GetFileStatement(FvObj)
   3747                     if not IsInf and not IsFile:
   3748                         break
   3749 
   3750                 if not self.__IsToken( "}"):
   3751                     raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3752                 FvImageSectionObj.Fv = FvObj
   3753                 FvImageSectionObj.FvName = None
   3754 
   3755             else:
   3756                 if not self.__IsKeyword("FV"):
   3757                     raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber)
   3758                 FvImageSectionObj.FvFileType = self.__Token
   3759 
   3760                 if self.__GetAlignment():
   3761                     if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3762                         raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3763                     FvImageSectionObj.Alignment = self.__Token
   3764 
   3765                 if self.__IsToken('|'):
   3766                     FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
   3767                 elif self.__GetNextToken():
   3768                     if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   3769                                "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
   3770                         FvImageSectionObj.FvFileName = self.__Token
   3771                     else:
   3772                         self.__UndoToken()
   3773                 else:
   3774                     raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)
   3775 
   3776             Obj.SectionList.append(FvImageSectionObj)
   3777             return True
   3778 
   3779         EfiSectionObj = EfiSection.EfiSection()
   3780         EfiSectionObj.SectionType = SectionName
   3781 
   3782         if not self.__GetNextToken():
   3783             raise Warning("expected file type", self.FileName, self.CurrentLineNumber)
   3784 
   3785         if self.__Token == "STRING":
   3786             if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
   3787                 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3788 
   3789             if not self.__IsToken('='):
   3790                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3791 
   3792             if not self.__GetNextToken():
   3793                 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)
   3794 
   3795             if self.__GetStringData():
   3796                 EfiSectionObj.StringData = self.__Token
   3797 
   3798             if self.__IsKeyword("BUILD_NUM"):
   3799                 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
   3800                     raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3801 
   3802                 if not self.__IsToken("="):
   3803                     raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3804                 if not self.__GetNextToken():
   3805                     raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
   3806                 EfiSectionObj.BuildNum = self.__Token
   3807 
   3808         else:
   3809             EfiSectionObj.FileType = self.__Token
   3810             self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
   3811 
   3812         if self.__IsKeyword("Optional"):
   3813             if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
   3814                 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3815             EfiSectionObj.Optional = True
   3816 
   3817             if self.__IsKeyword("BUILD_NUM"):
   3818                 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
   3819                     raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
   3820 
   3821                 if not self.__IsToken("="):
   3822                     raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   3823                 if not self.__GetNextToken():
   3824                     raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
   3825                 EfiSectionObj.BuildNum = self.__Token
   3826 
   3827         if self.__GetAlignment():
   3828             if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
   3829                 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   3830             if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
   3831                 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
   3832             EfiSectionObj.Alignment = self.__Token
   3833 
   3834         if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
   3835             if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
   3836                 if self.__Token == 'RELOCS_STRIPPED':
   3837                     EfiSectionObj.KeepReloc = False
   3838                 else:
   3839                     EfiSectionObj.KeepReloc = True
   3840                 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
   3841                     raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
   3842             else:
   3843                 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
   3844 
   3845 
   3846         if self.__IsToken('|'):
   3847             EfiSectionObj.FileExtension = self.__GetFileExtension()
   3848         elif self.__GetNextToken():
   3849             if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
   3850                        "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
   3851                 
   3852                 if self.__Token.startswith('PCD'):
   3853                     self.__UndoToken()
   3854                     self.__GetNextWord()
   3855                 
   3856                     if self.__Token == 'PCD':
   3857                         if not self.__IsToken( "("):
   3858                             raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
   3859                         PcdPair = self.__GetNextPcdName()
   3860                         if not self.__IsToken( ")"):
   3861                             raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
   3862                         self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
   3863                         
   3864                 EfiSectionObj.FileName = self.__Token        
   3865                             
   3866             else:
   3867                 self.__UndoToken()
   3868         else:
   3869             raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)
   3870 
   3871         Obj.SectionList.append(EfiSectionObj)
   3872         return True
   3873 
   3874     ## __RuleSectionCouldBeOptional() method

   3875     #

   3876     #   Get whether a section could be optional

   3877     #

   3878     #   @param  self        The object pointer

   3879     #   @param  SectionType The section type to check

   3880     #   @retval True        section could be optional

   3881     #   @retval False       section never optional

   3882     #

   3883     def __RuleSectionCouldBeOptional(self, SectionType):
   3884         if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
   3885             return True
   3886         else:
   3887             return False
   3888 
   3889     ## __RuleSectionCouldHaveBuildNum() method

   3890     #

   3891     #   Get whether a section could have build number information

   3892     #

   3893     #   @param  self        The object pointer

   3894     #   @param  SectionType The section type to check

   3895     #   @retval True        section could have build number information

   3896     #   @retval False       section never have build number information

   3897     #

   3898     def __RuleSectionCouldHaveBuildNum(self, SectionType):
   3899         if SectionType in ("VERSION"):
   3900             return True
   3901         else:
   3902             return False
   3903 
   3904     ## __RuleSectionCouldHaveString() method

   3905     #

   3906     #   Get whether a section could have string

   3907     #

   3908     #   @param  self        The object pointer

   3909     #   @param  SectionType The section type to check

   3910     #   @retval True        section could have string

   3911     #   @retval False       section never have string

   3912     #

   3913     def __RuleSectionCouldHaveString(self, SectionType):
   3914         if SectionType in ("UI", "VERSION"):
   3915             return True
   3916         else:
   3917             return False
   3918 
   3919     ## __CheckRuleSectionFileType() method

   3920     #

   3921     #   Get whether a section matches a file type

   3922     #

   3923     #   @param  self        The object pointer

   3924     #   @param  SectionType The section type to check

   3925     #   @param  FileType    The file type to check

   3926     #

   3927     def __CheckRuleSectionFileType(self, SectionType, FileType):
   3928         if SectionType == "COMPAT16":
   3929             if FileType not in ("COMPAT16", "SEC_COMPAT16"):
   3930                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3931         elif SectionType == "PE32":
   3932             if FileType not in ("PE32", "SEC_PE32"):
   3933                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3934         elif SectionType == "PIC":
   3935             if FileType not in ("PIC", "PIC"):
   3936                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3937         elif SectionType == "TE":
   3938             if FileType not in ("TE", "SEC_TE"):
   3939                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3940         elif SectionType == "RAW":
   3941             if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
   3942                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3943         elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
   3944             if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
   3945                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3946         elif SectionType == "UI":
   3947             if FileType not in ("UI", "SEC_UI"):
   3948                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3949         elif SectionType == "VERSION":
   3950             if FileType not in ("VERSION", "SEC_VERSION"):
   3951                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3952         elif SectionType == "PEI_DEPEX":
   3953             if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
   3954                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3955         elif SectionType == "GUID":
   3956             if FileType not in ("PE32", "SEC_GUID"):
   3957                 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
   3958 
   3959     ## __GetRuleEncapsulationSection() method

   3960     #

   3961     #   Get encapsulation section for Rule

   3962     #

   3963     #   @param  self        The object pointer

   3964     #   @param  Rule        for whom section is got

   3965     #   @retval True        Successfully find section statement

   3966     #   @retval False       Not able to find section statement

   3967     #

   3968     def __GetRuleEncapsulationSection(self, Rule):
   3969 
   3970         if self.__IsKeyword( "COMPRESS"):
   3971             Type = "PI_STD"
   3972             if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
   3973                 Type = self.__Token
   3974 
   3975             if not self.__IsToken("{"):
   3976                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   3977 
   3978             CompressSectionObj = CompressSection.CompressSection()
   3979 
   3980             CompressSectionObj.CompType = Type
   3981             # Recursive sections...

   3982             while True:
   3983                 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
   3984                 IsLeaf = self.__GetEfiSection(CompressSectionObj)
   3985                 if not IsEncapsulate and not IsLeaf:
   3986                     break
   3987 
   3988             if not self.__IsToken( "}"):
   3989                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   3990             Rule.SectionList.append(CompressSectionObj)
   3991 
   3992             return True
   3993 
   3994         elif self.__IsKeyword( "GUIDED"):
   3995             GuidValue = None
   3996             if self.__GetNextGuid():
   3997                 GuidValue = self.__Token
   3998 
   3999             if self.__IsKeyword( "$(NAMED_GUID)"):
   4000                 GuidValue = self.__Token
   4001 
   4002             AttribDict = self.__GetGuidAttrib()
   4003 
   4004             if not self.__IsToken("{"):
   4005                 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
   4006             GuidSectionObj = GuidSection.GuidSection()
   4007             GuidSectionObj.NameGuid = GuidValue
   4008             GuidSectionObj.SectionType = "GUIDED"
   4009             GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
   4010             GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
   4011             GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
   4012 
   4013             # Efi sections...

   4014             while True:
   4015                 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
   4016                 IsLeaf = self.__GetEfiSection(GuidSectionObj)
   4017                 if not IsEncapsulate and not IsLeaf:
   4018                     break
   4019 
   4020             if not self.__IsToken( "}"):
   4021                 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
   4022             Rule.SectionList.append(GuidSectionObj)
   4023 
   4024             return True
   4025 
   4026         return False
   4027 
   4028     ## __GetVtf() method

   4029     #

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

   4031     #

   4032     #   @param  self        The object pointer

   4033     #   @retval True        Successfully find a VTF

   4034     #   @retval False       Not able to find a VTF

   4035     #

   4036     def __GetVtf(self):
   4037 
   4038         if not self.__GetNextToken():
   4039             return False
   4040 
   4041         S = self.__Token.upper()
   4042         if S.startswith("[") and not S.startswith("[VTF."):
   4043             if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
   4044                 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
   4045             self.__UndoToken()
   4046             return False
   4047 
   4048         self.__UndoToken()
   4049         if not self.__IsToken("[VTF.", True):
   4050             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   4051             #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \

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

   4053             raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)
   4054 
   4055         if not self.__SkipToToken("."):
   4056             raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
   4057 
   4058         Arch = self.__SkippedChars.rstrip(".").upper()
   4059         if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
   4060             raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
   4061 
   4062         if not self.__GetNextWord():
   4063             raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)
   4064         Name = self.__Token.upper()
   4065 
   4066         VtfObj = Vtf.Vtf()
   4067         VtfObj.UiName = Name
   4068         VtfObj.KeyArch = Arch
   4069 
   4070         if self.__IsToken(","):
   4071             if not self.__GetNextWord():
   4072                 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)
   4073             if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
   4074                 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4075             VtfObj.ArchList = self.__Token.upper()
   4076 
   4077         if not self.__IsToken( "]"):
   4078             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   4079 
   4080         if self.__IsKeyword("IA32_RST_BIN"):
   4081             if not self.__IsToken("="):
   4082                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4083 
   4084             if not self.__GetNextToken():
   4085                 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)
   4086 
   4087             VtfObj.ResetBin = self.__Token
   4088             if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1:
   4089                 #check for file path

   4090                 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4091                 if ErrorCode != 0:
   4092                     EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4093 
   4094         while self.__GetComponentStatement(VtfObj):
   4095             pass
   4096 
   4097         self.Profile.VtfList.append(VtfObj)
   4098         return True
   4099 
   4100     ## __GetComponentStatement() method

   4101     #

   4102     #   Get components in VTF

   4103     #

   4104     #   @param  self        The object pointer

   4105     #   @param  VtfObj         for whom component is got

   4106     #   @retval True        Successfully find a component

   4107     #   @retval False       Not able to find a component

   4108     #

   4109     def __GetComponentStatement(self, VtfObj):
   4110 
   4111         if not self.__IsKeyword("COMP_NAME"):
   4112             return False
   4113 
   4114         if not self.__IsToken("="):
   4115             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4116 
   4117         if not self.__GetNextWord():
   4118             raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)
   4119 
   4120         CompStatementObj = ComponentStatement.ComponentStatement()
   4121         CompStatementObj.CompName = self.__Token
   4122 
   4123         if not self.__IsKeyword("COMP_LOC"):
   4124             raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)
   4125 
   4126         if not self.__IsToken("="):
   4127             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4128 
   4129         CompStatementObj.CompLoc = ""
   4130         if self.__GetNextWord():
   4131             CompStatementObj.CompLoc = self.__Token
   4132             if self.__IsToken('|'):
   4133                 if not self.__GetNextWord():
   4134                     raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)
   4135 
   4136                 if self.__Token not in ("F", "N", "S"):    #, "H", "L", "PH", "PL"): not support

   4137                     raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4138 
   4139                 CompStatementObj.FilePos = self.__Token
   4140         else:
   4141             self.CurrentLineNumber += 1
   4142             self.CurrentOffsetWithinLine = 0
   4143 
   4144         if not self.__IsKeyword("COMP_TYPE"):
   4145             raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)
   4146 
   4147         if not self.__IsToken("="):
   4148             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4149 
   4150         if not self.__GetNextToken():
   4151             raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)
   4152         if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
   4153             if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
   4154                 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
   4155                 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4156         CompStatementObj.CompType = self.__Token
   4157 
   4158         if not self.__IsKeyword("COMP_VER"):
   4159             raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)
   4160 
   4161         if not self.__IsToken("="):
   4162             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4163 
   4164         if not self.__GetNextToken():
   4165             raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)
   4166 
   4167         Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL)
   4168         if Pattern.match(self.__Token) == None:
   4169             raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4170         CompStatementObj.CompVer = self.__Token
   4171 
   4172         if not self.__IsKeyword("COMP_CS"):
   4173             raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)
   4174 
   4175         if not self.__IsToken("="):
   4176             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4177 
   4178         if not self.__GetNextToken():
   4179             raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)
   4180         if self.__Token not in ("1", "0"):
   4181             raise Warning("Unknown  Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4182         CompStatementObj.CompCs = self.__Token
   4183 
   4184 
   4185         if not self.__IsKeyword("COMP_BIN"):
   4186             raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)
   4187 
   4188         if not self.__IsToken("="):
   4189             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4190 
   4191         if not self.__GetNextToken():
   4192             raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)
   4193 
   4194         CompStatementObj.CompBin = self.__Token
   4195         if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1:
   4196             #check for file path

   4197             ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4198             if ErrorCode != 0:
   4199                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4200 
   4201         if not self.__IsKeyword("COMP_SYM"):
   4202             raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)
   4203 
   4204         if not self.__IsToken("="):
   4205             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4206 
   4207         if not self.__GetNextToken():
   4208             raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)
   4209 
   4210         CompStatementObj.CompSym = self.__Token
   4211         if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1:
   4212             #check for file path

   4213             ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4214             if ErrorCode != 0:
   4215                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4216 
   4217         if not self.__IsKeyword("COMP_SIZE"):
   4218             raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)
   4219 
   4220         if not self.__IsToken("="):
   4221             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4222 
   4223         if self.__IsToken("-"):
   4224             CompStatementObj.CompSize = self.__Token
   4225         elif self.__GetNextDecimalNumber():
   4226             CompStatementObj.CompSize = self.__Token
   4227         elif self.__GetNextHexNumber():
   4228             CompStatementObj.CompSize = self.__Token
   4229         else:
   4230             raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4231 
   4232         VtfObj.ComponentStatementList.append(CompStatementObj)
   4233         return True
   4234 
   4235     ## __GetOptionRom() method

   4236     #

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

   4238     #

   4239     #   @param  self        The object pointer

   4240     #   @retval True        Successfully find a OptionROM

   4241     #   @retval False       Not able to find a OptionROM

   4242     #

   4243     def __GetOptionRom(self):
   4244 
   4245         if not self.__GetNextToken():
   4246             return False
   4247 
   4248         S = self.__Token.upper()
   4249         if S.startswith("[") and not S.startswith("[OPTIONROM."):
   4250             raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
   4251         
   4252         self.__UndoToken()
   4253         if not self.__IsToken("[OptionRom.", True):
   4254             raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
   4255 
   4256         OptRomName = self.__GetUiName()
   4257 
   4258         if not self.__IsToken( "]"):
   4259             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
   4260 
   4261         OptRomObj = OptionRom.OPTIONROM()
   4262         OptRomObj.DriverName = OptRomName
   4263         self.Profile.OptRomDict[OptRomName] = OptRomObj
   4264 
   4265         while True:
   4266             isInf = self.__GetOptRomInfStatement(OptRomObj)
   4267             isFile = self.__GetOptRomFileStatement(OptRomObj)
   4268             if not isInf and not isFile:
   4269                 break
   4270             
   4271         return True
   4272 
   4273     ## __GetOptRomInfStatement() method

   4274     #

   4275     #   Get INF statements

   4276     #

   4277     #   @param  self        The object pointer

   4278     #   @param  Obj         for whom inf statement is got

   4279     #   @retval True        Successfully find inf statement

   4280     #   @retval False       Not able to find inf statement

   4281     #

   4282     def __GetOptRomInfStatement(self, Obj):
   4283 
   4284         if not self.__IsKeyword( "INF"):
   4285             return False
   4286 
   4287         ffsInf = OptRomInfStatement.OptRomInfStatement()
   4288         self.__GetInfOptions( ffsInf)
   4289 
   4290         if not self.__GetNextToken():
   4291             raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
   4292         ffsInf.InfFileName = self.__Token
   4293         if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
   4294             #check for file path

   4295             ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4296             if ErrorCode != 0:
   4297                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4298 
   4299         if not ffsInf.InfFileName in self.Profile.InfList:
   4300             self.Profile.InfList.append(ffsInf.InfFileName)
   4301             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
   4302             self.Profile.InfFileLineList.append(FileLineTuple)
   4303 
   4304         
   4305         self.__GetOptRomOverrides (ffsInf)
   4306             
   4307         Obj.FfsList.append(ffsInf)
   4308         return True
   4309 
   4310     ## __GetOptRomOverrides() method

   4311     #

   4312     #   Get overrides for OptROM INF & FILE

   4313     #

   4314     #   @param  self        The object pointer

   4315     #   @param  FfsInfObj   for whom overrides is got

   4316     #

   4317     def __GetOptRomOverrides(self, Obj):
   4318         if self.__IsToken('{'):
   4319             Overrides = OptionRom.OverrideAttribs()
   4320             while True:
   4321                 if self.__IsKeyword( "PCI_VENDOR_ID"):
   4322                     if not self.__IsToken( "="):
   4323                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4324                     if not self.__GetNextHexNumber():
   4325                         raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)
   4326                     Overrides.PciVendorId = self.__Token
   4327                     continue
   4328 
   4329                 if self.__IsKeyword( "PCI_CLASS_CODE"):
   4330                     if not self.__IsToken( "="):
   4331                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4332                     if not self.__GetNextHexNumber():
   4333                         raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)
   4334                     Overrides.PciClassCode = self.__Token
   4335                     continue
   4336 
   4337                 if self.__IsKeyword( "PCI_DEVICE_ID"):
   4338                     if not self.__IsToken( "="):
   4339                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4340                     if not self.__GetNextHexNumber():
   4341                         raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)
   4342 
   4343                     Overrides.PciDeviceId = self.__Token
   4344                     continue
   4345 
   4346                 if self.__IsKeyword( "PCI_REVISION"):
   4347                     if not self.__IsToken( "="):
   4348                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4349                     if not self.__GetNextHexNumber():
   4350                         raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)
   4351                     Overrides.PciRevision = self.__Token
   4352                     continue
   4353 
   4354                 if self.__IsKeyword( "PCI_COMPRESS"):
   4355                     if not self.__IsToken( "="):
   4356                         raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
   4357                     if not self.__GetNextToken():
   4358                         raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
   4359                     Overrides.NeedCompress = self.__Token.upper() == 'TRUE'
   4360                     continue
   4361 
   4362                 if self.__IsToken( "}"):
   4363                     break
   4364                 else:
   4365                     EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)
   4366 
   4367             Obj.OverrideAttribs = Overrides
   4368             
   4369     ## __GetOptRomFileStatement() method

   4370     #

   4371     #   Get FILE statements

   4372     #

   4373     #   @param  self        The object pointer

   4374     #   @param  Obj         for whom FILE statement is got

   4375     #   @retval True        Successfully find FILE statement

   4376     #   @retval False       Not able to find FILE statement

   4377     #

   4378     def __GetOptRomFileStatement(self, Obj):
   4379 
   4380         if not self.__IsKeyword( "FILE"):
   4381             return False
   4382 
   4383         FfsFileObj = OptRomFileStatement.OptRomFileStatement()
   4384 
   4385         if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"):
   4386             raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
   4387         FfsFileObj.FileType = self.__Token
   4388 
   4389         if not self.__GetNextToken():
   4390             raise Warning("expected File path", self.FileName, self.CurrentLineNumber)
   4391         FfsFileObj.FileName = self.__Token
   4392         if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
   4393             #check for file path

   4394             ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
   4395             if ErrorCode != 0:
   4396                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
   4397 
   4398         if FfsFileObj.FileType == 'EFI':
   4399             self.__GetOptRomOverrides(FfsFileObj)
   4400         
   4401         Obj.FfsList.append(FfsFileObj)
   4402 
   4403         return True
   4404 
   4405     ## __GetCapInFd() method

   4406     #

   4407     #   Get Cap list contained in FD

   4408     #

   4409     #   @param  self        The object pointer

   4410     #   @param  FdName      FD name

   4411     #   @retval CapList     List of Capsule in FD

   4412     #

   4413     def __GetCapInFd (self, FdName):
   4414 
   4415         CapList = []
   4416         if FdName.upper() in self.Profile.FdDict.keys():
   4417             FdObj = self.Profile.FdDict[FdName.upper()]
   4418             for elementRegion in FdObj.RegionList:
   4419                 if elementRegion.RegionType == 'CAPSULE':
   4420                     for elementRegionData in elementRegion.RegionDataList:
   4421                         if elementRegionData.endswith(".cap"):
   4422                             continue
   4423                         if elementRegionData != None and elementRegionData.upper() not in CapList:
   4424                             CapList.append(elementRegionData.upper())
   4425         return CapList
   4426 
   4427     ## __GetReferencedFdCapTuple() method

   4428     #

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

   4430     #

   4431     #   @param  self        The object pointer

   4432     #   @param  CapObj      Capsule section to be searched

   4433     #   @param  RefFdList   referenced FD by section

   4434     #   @param  RefFvList   referenced FV by section

   4435     #

   4436     def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
   4437 
   4438         for CapsuleDataObj in CapObj.CapsuleDataList :
   4439             if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:
   4440                 RefFvList.append (CapsuleDataObj.FvName.upper())
   4441             elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList:
   4442                 RefFdList.append (CapsuleDataObj.FdName.upper())            
   4443             elif CapsuleDataObj.Ffs != None:
   4444                 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):
   4445                     if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
   4446                         RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
   4447                     elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
   4448                         RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
   4449                     else:
   4450                         self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)
   4451 
   4452     ## __GetFvInFd() method

   4453     #

   4454     #   Get FV list contained in FD

   4455     #

   4456     #   @param  self        The object pointer

   4457     #   @param  FdName      FD name

   4458     #   @retval FvList      list of FV in FD

   4459     #

   4460     def __GetFvInFd (self, FdName):
   4461 
   4462         FvList = []
   4463         if FdName.upper() in self.Profile.FdDict.keys():
   4464             FdObj = self.Profile.FdDict[FdName.upper()]
   4465             for elementRegion in FdObj.RegionList:
   4466                 if elementRegion.RegionType == 'FV':
   4467                     for elementRegionData in elementRegion.RegionDataList:
   4468                         if elementRegionData.endswith(".fv"):
   4469                             continue
   4470                         if elementRegionData != None and elementRegionData.upper() not in FvList:
   4471                             FvList.append(elementRegionData.upper())
   4472         return FvList
   4473 
   4474     ## __GetReferencedFdFvTuple() method

   4475     #

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

   4477     #

   4478     #   @param  self        The object pointer

   4479     #   @param  FfsFile     contains sections to be searched

   4480     #   @param  RefFdList   referenced FD by section

   4481     #   @param  RefFvList   referenced FV by section

   4482     #

   4483     def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
   4484 
   4485         for FfsObj in FvObj.FfsList:
   4486             if isinstance(FfsObj, FfsFileStatement.FileStatement):
   4487                 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
   4488                     RefFvList.append(FfsObj.FvName.upper())
   4489                 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
   4490                     RefFdList.append(FfsObj.FdName.upper())
   4491                 else:
   4492                     self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
   4493 
   4494     ## __GetReferencedFdFvTupleFromSection() method

   4495     #

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

   4497     #

   4498     #   @param  self        The object pointer

   4499     #   @param  FfsFile     contains sections to be searched

   4500     #   @param  FdList      referenced FD by section

   4501     #   @param  FvList      referenced FV by section

   4502     #

   4503     def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
   4504 
   4505         SectionStack = []
   4506         SectionStack.extend(FfsFile.SectionList)
   4507         while SectionStack != []:
   4508             SectionObj = SectionStack.pop()
   4509             if isinstance(SectionObj, FvImageSection.FvImageSection):
   4510                 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
   4511                     FvList.append(SectionObj.FvName.upper())
   4512                 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
   4513                     FvList.append(SectionObj.Fv.UiFvName.upper())
   4514                     self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
   4515 
   4516             if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
   4517                 SectionStack.extend(SectionObj.SectionList)
   4518 
   4519     ## CycleReferenceCheck() method

   4520     #

   4521     #   Check whether cycle reference exists in FDF

   4522     #

   4523     #   @param  self        The object pointer

   4524     #   @retval True        cycle reference exists

   4525     #   @retval False       Not exists cycle reference

   4526     #

   4527     def CycleReferenceCheck(self):
   4528         #

   4529         # Check the cycle between FV and FD image

   4530         #

   4531         MaxLength = len (self.Profile.FvDict)
   4532         for FvName in self.Profile.FvDict.keys():
   4533             LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
   4534             RefFvStack = []
   4535             RefFvStack.append(FvName)
   4536             FdAnalyzedList = []
   4537             
   4538             Index = 0
   4539             while RefFvStack != [] and Index < MaxLength:
   4540                 Index = Index + 1
   4541                 FvNameFromStack = RefFvStack.pop()
   4542                 if FvNameFromStack.upper() in self.Profile.FvDict.keys():
   4543                     FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
   4544                 else:
   4545                     continue
   4546 
   4547                 RefFdList = []
   4548                 RefFvList = []
   4549                 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
   4550 
   4551                 for RefFdName in RefFdList:
   4552                     if RefFdName in FdAnalyzedList:
   4553                         continue
   4554 
   4555                     LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
   4556                     FvInFdList = self.__GetFvInFd(RefFdName)
   4557                     if FvInFdList != []:
   4558                         for FvNameInFd in FvInFdList:
   4559                             LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
   4560                             if FvNameInFd not in RefFvStack:
   4561                                 RefFvStack.append(FvNameInFd)
   4562 
   4563                             if FvName in RefFvStack or FvNameFromStack in RefFvStack:
   4564                                 EdkLogger.info(LogStr)
   4565                                 return True
   4566                     FdAnalyzedList.append(RefFdName)
   4567 
   4568                 for RefFvName in RefFvList:
   4569                     LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
   4570                     if RefFvName not in RefFvStack:
   4571                         RefFvStack.append(RefFvName)
   4572 
   4573                     if FvName in RefFvStack or FvNameFromStack in RefFvStack:
   4574                         EdkLogger.info(LogStr)
   4575                         return True
   4576 
   4577         #

   4578         # Check the cycle between Capsule and FD image

   4579         #

   4580         MaxLength = len (self.Profile.CapsuleDict)
   4581         for CapName in self.Profile.CapsuleDict.keys():
   4582             #

   4583             # Capsule image to be checked.

   4584             #

   4585             LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
   4586             RefCapStack = []
   4587             RefCapStack.append(CapName)
   4588             FdAnalyzedList = []
   4589             FvAnalyzedList = []
   4590             
   4591             Index = 0
   4592             while RefCapStack != [] and Index < MaxLength:
   4593                 Index = Index + 1
   4594                 CapNameFromStack = RefCapStack.pop()
   4595                 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():
   4596                     CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
   4597                 else:
   4598                     continue
   4599 
   4600                 RefFvList = []
   4601                 RefFdList = []
   4602                 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)
   4603 
   4604                 FvListLength = 0
   4605                 FdListLength = 0
   4606                 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
   4607                     for RefFdName in RefFdList:
   4608                         if RefFdName in FdAnalyzedList:
   4609                             continue
   4610 
   4611                         LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
   4612                         CapInFdList = self.__GetCapInFd(RefFdName)
   4613                         if CapInFdList != []:
   4614                             for CapNameInFd in CapInFdList:
   4615                                 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)
   4616                                 if CapNameInFd not in RefCapStack:
   4617                                     RefCapStack.append(CapNameInFd)
   4618 
   4619                                 if CapName in RefCapStack or CapNameFromStack in RefCapStack:
   4620                                     EdkLogger.info(LogStr)
   4621                                     return True
   4622 
   4623                         FvInFdList = self.__GetFvInFd(RefFdName)
   4624                         if FvInFdList != []:
   4625                             for FvNameInFd in FvInFdList:
   4626                                 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
   4627                                 if FvNameInFd not in RefFvList:
   4628                                     RefFvList.append(FvNameInFd)
   4629 
   4630                         FdAnalyzedList.append(RefFdName)
   4631                     #

   4632                     # the number of the parsed FV and FD image

   4633                     #

   4634                     FvListLength = len (RefFvList)
   4635                     FdListLength = len (RefFdList)
   4636                     for RefFvName in RefFvList:
   4637                         if RefFvName in FvAnalyzedList:
   4638                             continue
   4639                         LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
   4640                         if RefFvName.upper() in self.Profile.FvDict.keys():
   4641                             FvObj = self.Profile.FvDict[RefFvName.upper()]
   4642                         else:
   4643                             continue
   4644                         self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
   4645                         FvAnalyzedList.append(RefFvName)
   4646 
   4647         return False
   4648 
   4649 if __name__ == "__main__":
   4650     import sys
   4651     try:
   4652         test_file = sys.argv[1]
   4653     except IndexError, v:
   4654         print "Usage: %s filename" % sys.argv[0]
   4655         sys.exit(1)
   4656 
   4657     parser = FdfParser(test_file)
   4658     try:
   4659         parser.ParseFile()
   4660         parser.CycleReferenceCheck()
   4661     except Warning, X:
   4662         print str(X)
   4663     else:
   4664         print "Success!"
   4665 
   4666