• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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#
19import re
20
21import Fd
22import Region
23import Fv
24import AprioriSection
25import FfsInfStatement
26import FfsFileStatement
27import VerSection
28import UiSection
29import FvImageSection
30import DataSection
31import DepexSection
32import CompressSection
33import GuidSection
34import Capsule
35import CapsuleData
36import Rule
37import RuleComplexFile
38import RuleSimpleFile
39import EfiSection
40import Vtf
41import ComponentStatement
42import OptionRom
43import OptRomInfStatement
44import OptRomFileStatement
45
46from GenFdsGlobalVariable import GenFdsGlobalVariable
47from Common.BuildToolError import *
48from Common import EdkLogger
49from Common.Misc import PathClass
50from Common.String import NormPath
51import Common.GlobalData as GlobalData
52from Common.Expression import *
53from Common import GlobalData
54from Common.String import ReplaceMacro
55
56from Common.Misc import tdict
57
58import re
59import Common.LongFilePathOs as os
60from 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, \
75T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
76(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
77
78SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
79
80RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
81RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
82RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")
83ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
84
85AllIncludeFileList = []
86
87# Get the closest parent
88def GetParentAtLine (Line):
89    for Profile in AllIncludeFileList:
90        if Profile.IsLineInFile(Line):
91            return Profile
92    return None
93
94# Check include loop
95def 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
102def 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#
117class 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#
140class 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#
156class 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#
214class 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#
256class 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
4649if __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