1## @file
2# parse FDF file
3#
4#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5#
6#  This program and the accompanying materials
7#  are licensed and made available under the terms and conditions of the BSD License
8#  which accompanies this distribution.  The full text of the license may be found at
9#  http://opensource.org/licenses/bsd-license.php
10#
11#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13#
14
15##
16# Import Modules
17#
18import re
19import Common.LongFilePathOs as os
20
21import CommonDataClass.FdfClass
22from Common.LongFilePathSupport import OpenLongFilePath as open
23from Common.MultipleWorkspace import MultipleWorkspace as mws
24
25##define T_CHAR_SPACE                ' '
26##define T_CHAR_NULL                 '\0'
27##define T_CHAR_CR                   '\r'
28##define T_CHAR_TAB                  '\t'
29##define T_CHAR_LF                   '\n'
30##define T_CHAR_SLASH                '/'
31##define T_CHAR_BACKSLASH            '\\'
32##define T_CHAR_DOUBLE_QUOTE         '\"'
33##define T_CHAR_SINGLE_QUOTE         '\''
34##define T_CHAR_STAR                 '*'
35##define T_CHAR_HASH                 '#'
36
37(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \
38T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
39(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
40
41SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
42
43IncludeFileList = []
44# Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF
45InputMacroDict = {}
46# All Macro values when parsing file, not replace existing Macro
47AllMacroList = []
48
49def GetRealFileLine (File, Line):
50
51    InsertedLines = 0
52    for Profile in IncludeFileList:
53        if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
54            return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1)
55        if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
56            InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList)
57
58    return (File, Line - InsertedLines)
59
60## The exception class that used to report error messages when parsing FDF
61#
62# Currently the "ToolName" is set to be "FDF Parser".
63#
64class Warning (Exception):
65    ## The constructor
66    #
67    #   @param  self        The object pointer
68    #   @param  Str         The message to record
69    #   @param  File        The FDF name
70    #   @param  Line        The Line number that error occurs
71    #
72    def __init__(self, Str, File=None, Line=None):
73
74        FileLineTuple = GetRealFileLine(File, Line)
75        self.FileName = FileLineTuple[0]
76        self.LineNumber = FileLineTuple[1]
77        self.message = Str + str(self.LineNumber)
78        self.ToolName = 'FDF Parser'
79
80## The MACRO class that used to record macro value data when parsing include file
81#
82#
83class MacroProfile :
84    ## The constructor
85    #
86    #   @param  self        The object pointer
87    #   @param  FileName    The file that to be parsed
88    #
89    def __init__(self, FileName, Line):
90        self.FileName = FileName
91        self.DefinedAtLine  = Line
92        self.MacroName = None
93        self.MacroValue = None
94
95## The Include file content class that used to record file data when parsing include file
96#
97# May raise Exception when opening file.
98#
99class IncludeFileProfile :
100    ## The constructor
101    #
102    #   @param  self        The object pointer
103    #   @param  FileName    The file that to be parsed
104    #
105    def __init__(self, FileName):
106        self.FileName = FileName
107        self.FileLinesList = []
108        try:
109            fsock = open(FileName, "rb", 0)
110            try:
111                self.FileLinesList = fsock.readlines()
112            finally:
113                fsock.close()
114
115        except IOError:
116            raise Warning("Error when opening file %s" % FileName)
117
118        self.InsertStartLineNumber = None
119        self.InsertAdjust = 0
120
121## The FDF content class that used to record file data when parsing FDF
122#
123# May raise Exception when opening file.
124#
125class FileProfile :
126    ## The constructor
127    #
128    #   @param  self        The object pointer
129    #   @param  FileName    The file that to be parsed
130    #
131    def __init__(self, FileName):
132        self.FileLinesList = []
133        try:
134            fsock = open(FileName, "rb", 0)
135            try:
136                self.FileLinesList = fsock.readlines()
137            finally:
138                fsock.close()
139
140        except IOError:
141            raise Warning("Error when opening file %s" % FileName)
142
143        self.PcdDict = {}
144        self.InfList = []
145
146        self.PcdFileLineDict = {}
147        self.InfFileLineList = []
148
149        self.FdDict = {}
150        self.FvDict = {}
151        self.CapsuleList = []
152#        self.VtfList = []
153#        self.RuleDict = {}
154
155## The syntax parser for FDF
156#
157# PreprocessFile method should be called prior to ParseFile
158# CycleReferenceCheck method can detect cycles in FDF contents
159#
160# GetNext*** procedures mean these procedures will get next token first, then make judgement.
161# Get*** procedures mean these procedures will make judgement on current token only.
162#
163class FdfParser(object):
164    ## The constructor
165    #
166    #   @param  self        The object pointer
167    #   @param  FileName    The file that to be parsed
168    #
169    def __init__(self, FileName):
170        self.Profile = FileProfile(FileName)
171        self.FileName = FileName
172        self.CurrentLineNumber = 1
173        self.CurrentOffsetWithinLine = 0
174        self.CurrentFdName = None
175        self.CurrentFvName = None
176        self.__Token = ""
177        self.__SkippedChars = ""
178
179        self.__WipeOffArea = []
180
181    ## __IsWhiteSpace() method
182    #
183    #   Whether char at current FileBufferPos is whitespace
184    #
185    #   @param  self        The object pointer
186    #   @param  Char        The char to test
187    #   @retval True        The char is a kind of white space
188    #   @retval False       The char is NOT a kind of white space
189    #
190    def __IsWhiteSpace(self, Char):
191        if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):
192            return True
193        else:
194            return False
195
196    ## __SkipWhiteSpace() method
197    #
198    #   Skip white spaces from current char, return number of chars skipped
199    #
200    #   @param  self        The object pointer
201    #   @retval Count       The number of chars skipped
202    #
203    def __SkipWhiteSpace(self):
204        Count = 0
205        while not self.__EndOfFile():
206            Count += 1
207            if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):
208                self.__SkippedChars += str(self.__CurrentChar())
209                self.__GetOneChar()
210
211            else:
212                Count = Count - 1
213                return Count
214
215    ## __EndOfFile() method
216    #
217    #   Judge current buffer pos is at file end
218    #
219    #   @param  self        The object pointer
220    #   @retval True        Current File buffer position is at file end
221    #   @retval False       Current File buffer position is NOT at file end
222    #
223    def __EndOfFile(self):
224        NumberOfLines = len(self.Profile.FileLinesList)
225        SizeOfLastLine = len(self.Profile.FileLinesList[-1])
226        if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
227            return True
228        elif self.CurrentLineNumber > NumberOfLines:
229            return True
230        else:
231            return False
232
233    ## __EndOfLine() method
234    #
235    #   Judge current buffer pos is at line end
236    #
237    #   @param  self        The object pointer
238    #   @retval True        Current File buffer position is at line end
239    #   @retval False       Current File buffer position is NOT at line end
240    #
241    def __EndOfLine(self):
242        if self.CurrentLineNumber > len(self.Profile.FileLinesList):
243            return True
244        SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
245        if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
246            return True
247        else:
248            return False
249
250    ## Rewind() method
251    #
252    #   Reset file data buffer to the initial state
253    #
254    #   @param  self        The object pointer
255    #
256    def Rewind(self):
257        self.CurrentLineNumber = 1
258        self.CurrentOffsetWithinLine = 0
259
260    ## __UndoOneChar() method
261    #
262    #   Go back one char in the file buffer
263    #
264    #   @param  self        The object pointer
265    #   @retval True        Successfully go back one char
266    #   @retval False       Not able to go back one char as file beginning reached
267    #
268    def __UndoOneChar(self):
269
270        if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
271            return False
272        elif self.CurrentOffsetWithinLine == 0:
273            self.CurrentLineNumber -= 1
274            self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1
275        else:
276            self.CurrentOffsetWithinLine -= 1
277        return True
278
279    ## __GetOneChar() method
280    #
281    #   Move forward one char in the file buffer
282    #
283    #   @param  self        The object pointer
284    #
285    def __GetOneChar(self):
286        if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
287            self.CurrentLineNumber += 1
288            self.CurrentOffsetWithinLine = 0
289        else:
290            self.CurrentOffsetWithinLine += 1
291
292    ## __CurrentChar() method
293    #
294    #   Get the char pointed to by the file buffer pointer
295    #
296    #   @param  self        The object pointer
297    #   @retval Char        Current char
298    #
299    def __CurrentChar(self):
300        return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]
301
302    ## __NextChar() method
303    #
304    #   Get the one char pass the char pointed to by the file buffer pointer
305    #
306    #   @param  self        The object pointer
307    #   @retval Char        Next char
308    #
309    def __NextChar(self):
310        if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
311            return self.Profile.FileLinesList[self.CurrentLineNumber][0]
312        else:
313            return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]
314
315    ## __SetCurrentCharValue() method
316    #
317    #   Modify the value of current char
318    #
319    #   @param  self        The object pointer
320    #   @param  Value       The new value of current char
321    #
322    def __SetCurrentCharValue(self, Value):
323        self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value
324
325    ## __CurrentLine() method
326    #
327    #   Get the list that contains current line contents
328    #
329    #   @param  self        The object pointer
330    #   @retval List        current line contents
331    #
332    def __CurrentLine(self):
333        return self.Profile.FileLinesList[self.CurrentLineNumber - 1]
334
335    def __StringToList(self):
336        self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
337        self.Profile.FileLinesList[-1].append(' ')
338
339    def __ReplaceMacros(self, Str, File, Line):
340        MacroEnd = 0
341        while Str.find('$(', MacroEnd) >= 0:
342            MacroStart = Str.find('$(', MacroEnd)
343            if Str.find(')', MacroStart) > 0:
344                MacroEnd = Str.find(')', MacroStart)
345                Name = Str[MacroStart + 2 : MacroEnd]
346                Value = None
347                if Name in InputMacroDict:
348                    Value = InputMacroDict[Name]
349
350                else:
351                    for Profile in AllMacroList:
352                        if Profile.FileName == File and Profile.MacroName == Name and Profile.DefinedAtLine <= Line:
353                            Value = Profile.MacroValue
354
355                if Value != None:
356                    Str = Str.replace('$(' + Name + ')', Value)
357                    MacroEnd = MacroStart + len(Value)
358
359            else:
360                raise Warning("Macro not complete At Line ", self.FileName, self.CurrentLineNumber)
361        return Str
362
363    def __ReplaceFragment(self, StartPos, EndPos, Value=' '):
364        if StartPos[0] == EndPos[0]:
365            Offset = StartPos[1]
366            while Offset <= EndPos[1]:
367                self.Profile.FileLinesList[StartPos[0]][Offset] = Value
368                Offset += 1
369            return
370
371        Offset = StartPos[1]
372        while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):
373            self.Profile.FileLinesList[StartPos[0]][Offset] = Value
374            Offset += 1
375
376        Line = StartPos[0]
377        while Line < EndPos[0]:
378            Offset = 0
379            while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):
380                self.Profile.FileLinesList[Line][Offset] = Value
381                Offset += 1
382            Line += 1
383
384        Offset = 0
385        while Offset <= EndPos[1]:
386            self.Profile.FileLinesList[EndPos[0]][Offset] = Value
387            Offset += 1
388
389
390    def __GetMacroName(self):
391        if not self.__GetNextToken():
392            raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
393        MacroName = self.__Token
394        NotFlag = False
395        if MacroName.startswith('!'):
396            NotFlag = True
397            MacroName = MacroName[1:].strip()
398
399        if not MacroName.startswith('$(') or not MacroName.endswith(')'):
400            raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},
401                          self.FileName, self.CurrentLineNumber)
402        MacroName = MacroName[2:-1]
403        return MacroName, NotFlag
404
405    ## PreprocessFile() method
406    #
407    #   Preprocess file contents, replace comments with spaces.
408    #   In the end, rewind the file buffer pointer to the beginning
409    #   BUGBUG: No !include statement processing contained in this procedure
410    #   !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
411    #
412    #   @param  self        The object pointer
413    #
414    def PreprocessFile(self):
415
416        self.Rewind()
417        InComment = False
418        DoubleSlashComment = False
419        HashComment = False
420        # HashComment in quoted string " " is ignored.
421        InString = False
422
423        while not self.__EndOfFile():
424
425            if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
426                InString = not InString
427            # meet new line, then no longer in a comment for // and '#'
428            if self.__CurrentChar() == T_CHAR_LF:
429                self.CurrentLineNumber += 1
430                self.CurrentOffsetWithinLine = 0
431                if InComment and DoubleSlashComment:
432                    InComment = False
433                    DoubleSlashComment = False
434                if InComment and HashComment:
435                    InComment = False
436                    HashComment = False
437            # check for */ comment end
438            elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:
439                self.__SetCurrentCharValue(T_CHAR_SPACE)
440                self.__GetOneChar()
441                self.__SetCurrentCharValue(T_CHAR_SPACE)
442                self.__GetOneChar()
443                InComment = False
444            # set comments to spaces
445            elif InComment:
446                self.__SetCurrentCharValue(T_CHAR_SPACE)
447                self.__GetOneChar()
448            # check for // comment
449            elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():
450                InComment = True
451                DoubleSlashComment = True
452            # check for '#' comment
453            elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:
454                InComment = True
455                HashComment = True
456            # check for /* comment start
457            elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:
458                self.__SetCurrentCharValue( T_CHAR_SPACE)
459                self.__GetOneChar()
460                self.__SetCurrentCharValue( T_CHAR_SPACE)
461                self.__GetOneChar()
462                InComment = True
463            else:
464                self.__GetOneChar()
465
466        # restore from ListOfList to ListOfString
467        self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
468        self.Rewind()
469
470    ## PreprocessIncludeFile() method
471    #
472    #   Preprocess file contents, replace !include statements with file contents.
473    #   In the end, rewind the file buffer pointer to the beginning
474    #
475    #   @param  self        The object pointer
476    #
477    def PreprocessIncludeFile(self):
478
479        while self.__GetNextToken():
480
481            if self.__Token == '!include':
482                IncludeLine = self.CurrentLineNumber
483                IncludeOffset = self.CurrentOffsetWithinLine - len('!include')
484                if not self.__GetNextToken():
485                    raise Warning("expected include file name At Line ", self.FileName, self.CurrentLineNumber)
486                IncFileName = self.__Token
487                if not os.path.isabs(IncFileName):
488                    if IncFileName.startswith('$(WORKSPACE)'):
489                        Str = mws.handleWsMacro(IncFileName)
490                        Str = Str.replace('$(WORKSPACE)', os.environ.get('WORKSPACE'))
491                        if os.path.exists(Str):
492                            if not os.path.isabs(Str):
493                                Str = os.path.abspath(Str)
494                        IncFileName = Str
495                    else:
496                        # file is in the same dir with FDF file
497                        FullFdf = self.FileName
498                        if not os.path.isabs(self.FileName):
499                            FullFdf = mws.join(os.environ.get('WORKSPACE'), self.FileName)
500
501                        IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName)
502
503                if not os.path.exists(os.path.normpath(IncFileName)):
504                    raise Warning("Include file not exists At Line ", self.FileName, self.CurrentLineNumber)
505
506                IncFileProfile = IncludeFileProfile(os.path.normpath(IncFileName))
507
508                CurrentLine = self.CurrentLineNumber
509                CurrentOffset = self.CurrentOffsetWithinLine
510                # list index of the insertion, note that line number is 'CurrentLine + 1'
511                InsertAtLine = CurrentLine
512                IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
513                # deal with remaining portions after "!include filename", if exists.
514                if self.__GetNextToken():
515                    if self.CurrentLineNumber == CurrentLine:
516                        RemainingLine = self.__CurrentLine()[CurrentOffset:]
517                        self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
518                        IncFileProfile.InsertAdjust += 1
519                        self.CurrentLineNumber += 1
520                        self.CurrentOffsetWithinLine = 0
521
522                for Line in IncFileProfile.FileLinesList:
523                    self.Profile.FileLinesList.insert(InsertAtLine, Line)
524                    self.CurrentLineNumber += 1
525                    InsertAtLine += 1
526
527                IncludeFileList.append(IncFileProfile)
528
529                # comment out the processed include file statement
530                TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
531                TempList.insert(IncludeOffset, '#')
532                self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
533
534        self.Rewind()
535
536    ## PreprocessIncludeFile() method
537    #
538    #   Preprocess file contents, replace !include statements with file contents.
539    #   In the end, rewind the file buffer pointer to the beginning
540    #
541    #   @param  self        The object pointer
542    #
543    def PreprocessConditionalStatement(self):
544        # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
545        IfList = []
546        while self.__GetNextToken():
547            if self.__Token == 'DEFINE':
548                DefineLine = self.CurrentLineNumber - 1
549                DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
550                if not self.__GetNextToken():
551                    raise Warning("expected Macro name At Line ", self.FileName, self.CurrentLineNumber)
552                Macro = self.__Token
553                if not self.__IsToken( "="):
554                    raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
555
556                if not self.__GetNextToken():
557                    raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
558
559                if self.__GetStringData():
560                    pass
561                Value = self.__Token
562                if not Macro in InputMacroDict:
563                    FileLineTuple = GetRealFileLine(self.FileName, DefineLine + 1)
564                    MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
565                    MacProfile.MacroName = Macro
566                    MacProfile.MacroValue = Value
567                    AllMacroList.append(MacProfile)
568                self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
569
570            elif self.__Token in ('!ifdef', '!ifndef', '!if'):
571                IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
572                IfList.append([IfStartPos, None, None])
573                CondLabel = self.__Token
574
575                MacroName, NotFlag = self.__GetMacroName()
576                NotDefineFlag = False
577                if CondLabel == '!ifndef':
578                    NotDefineFlag = True
579                if CondLabel == '!ifdef' or CondLabel == '!ifndef':
580                    if NotFlag:
581                        raise Warning("'NOT' operation not allowed for Macro name At Line ", self.FileName, self.CurrentLineNumber)
582
583                if CondLabel == '!if':
584
585                    if not self.__GetNextOp():
586                        raise Warning("expected !endif At Line ", self.FileName, self.CurrentLineNumber)
587
588                    if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
589                        Op = self.__Token
590                        if not self.__GetNextToken():
591                            raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
592                        if self.__GetStringData():
593                            pass
594                        MacroValue = self.__Token
595                        ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
596                        if NotFlag:
597                            ConditionSatisfied = not ConditionSatisfied
598                        BranchDetermined = ConditionSatisfied
599                    else:
600                        self.CurrentOffsetWithinLine -= len(self.__Token)
601                        ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
602                        if NotFlag:
603                            ConditionSatisfied = not ConditionSatisfied
604                        BranchDetermined = ConditionSatisfied
605                    IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
606                    if ConditionSatisfied:
607                        self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
608
609                else:
610                    ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1)
611                    if NotDefineFlag:
612                        ConditionSatisfied = not ConditionSatisfied
613                    BranchDetermined = ConditionSatisfied
614                    IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
615                    if ConditionSatisfied:
616                        self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
617
618            elif self.__Token in ('!elseif', '!else'):
619                ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
620                if len(IfList) <= 0:
621                    raise Warning("Missing !if statement At Line ", self.FileName, self.CurrentLineNumber)
622                if IfList[-1][1]:
623                    IfList[-1] = [ElseStartPos, False, True]
624                    self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
625                else:
626                    self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
627                    IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
628                    if self.__Token == '!elseif':
629                        MacroName, NotFlag = self.__GetMacroName()
630                        if not self.__GetNextOp():
631                            raise Warning("expected !endif At Line ", self.FileName, self.CurrentLineNumber)
632
633                        if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
634                            Op = self.__Token
635                            if not self.__GetNextToken():
636                                raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
637                            if self.__GetStringData():
638                                pass
639                            MacroValue = self.__Token
640                            ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
641                            if NotFlag:
642                                ConditionSatisfied = not ConditionSatisfied
643
644                        else:
645                            self.CurrentOffsetWithinLine -= len(self.__Token)
646                            ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
647                            if NotFlag:
648                                ConditionSatisfied = not ConditionSatisfied
649
650                        IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
651
652                    if IfList[-1][1]:
653                        if IfList[-1][2]:
654                            IfList[-1][1] = False
655                        else:
656                            IfList[-1][2] = True
657                            self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
658
659
660            elif self.__Token == '!endif':
661                if IfList[-1][1]:
662                    self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
663                else:
664                    self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
665
666                IfList.pop()
667
668
669        if len(IfList) > 0:
670            raise Warning("Missing !endif At Line ", self.FileName, self.CurrentLineNumber)
671        self.Rewind()
672
673    def __EvaluateConditional(self, Name, Line, Op = None, Value = None):
674
675        FileLineTuple = GetRealFileLine(self.FileName, Line)
676        if Name in InputMacroDict:
677            MacroValue = InputMacroDict[Name]
678            if Op == None:
679                if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE':
680                    return False
681                return True
682            elif Op == '!=':
683                if Value != MacroValue:
684                    return True
685                else:
686                    return False
687            elif Op == '==':
688                if Value == MacroValue:
689                    return True
690                else:
691                    return False
692            else:
693                if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())):
694                    InputVal = long(Value, 0)
695                    MacroVal = long(MacroValue, 0)
696                    if Op == '>':
697                        if MacroVal > InputVal:
698                            return True
699                        else:
700                            return False
701                    elif Op == '>=':
702                        if MacroVal >= InputVal:
703                            return True
704                        else:
705                            return False
706                    elif Op == '<':
707                        if MacroVal < InputVal:
708                            return True
709                        else:
710                            return False
711                    elif Op == '<=':
712                        if MacroVal <= InputVal:
713                            return True
714                        else:
715                            return False
716                    else:
717                        return False
718                else:
719                    raise Warning("Value %s is not a number At Line ", self.FileName, Line)
720
721        for Profile in AllMacroList:
722            if Profile.FileName == FileLineTuple[0] and Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]:
723                if Op == None:
724                    if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE':
725                        return False
726                    return True
727                elif Op == '!=':
728                    if Value != Profile.MacroValue:
729                        return True
730                    else:
731                        return False
732                elif Op == '==':
733                    if Value == Profile.MacroValue:
734                        return True
735                    else:
736                        return False
737                else:
738                    if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())):
739                        InputVal = long(Value, 0)
740                        MacroVal = long(Profile.MacroValue, 0)
741                        if Op == '>':
742                            if MacroVal > InputVal:
743                                return True
744                            else:
745                                return False
746                        elif Op == '>=':
747                            if MacroVal >= InputVal:
748                                return True
749                            else:
750                                return False
751                        elif Op == '<':
752                            if MacroVal < InputVal:
753                                return True
754                            else:
755                                return False
756                        elif Op == '<=':
757                            if MacroVal <= InputVal:
758                                return True
759                            else:
760                                return False
761                        else:
762                            return False
763                    else:
764                        raise Warning("Value %s is not a number At Line ", self.FileName, Line)
765
766        return False
767
768    ## __IsToken() method
769    #
770    #   Check whether input string is found from current char position along
771    #   If found, the string value is put into self.__Token
772    #
773    #   @param  self        The object pointer
774    #   @param  String      The string to search
775    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
776    #   @retval True        Successfully find string, file buffer pointer moved forward
777    #   @retval False       Not able to find string, file buffer pointer not changed
778    #
779    def __IsToken(self, String, IgnoreCase = False):
780        self.__SkipWhiteSpace()
781
782        # Only consider the same line, no multi-line token allowed
783        StartPos = self.CurrentOffsetWithinLine
784        index = -1
785        if IgnoreCase:
786            index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
787        else:
788            index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
789        if index == 0:
790            self.CurrentOffsetWithinLine += len(String)
791            self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
792            return True
793        return False
794
795    ## __IsKeyword() method
796    #
797    #   Check whether input keyword is found from current char position along, whole word only!
798    #   If found, the string value is put into self.__Token
799    #
800    #   @param  self        The object pointer
801    #   @param  Keyword     The string to search
802    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
803    #   @retval True        Successfully find string, file buffer pointer moved forward
804    #   @retval False       Not able to find string, file buffer pointer not changed
805    #
806    def __IsKeyword(self, KeyWord, IgnoreCase = False):
807        self.__SkipWhiteSpace()
808
809        # Only consider the same line, no multi-line token allowed
810        StartPos = self.CurrentOffsetWithinLine
811        index = -1
812        if IgnoreCase:
813            index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())
814        else:
815            index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)
816        if index == 0:
817            followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
818            if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:
819                return False
820            self.CurrentOffsetWithinLine += len(KeyWord)
821            self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
822            return True
823        return False
824
825    ## __GetNextWord() method
826    #
827    #   Get next C name from file lines
828    #   If found, the string value is put into self.__Token
829    #
830    #   @param  self        The object pointer
831    #   @retval True        Successfully find a C name string, file buffer pointer moved forward
832    #   @retval False       Not able to find a C name string, file buffer pointer not changed
833    #
834    def __GetNextWord(self):
835        self.__SkipWhiteSpace()
836        if self.__EndOfFile():
837            return False
838
839        TempChar = self.__CurrentChar()
840        StartPos = self.CurrentOffsetWithinLine
841        if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
842            self.__GetOneChar()
843            while not self.__EndOfLine():
844                TempChar = self.__CurrentChar()
845                if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
846                or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
847                    self.__GetOneChar()
848
849                else:
850                    break
851
852            self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
853            return True
854
855        return False
856
857    ## __GetNextToken() method
858    #
859    #   Get next token unit before a seperator
860    #   If found, the string value is put into self.__Token
861    #
862    #   @param  self        The object pointer
863    #   @retval True        Successfully find a token unit, file buffer pointer moved forward
864    #   @retval False       Not able to find a token unit, file buffer pointer not changed
865    #
866    def __GetNextToken(self):
867        # Skip leading spaces, if exist.
868        self.__SkipWhiteSpace()
869        if self.__EndOfFile():
870            return False
871        # Record the token start position, the position of the first non-space char.
872        StartPos = self.CurrentOffsetWithinLine
873        StartLine = self.CurrentLineNumber
874        while not self.__EndOfLine():
875            TempChar = self.__CurrentChar()
876            # Try to find the end char that is not a space and not in seperator tuple.
877            # That is, when we got a space or any char in the tuple, we got the end of token.
878            if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:
879                self.__GetOneChar()
880            # if we happen to meet a seperator as the first char, we must proceed to get it.
881            # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
882            elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
883                self.__GetOneChar()
884                break
885            else:
886                break
887#        else:
888#            return False
889
890        EndPos = self.CurrentOffsetWithinLine
891        if self.CurrentLineNumber != StartLine:
892            EndPos = len(self.Profile.FileLinesList[StartLine-1])
893        self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]
894        if StartPos != self.CurrentOffsetWithinLine:
895            return True
896        else:
897            return False
898
899    def __GetNextOp(self):
900        # Skip leading spaces, if exist.
901        self.__SkipWhiteSpace()
902        if self.__EndOfFile():
903            return False
904        # Record the token start position, the position of the first non-space char.
905        StartPos = self.CurrentOffsetWithinLine
906        while not self.__EndOfLine():
907            TempChar = self.__CurrentChar()
908            # Try to find the end char that is not a space
909            if not str(TempChar).isspace():
910                self.__GetOneChar()
911            else:
912                break
913        else:
914            return False
915
916        if StartPos != self.CurrentOffsetWithinLine:
917            self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
918            return True
919        else:
920            return False
921    ## __GetNextGuid() method
922    #
923    #   Get next token unit before a seperator
924    #   If found, the GUID string is put into self.__Token
925    #
926    #   @param  self        The object pointer
927    #   @retval True        Successfully find a registry format GUID, file buffer pointer moved forward
928    #   @retval False       Not able to find a registry format GUID, file buffer pointer not changed
929    #
930    def __GetNextGuid(self):
931
932        if not self.__GetNextToken():
933            return False
934        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}')
935        if p.match(self.__Token) != None:
936            return True
937        else:
938            self.__UndoToken()
939            return False
940
941    ## __UndoToken() method
942    #
943    #   Go back one token unit in file buffer
944    #
945    #   @param  self        The object pointer
946    #
947    def __UndoToken(self):
948        self.__UndoOneChar()
949        while self.__CurrentChar().isspace():
950            if not self.__UndoOneChar():
951                self.__GetOneChar()
952                return
953
954
955        StartPos = self.CurrentOffsetWithinLine
956        CurrentLine = self.CurrentLineNumber
957        while CurrentLine == self.CurrentLineNumber:
958
959            TempChar = self.__CurrentChar()
960            # Try to find the end char that is not a space and not in seperator tuple.
961            # That is, when we got a space or any char in the tuple, we got the end of token.
962            if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:
963                if not self.__UndoOneChar():
964                    break
965            # if we happen to meet a seperator as the first char, we must proceed to get it.
966            # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
967            elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
968                return
969            else:
970                break
971
972        self.__GetOneChar()
973
974    ## __HexDigit() method
975    #
976    #   Whether char input is a Hex data bit
977    #
978    #   @param  self        The object pointer
979    #   @param  TempChar    The char to test
980    #   @retval True        The char is a Hex data bit
981    #   @retval False       The char is NOT a Hex data bit
982    #
983    def __HexDigit(self, TempChar):
984        if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \
985                or (TempChar >= '0' and TempChar <= '9'):
986                    return True
987        else:
988            return False
989
990    def __IsHex(self, HexStr):
991        if not HexStr.upper().startswith("0X"):
992            return False
993        if len(self.__Token) <= 2:
994            return False
995        charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]
996        if len(charList) == 0:
997            return True
998        else:
999            return False
1000    ## __GetNextHexNumber() method
1001    #
1002    #   Get next HEX data before a seperator
1003    #   If found, the HEX data is put into self.__Token
1004    #
1005    #   @param  self        The object pointer
1006    #   @retval True        Successfully find a HEX data, file buffer pointer moved forward
1007    #   @retval False       Not able to find a HEX data, file buffer pointer not changed
1008    #
1009    def __GetNextHexNumber(self):
1010        if not self.__GetNextToken():
1011            return False
1012        if self.__IsHex(self.__Token):
1013            return True
1014        else:
1015            self.__UndoToken()
1016            return False
1017
1018    ## __GetNextDecimalNumber() method
1019    #
1020    #   Get next decimal data before a seperator
1021    #   If found, the decimal data is put into self.__Token
1022    #
1023    #   @param  self        The object pointer
1024    #   @retval True        Successfully find a decimal data, file buffer pointer moved forward
1025    #   @retval False       Not able to find a decimal data, file buffer pointer not changed
1026    #
1027    def __GetNextDecimalNumber(self):
1028        if not self.__GetNextToken():
1029            return False
1030        if self.__Token.isdigit():
1031            return True
1032        else:
1033            self.__UndoToken()
1034            return False
1035
1036    ## __GetNextPcdName() method
1037    #
1038    #   Get next PCD token space C name and PCD C name pair before a seperator
1039    #   If found, the decimal data is put into self.__Token
1040    #
1041    #   @param  self        The object pointer
1042    #   @retval Tuple       PCD C name and PCD token space C name pair
1043    #
1044    def __GetNextPcdName(self):
1045        if not self.__GetNextWord():
1046            raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber)
1047        pcdTokenSpaceCName = self.__Token
1048
1049        if not self.__IsToken( "."):
1050            raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber)
1051
1052        if not self.__GetNextWord():
1053            raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber)
1054        pcdCName = self.__Token
1055
1056        return (pcdCName, pcdTokenSpaceCName)
1057
1058    ## __GetStringData() method
1059    #
1060    #   Get string contents quoted in ""
1061    #   If found, the decimal data is put into self.__Token
1062    #
1063    #   @param  self        The object pointer
1064    #   @retval True        Successfully find a string data, file buffer pointer moved forward
1065    #   @retval False       Not able to find a string data, file buffer pointer not changed
1066    #
1067    def __GetStringData(self):
1068        if self.__Token.startswith("\"") or self.__Token.startswith("L\""):
1069            self.__UndoToken()
1070            self.__SkipToToken("\"")
1071            currentLineNumber = self.CurrentLineNumber
1072
1073            if not self.__SkipToToken("\""):
1074                raise Warning("Missing Quote \" for String At Line ", self.FileName, self.CurrentLineNumber)
1075            if currentLineNumber != self.CurrentLineNumber:
1076                raise Warning("Missing Quote \" for String At Line ", self.FileName, self.CurrentLineNumber)
1077            self.__Token = self.__SkippedChars.rstrip('\"')
1078            return True
1079
1080        elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):
1081            self.__UndoToken()
1082            self.__SkipToToken("\'")
1083            currentLineNumber = self.CurrentLineNumber
1084
1085            if not self.__SkipToToken("\'"):
1086                raise Warning("Missing Quote \' for String At Line ", self.FileName, self.CurrentLineNumber)
1087            if currentLineNumber != self.CurrentLineNumber:
1088                raise Warning("Missing Quote \' for String At Line ", self.FileName, self.CurrentLineNumber)
1089            self.__Token = self.__SkippedChars.rstrip('\'')
1090            return True
1091
1092        else:
1093            return False
1094
1095    ## __SkipToToken() method
1096    #
1097    #   Search forward in file buffer for the string
1098    #   The skipped chars are put into self.__SkippedChars
1099    #
1100    #   @param  self        The object pointer
1101    #   @param  String      The string to search
1102    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
1103    #   @retval True        Successfully find the string, file buffer pointer moved forward
1104    #   @retval False       Not able to find the string, file buffer pointer not changed
1105    #
1106    def __SkipToToken(self, String, IgnoreCase = False):
1107        StartPos = self.GetFileBufferPos()
1108
1109        self.__SkippedChars = ""
1110        while not self.__EndOfFile():
1111            index = -1
1112            if IgnoreCase:
1113                index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
1114            else:
1115                index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
1116            if index == 0:
1117                self.CurrentOffsetWithinLine += len(String)
1118                self.__SkippedChars += String
1119                return True
1120            self.__SkippedChars += str(self.__CurrentChar())
1121            self.__GetOneChar()
1122
1123        self.SetFileBufferPos( StartPos)
1124        self.__SkippedChars = ""
1125        return False
1126
1127    ## GetFileBufferPos() method
1128    #
1129    #   Return the tuple of current line and offset within the line
1130    #
1131    #   @param  self        The object pointer
1132    #   @retval Tuple       Line number and offset pair
1133    #
1134    def GetFileBufferPos(self):
1135        return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
1136
1137    ## SetFileBufferPos() method
1138    #
1139    #   Restore the file buffer position
1140    #
1141    #   @param  self        The object pointer
1142    #   @param  Pos         The new file buffer position
1143    #
1144    def SetFileBufferPos(self, Pos):
1145        (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos
1146
1147    ## ParseFile() method
1148    #
1149    #   Parse the file profile buffer to extract fd, fv ... information
1150    #   Exception will be raised if syntax error found
1151    #
1152    #   @param  self        The object pointer
1153    #
1154    def ParseFile(self):
1155
1156        try:
1157            self.__StringToList()
1158            self.PreprocessFile()
1159            self.PreprocessIncludeFile()
1160            self.__StringToList()
1161            self.PreprocessFile()
1162            self.PreprocessConditionalStatement()
1163            self.__StringToList()
1164            for Pos in self.__WipeOffArea:
1165                self.__ReplaceFragment(Pos[0], Pos[1])
1166            self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
1167
1168            while self.__GetDefines():
1169                pass
1170
1171            Index = 0
1172            while Index < len(self.Profile.FileLinesList):
1173                FileLineTuple = GetRealFileLine(self.FileName, Index + 1)
1174                self.Profile.FileLinesList[Index] = self.__ReplaceMacros(self.Profile.FileLinesList[Index], FileLineTuple[0], FileLineTuple[1])
1175                Index += 1
1176
1177            while self.__GetFd():
1178                pass
1179
1180            while self.__GetFv():
1181                pass
1182
1183            while self.__GetCapsule():
1184                pass
1185
1186#            while self.__GetVtf():
1187#                pass
1188#
1189#            while self.__GetRule():
1190#                pass
1191
1192
1193        except Warning, X:
1194            self.__UndoToken()
1195            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1196            X.message += '\nGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1197                'Previous Token: \"%s\" At line: %d, Offset Within Line: %d\n' \
1198                    % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'), FileLineTuple[1], self.CurrentOffsetWithinLine)
1199            raise
1200
1201    ## __GetDefines() method
1202    #
1203    #   Get Defines section contents and store its data into AllMacrosList
1204    #
1205    #   @param  self        The object pointer
1206    #   @retval True        Successfully find a Defines
1207    #   @retval False       Not able to find a Defines
1208    #
1209    def __GetDefines(self):
1210
1211        if not self.__GetNextToken():
1212            return False
1213
1214        S = self.__Token.upper()
1215        if S.startswith("[") and not S.startswith("[DEFINES"):
1216            if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1217                and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
1218                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)
1219            self.__UndoToken()
1220            return False
1221
1222        self.__UndoToken()
1223        if not self.__IsToken("[DEFINES", True):
1224            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1225            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1226            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1227            raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)
1228
1229        if not self.__IsToken( "]"):
1230            raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1231
1232        while self.__GetNextWord():
1233            Macro = self.__Token
1234
1235            if not self.__IsToken("="):
1236                raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1237            if not self.__GetNextToken() or self.__Token.startswith('['):
1238                raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
1239            Value = self.__Token
1240            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1241            MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
1242            MacProfile.MacroName = Macro
1243            MacProfile.MacroValue = Value
1244            AllMacroList.append(MacProfile)
1245
1246        return False
1247
1248    ## __GetFd() method
1249    #
1250    #   Get FD section contents and store its data into FD dictionary of self.Profile
1251    #
1252    #   @param  self        The object pointer
1253    #   @retval True        Successfully find a FD
1254    #   @retval False       Not able to find a FD
1255    #
1256    def __GetFd(self):
1257
1258        if not self.__GetNextToken():
1259            return False
1260
1261        S = self.__Token.upper()
1262        if S.startswith("[") and not S.startswith("[FD."):
1263            if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1264                and not S.startswith("[VTF.") and not S.startswith("[RULE."):
1265                raise Warning("Unknown section At Line ", self.FileName, self.CurrentLineNumber)
1266            self.__UndoToken()
1267            return False
1268
1269        self.__UndoToken()
1270        if not self.__IsToken("[FD.", True):
1271            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1272            print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1273                    % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1274            raise Warning("expected [FD.] At Line ", self.FileName, self.CurrentLineNumber)
1275
1276        FdName = self.__GetUiName()
1277        self.CurrentFdName = FdName.upper()
1278
1279        if not self.__IsToken( "]"):
1280            raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
1281
1282        FdObj = CommonDataClass.FdfClass.FDClassObject()
1283        FdObj.FdUiName = self.CurrentFdName
1284        self.Profile.FdDict[self.CurrentFdName] = FdObj
1285        Status = self.__GetCreateFile(FdObj)
1286        if not Status:
1287            raise Warning("FD name error At Line ", self.FileName, self.CurrentLineNumber)
1288
1289        if not self.__GetTokenStatements(FdObj):
1290            return False
1291
1292        self.__GetDefineStatements(FdObj)
1293
1294        self.__GetSetStatements(FdObj)
1295
1296        if not self.__GetRegionLayout(FdObj):
1297            raise Warning("expected region layout At Line ", self.FileName, self.CurrentLineNumber)
1298
1299        while self.__GetRegionLayout(FdObj):
1300            pass
1301        return True
1302
1303    ## __GetUiName() method
1304    #
1305    #   Return the UI name of a section
1306    #
1307    #   @param  self        The object pointer
1308    #   @retval FdName      UI name
1309    #
1310    def __GetUiName(self):
1311        FdName = ""
1312        if self.__GetNextWord():
1313            FdName = self.__Token
1314
1315        return FdName
1316
1317    ## __GetCreateFile() method
1318    #
1319    #   Return the output file name of object
1320    #
1321    #   @param  self        The object pointer
1322    #   @param  Obj         object whose data will be stored in file
1323    #   @retval FdName      UI name
1324    #
1325    def __GetCreateFile(self, Obj):
1326
1327        if self.__IsKeyword( "CREATE_FILE"):
1328            if not self.__IsToken( "="):
1329                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1330
1331            if not self.__GetNextToken():
1332                raise Warning("expected file name At Line ", self.FileName, self.CurrentLineNumber)
1333
1334            FileName = self.__Token
1335            Obj.CreateFileName = FileName
1336
1337        return True
1338
1339    ## __GetTokenStatements() method
1340    #
1341    #   Get token statements
1342    #
1343    #   @param  self        The object pointer
1344    #   @param  Obj         for whom token statement is got
1345    #   @retval True        Successfully find a token statement
1346    #   @retval False       Not able to find a token statement
1347    #
1348    def __GetTokenStatements(self, Obj):
1349        if not self.__IsKeyword( "BaseAddress"):
1350            raise Warning("BaseAddress missing At Line ", self.FileName, self.CurrentLineNumber)
1351
1352        if not self.__IsToken( "="):
1353            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1354
1355        if not self.__GetNextHexNumber():
1356            raise Warning("expected Hex base address At Line ", self.FileName, self.CurrentLineNumber)
1357
1358        Obj.BaseAddress = self.__Token
1359
1360        if self.__IsToken( "|"):
1361            pcdPair = self.__GetNextPcdName()
1362            Obj.BaseAddressPcd = pcdPair
1363            self.Profile.PcdDict[pcdPair] = long(Obj.BaseAddress, 0)
1364            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1365            self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1366
1367        if not self.__IsKeyword( "Size"):
1368            raise Warning("Size missing At Line ", self.FileName, self.CurrentLineNumber)
1369
1370        if not self.__IsToken( "="):
1371            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1372
1373        if not self.__GetNextHexNumber():
1374            raise Warning("expected Hex size At Line ", self.FileName, self.CurrentLineNumber)
1375
1376
1377        Obj.Size = long(self.__Token, 0)
1378
1379        if self.__IsToken( "|"):
1380            pcdPair = self.__GetNextPcdName()
1381            Obj.SizePcd = pcdPair
1382            self.Profile.PcdDict[pcdPair] = Obj.Size
1383            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1384            self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1385
1386        if not self.__IsKeyword( "ErasePolarity"):
1387            raise Warning("ErasePolarity missing At Line ", self.FileName, self.CurrentLineNumber)
1388
1389        if not self.__IsToken( "="):
1390            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1391
1392        if not self.__GetNextToken():
1393            raise Warning("expected Erase Polarity At Line ", self.FileName, self.CurrentLineNumber)
1394
1395        if self.__Token != "1" and self.__Token != "0":
1396            raise Warning("expected 1 or 0 Erase Polarity At Line ", self.FileName, self.CurrentLineNumber)
1397
1398        Obj.ErasePolarity = self.__Token
1399
1400        Status = self.__GetBlockStatements(Obj)
1401        return Status
1402
1403    ## __GetAddressStatements() method
1404    #
1405    #   Get address statements
1406    #
1407    #   @param  self        The object pointer
1408    #   @param  Obj         for whom address statement is got
1409    #   @retval True        Successfully find
1410    #   @retval False       Not able to find
1411    #
1412    def __GetAddressStatements(self, Obj):
1413
1414        if self.__IsKeyword("BsBaseAddress"):
1415            if not self.__IsToken( "="):
1416                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1417
1418            if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1419                raise Warning("expected address At Line ", self.FileName, self.CurrentLineNumber)
1420
1421            BsAddress = long(self.__Token, 0)
1422            Obj.BsBaseAddress = BsAddress
1423
1424        if self.__IsKeyword("RtBaseAddress"):
1425            if not self.__IsToken( "="):
1426                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1427
1428            if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1429                raise Warning("expected address At Line ", self.FileName, self.CurrentLineNumber)
1430
1431            RtAddress = long(self.__Token, 0)
1432            Obj.RtBaseAddress = RtAddress
1433
1434    ## __GetBlockStatements() method
1435    #
1436    #   Get block statements
1437    #
1438    #   @param  self        The object pointer
1439    #   @param  Obj         for whom block statement is got
1440    #   @retval True        Successfully find
1441    #   @retval False       Not able to find
1442    #
1443    def __GetBlockStatements(self, Obj):
1444
1445        if not self.__GetBlockStatement(Obj):
1446            #set default block size is 1
1447            Obj.BlockSizeList.append((1, Obj.Size, None))
1448            return True
1449
1450        while self.__GetBlockStatement(Obj):
1451            pass
1452
1453        for Item in Obj.BlockSizeList:
1454            if Item[0] == None or Item[1] == None:
1455                raise Warning("expected block statement for Fd Section", self.FileName, self.CurrentLineNumber)
1456
1457        return True
1458
1459    ## __GetBlockStatement() method
1460    #
1461    #   Get block statement
1462    #
1463    #   @param  self        The object pointer
1464    #   @param  Obj         for whom block statement is got
1465    #   @retval True        Successfully find
1466    #   @retval False       Not able to find
1467    #
1468    def __GetBlockStatement(self, Obj):
1469        if not self.__IsKeyword( "BlockSize"):
1470            return False
1471
1472        if not self.__IsToken( "="):
1473            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1474
1475        if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
1476            raise Warning("expected Hex block size At Line ", self.FileName, self.CurrentLineNumber)
1477
1478        BlockSize = long(self.__Token, 0)
1479        BlockSizePcd = None
1480        if self.__IsToken( "|"):
1481            PcdPair = self.__GetNextPcdName()
1482            BlockSizePcd = PcdPair
1483            self.Profile.PcdDict[PcdPair] = BlockSize
1484            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1485            self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1486
1487        BlockNumber = None
1488        if self.__IsKeyword( "NumBlocks"):
1489            if not self.__IsToken( "="):
1490                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1491
1492            if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1493                raise Warning("expected block numbers At Line ", self.FileName, self.CurrentLineNumber)
1494
1495            BlockNumber = long(self.__Token, 0)
1496
1497        Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
1498        return True
1499
1500    ## __GetDefineStatements() method
1501    #
1502    #   Get define statements
1503    #
1504    #   @param  self        The object pointer
1505    #   @param  Obj         for whom define statement is got
1506    #   @retval True        Successfully find
1507    #   @retval False       Not able to find
1508    #
1509    def __GetDefineStatements(self, Obj):
1510        while self.__GetDefineStatement( Obj):
1511            pass
1512
1513    ## __GetDefineStatement() method
1514    #
1515    #   Get define statement
1516    #
1517    #   @param  self        The object pointer
1518    #   @param  Obj         for whom define statement is got
1519    #   @retval True        Successfully find
1520    #   @retval False       Not able to find
1521    #
1522    def __GetDefineStatement(self, Obj):
1523        if self.__IsKeyword("DEFINE"):
1524            self.__GetNextToken()
1525            Macro = self.__Token
1526            if not self.__IsToken( "="):
1527                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1528
1529            if not self.__GetNextToken():
1530                raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
1531
1532            Value = self.__Token
1533            Macro = '$(' + Macro + ')'
1534            Obj.DefineVarDict[Macro] = Value
1535            return True
1536
1537        return False
1538
1539    ## __GetSetStatements() method
1540    #
1541    #   Get set statements
1542    #
1543    #   @param  self        The object pointer
1544    #   @param  Obj         for whom set statement is got
1545    #   @retval True        Successfully find
1546    #   @retval False       Not able to find
1547    #
1548    def __GetSetStatements(self, Obj):
1549        while self.__GetSetStatement(Obj):
1550            pass
1551
1552    ## __GetSetStatement() method
1553    #
1554    #   Get set statement
1555    #
1556    #   @param  self        The object pointer
1557    #   @param  Obj         for whom set statement is got
1558    #   @retval True        Successfully find
1559    #   @retval False       Not able to find
1560    #
1561    def __GetSetStatement(self, Obj):
1562        if self.__IsKeyword("SET"):
1563            PcdPair = self.__GetNextPcdName()
1564
1565            if not self.__IsToken( "="):
1566                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1567
1568            if not self.__GetNextToken():
1569                raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
1570
1571            Value = self.__Token
1572            if Value.startswith("{"):
1573                # deal with value with {}
1574                if not self.__SkipToToken( "}"):
1575                    raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
1576                Value += self.__SkippedChars
1577
1578            Obj.SetVarDict[PcdPair] = Value
1579            self.Profile.PcdDict[PcdPair] = Value
1580            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1581            self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
1582            return True
1583
1584        return False
1585
1586    ## __GetRegionLayout() method
1587    #
1588    #   Get region layout for FD
1589    #
1590    #   @param  self        The object pointer
1591    #   @param  Fd          for whom region is got
1592    #   @retval True        Successfully find
1593    #   @retval False       Not able to find
1594    #
1595    def __GetRegionLayout(self, Fd):
1596        if not self.__GetNextHexNumber():
1597            return False
1598
1599        RegionObj = CommonDataClass.FdfClass.RegionClassObject()
1600        RegionObj.Offset = long(self.__Token, 0)
1601        Fd.RegionList.append(RegionObj)
1602
1603        if not self.__IsToken( "|"):
1604            raise Warning("expected '|' At Line ", self.FileName, self.CurrentLineNumber)
1605
1606        if not self.__GetNextHexNumber():
1607            raise Warning("expected Region Size At Line ", self.FileName, self.CurrentLineNumber)
1608        RegionObj.Size = long(self.__Token, 0)
1609
1610        if not self.__GetNextWord():
1611            return True
1612
1613        if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):
1614            self.__UndoToken()
1615            RegionObj.PcdOffset = self.__GetNextPcdName()
1616            self.Profile.PcdDict[RegionObj.PcdOffset] = RegionObj.Offset + long(Fd.BaseAddress, 0)
1617            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1618            self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
1619            if self.__IsToken( "|"):
1620                RegionObj.PcdSize = self.__GetNextPcdName()
1621                self.Profile.PcdDict[RegionObj.PcdSize] = RegionObj.Size
1622                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1623                self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
1624
1625            if not self.__GetNextWord():
1626                return True
1627
1628        if self.__Token == "SET":
1629            self.__UndoToken()
1630            self.__GetSetStatements( RegionObj)
1631            if not self.__GetNextWord():
1632                return True
1633
1634        elif self.__Token == "FV":
1635            self.__UndoToken()
1636            self.__GetRegionFvType( RegionObj)
1637
1638        elif self.__Token == "CAPSULE":
1639            self.__UndoToken()
1640            self.__GetRegionCapType( RegionObj)
1641
1642        elif self.__Token == "FILE":
1643            self.__UndoToken()
1644            self.__GetRegionFileType( RegionObj)
1645
1646        else:
1647            self.__UndoToken()
1648            self.__GetRegionDataType( RegionObj)
1649
1650        return True
1651
1652    ## __GetRegionFvType() method
1653    #
1654    #   Get region fv data for region
1655    #
1656    #   @param  self        The object pointer
1657    #   @param  RegionObj   for whom region data is got
1658    #
1659    def __GetRegionFvType(self, RegionObj):
1660
1661        if not self.__IsKeyword( "FV"):
1662            raise Warning("expected Keyword 'FV' At Line ", self.FileName, self.CurrentLineNumber)
1663
1664        if not self.__IsToken( "="):
1665            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1666
1667        if not self.__GetNextToken():
1668            raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
1669
1670        RegionObj.RegionType = "FV"
1671        RegionObj.RegionDataList.append(self.__Token)
1672
1673        while self.__IsKeyword( "FV"):
1674
1675            if not self.__IsToken( "="):
1676                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1677
1678            if not self.__GetNextToken():
1679                raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
1680
1681            RegionObj.RegionDataList.append(self.__Token)
1682
1683    ## __GetRegionCapType() method
1684    #
1685    #   Get region capsule data for region
1686    #
1687    #   @param  self        The object pointer
1688    #   @param  RegionObj   for whom region data is got
1689    #
1690    def __GetRegionCapType(self, RegionObj):
1691
1692        if not self.__IsKeyword("CAPSULE"):
1693            raise Warning("expected Keyword 'CAPSULE' at line", self.FileName, self.CurrentLineNumber)
1694
1695        if not self.__IsToken("="):
1696            raise Warning("expected '=' at line", self.FileName, self.CurrentLineNumber)
1697
1698        if not self.__GetNextToken():
1699            raise Warning("expected CAPSULE name at line", self.FileName, self.CurrentLineNumber)
1700
1701        RegionObj.RegionType = "CAPSULE"
1702        RegionObj.RegionDataList.append(self.__Token)
1703
1704        while self.__IsKeyword("CAPSULE"):
1705
1706            if not self.__IsToken("="):
1707                raise Warning("expected '=' at line", self.FileName, self.CurrentLineNumber)
1708
1709            if not self.__GetNextToken():
1710                raise Warning("expected CAPSULE name at line", self.FileName, self.CurrentLineNumber)
1711
1712            RegionObj.RegionDataList.append(self.__Token)
1713
1714    ## __GetRegionFileType() method
1715    #
1716    #   Get region file data for region
1717    #
1718    #   @param  self        The object pointer
1719    #   @param  RegionObj   for whom region data is got
1720    #
1721    def __GetRegionFileType(self, RegionObj):
1722
1723        if not self.__IsKeyword( "FILE"):
1724            raise Warning("expected Keyword 'FILE' At Line ", self.FileName, self.CurrentLineNumber)
1725
1726        if not self.__IsToken( "="):
1727            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1728
1729        if not self.__GetNextToken():
1730            raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber)
1731
1732        RegionObj.RegionType = "FILE"
1733        RegionObj.RegionDataList.append( self.__Token)
1734
1735        while self.__IsKeyword( "FILE"):
1736
1737            if not self.__IsToken( "="):
1738                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1739
1740            if not self.__GetNextToken():
1741                raise Warning("expected FILE name At Line ", self.FileName, self.CurrentLineNumber)
1742
1743            RegionObj.RegionDataList.append(self.__Token)
1744
1745    ## __GetRegionDataType() method
1746    #
1747    #   Get region array data for region
1748    #
1749    #   @param  self        The object pointer
1750    #   @param  RegionObj   for whom region data is got
1751    #
1752    def __GetRegionDataType(self, RegionObj):
1753
1754        if not self.__IsKeyword( "DATA"):
1755            raise Warning("expected Region Data type At Line ", self.FileName, self.CurrentLineNumber)
1756
1757        if not self.__IsToken( "="):
1758            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1759
1760        if not self.__IsToken( "{"):
1761            raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
1762
1763        if not self.__GetNextHexNumber():
1764            raise Warning("expected Hex byte At Line ", self.FileName, self.CurrentLineNumber)
1765
1766        if len(self.__Token) > 18:
1767            raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
1768
1769        DataString = self.__Token
1770        DataString += ","
1771
1772        while self.__IsToken(","):
1773            if not self.__GetNextHexNumber():
1774                raise Warning("Invalid Hex number At Line ", self.FileName, self.CurrentLineNumber)
1775            if len(self.__Token) > 4:
1776                raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber)
1777            DataString += self.__Token
1778            DataString += ","
1779
1780        if not self.__IsToken( "}"):
1781            raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
1782
1783        DataString = DataString.rstrip(",")
1784        RegionObj.RegionType = "DATA"
1785        RegionObj.RegionDataList.append( DataString)
1786
1787        while self.__IsKeyword( "DATA"):
1788
1789            if not self.__IsToken( "="):
1790                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1791
1792            if not self.__IsToken( "{"):
1793                raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
1794
1795            if not self.__GetNextHexNumber():
1796                raise Warning("expected Hex byte At Line ", self.FileName, self.CurrentLineNumber)
1797
1798            if len(self.__Token) > 18:
1799                raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
1800
1801            DataString = self.__Token
1802            DataString += ","
1803
1804            while self.__IsToken(","):
1805                self.__GetNextHexNumber()
1806                if len(self.__Token) > 4:
1807                    raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber)
1808                DataString += self.__Token
1809                DataString += ","
1810
1811            if not self.__IsToken( "}"):
1812                raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
1813
1814            DataString = DataString.rstrip(",")
1815            RegionObj.RegionDataList.append( DataString)
1816
1817    ## __GetFv() method
1818    #
1819    #   Get FV section contents and store its data into FV dictionary of self.Profile
1820    #
1821    #   @param  self        The object pointer
1822    #   @retval True        Successfully find a FV
1823    #   @retval False       Not able to find a FV
1824    #
1825    def __GetFv(self):
1826        if not self.__GetNextToken():
1827            return False
1828
1829        S = self.__Token.upper()
1830        if S.startswith("[") and not S.startswith("[FV."):
1831            if not S.startswith("[CAPSULE.") \
1832                and not S.startswith("[VTF.") and not S.startswith("[RULE."):
1833                raise Warning("Unknown section or section appear sequence error \n(The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.]) At Line ", self.FileName, self.CurrentLineNumber)
1834            self.__UndoToken()
1835            return False
1836
1837        self.__UndoToken()
1838        if not self.__IsToken("[FV.", True):
1839            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1840            print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1841                    % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1842            raise Warning("Unknown Keyword At Line ", self.FileName, self.CurrentLineNumber)
1843
1844        FvName = self.__GetUiName()
1845        self.CurrentFvName = FvName.upper()
1846
1847        if not self.__IsToken( "]"):
1848            raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
1849
1850        FvObj = CommonDataClass.FdfClass.FvClassObject()
1851        FvObj.UiFvName = self.CurrentFvName
1852        self.Profile.FvDict[self.CurrentFvName] = FvObj
1853
1854        Status = self.__GetCreateFile(FvObj)
1855        if not Status:
1856            raise Warning("FV name error At Line ", self.FileName, self.CurrentLineNumber)
1857
1858        self.__GetDefineStatements(FvObj)
1859
1860        self.__GetAddressStatements(FvObj)
1861
1862        self.__GetBlockStatement(FvObj)
1863
1864        self.__GetSetStatements(FvObj)
1865
1866        self.__GetFvAlignment(FvObj)
1867
1868        self.__GetFvAttributes(FvObj)
1869
1870        self.__GetFvNameGuid(FvObj)
1871
1872        self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
1873        self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
1874
1875        while True:
1876            isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
1877            isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
1878            if not isInf and not isFile:
1879                break
1880
1881        return True
1882
1883    ## __GetFvAlignment() method
1884    #
1885    #   Get alignment for FV
1886    #
1887    #   @param  self        The object pointer
1888    #   @param  Obj         for whom alignment is got
1889    #   @retval True        Successfully find a alignment statement
1890    #   @retval False       Not able to find a alignment statement
1891    #
1892    def __GetFvAlignment(self, Obj):
1893
1894        if not self.__IsKeyword( "FvAlignment"):
1895            return False
1896
1897        if not self.__IsToken( "="):
1898            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1899
1900        if not self.__GetNextToken():
1901            raise Warning("expected alignment value At Line ", self.FileName, self.CurrentLineNumber)
1902
1903        if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
1904                                        "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
1905                                        "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
1906                                        "1G", "2G"):
1907            raise Warning("Unknown alignment value At Line ", self.FileName, self.CurrentLineNumber)
1908        Obj.FvAlignment = self.__Token
1909        return True
1910
1911    ## __GetFvAttributes() method
1912    #
1913    #   Get attributes for FV
1914    #
1915    #   @param  self        The object pointer
1916    #   @param  Obj         for whom attribute is got
1917    #   @retval None
1918    #
1919    def __GetFvAttributes(self, FvObj):
1920
1921        while self.__GetNextWord():
1922            name = self.__Token
1923            if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
1924                           "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
1925                           "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
1926                           "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
1927                           "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
1928                           "WRITE_POLICY_RELIABLE"):
1929                self.__UndoToken()
1930                return
1931
1932            if not self.__IsToken( "="):
1933                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
1934
1935            if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
1936                raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)
1937
1938            FvObj.FvAttributeDict[name] = self.__Token
1939
1940        return
1941
1942    ## __GetFvNameGuid() method
1943    #
1944    #   Get FV GUID for FV
1945    #
1946    #   @param  self        The object pointer
1947    #   @param  Obj         for whom GUID is got
1948    #   @retval None
1949    #
1950    def __GetFvNameGuid(self, FvObj):
1951
1952        if not self.__IsKeyword( "FvNameGuid"):
1953            return
1954
1955        if not self.__IsToken( "="):
1956            raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1957
1958        if not self.__GetNextGuid():
1959            raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)
1960
1961        FvObj.FvNameGuid = self.__Token
1962
1963        return
1964
1965    ## __GetAprioriSection() method
1966    #
1967    #   Get token statements
1968    #
1969    #   @param  self        The object pointer
1970    #   @param  FvObj       for whom apriori is got
1971    #   @param  MacroDict   dictionary used to replace macro
1972    #   @retval True        Successfully find apriori statement
1973    #   @retval False       Not able to find apriori statement
1974    #
1975    def __GetAprioriSection(self, FvObj, MacroDict = {}):
1976
1977        if not self.__IsKeyword( "APRIORI"):
1978            return False
1979
1980        if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):
1981            raise Warning("expected Apriori file type At Line ", self.FileName, self.CurrentLineNumber)
1982        AprType = self.__Token
1983
1984        if not self.__IsToken( "{"):
1985            raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
1986
1987        AprSectionObj = CommonDataClass.FdfClass.AprioriSectionClassObject()
1988        AprSectionObj.AprioriType = AprType
1989
1990        self.__GetDefineStatements(AprSectionObj)
1991        MacroDict.update(AprSectionObj.DefineVarDict)
1992
1993        while True:
1994            IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)
1995            IsFile = self.__GetFileStatement( AprSectionObj)
1996            if not IsInf and not IsFile:
1997                break
1998
1999        if not self.__IsToken( "}"):
2000            raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2001
2002        FvObj.AprioriSectionList.append(AprSectionObj)
2003        return True
2004
2005    ## __GetInfStatement() method
2006    #
2007    #   Get INF statements
2008    #
2009    #   @param  self        The object pointer
2010    #   @param  Obj         for whom inf statement is got
2011    #   @param  MacroDict   dictionary used to replace macro
2012    #   @retval True        Successfully find inf statement
2013    #   @retval False       Not able to find inf statement
2014    #
2015    def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2016
2017        if not self.__IsKeyword( "INF"):
2018            return False
2019
2020        ffsInf = CommonDataClass.FdfClass.FfsInfStatementClassObject()
2021        self.__GetInfOptions( ffsInf)
2022
2023        if not self.__GetNextToken():
2024            raise Warning("expected INF file path At Line ", self.FileName, self.CurrentLineNumber)
2025        ffsInf.InfFileName = self.__Token
2026
2027#        if ffsInf.InfFileName.find('$') >= 0:
2028#            ffsInf.InfFileName = GenFdsGlobalVariable.GenFdsGlobalVariable.MacroExtend(ffsInf.InfFileName, MacroDict)
2029
2030        if not ffsInf.InfFileName in self.Profile.InfList:
2031            self.Profile.InfList.append(ffsInf.InfFileName)
2032            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2033            self.Profile.InfFileLineList.append(FileLineTuple)
2034
2035        if self.__IsToken('|'):
2036            if self.__IsKeyword('RELOCS_STRIPPED'):
2037                ffsInf.KeepReloc = False
2038            elif self.__IsKeyword('RELOCS_RETAINED'):
2039                ffsInf.KeepReloc = True
2040            else:
2041                raise Warning("Unknown reloc strip flag At Line ", self.FileName, self.CurrentLineNumber)
2042
2043        if ForCapsule:
2044            capsuleFfs = CapsuleData.CapsuleFfs()
2045            capsuleFfs.Ffs = ffsInf
2046            Obj.CapsuleDataList.append(capsuleFfs)
2047        else:
2048            Obj.FfsList.append(ffsInf)
2049        return True
2050
2051    ## __GetInfOptions() method
2052    #
2053    #   Get options for INF
2054    #
2055    #   @param  self        The object pointer
2056    #   @param  FfsInfObj   for whom option is got
2057    #
2058    def __GetInfOptions(self, FfsInfObj):
2059
2060        if self.__IsKeyword( "RuleOverride"):
2061            if not self.__IsToken( "="):
2062                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2063            if not self.__GetNextToken():
2064                raise Warning("expected Rule name At Line ", self.FileName, self.CurrentLineNumber)
2065            FfsInfObj.Rule = self.__Token
2066
2067        if self.__IsKeyword( "VERSION"):
2068            if not self.__IsToken( "="):
2069                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2070            if not self.__GetNextToken():
2071                raise Warning("expected Version At Line ", self.FileName, self.CurrentLineNumber)
2072
2073            if self.__GetStringData():
2074                FfsInfObj.Version = self.__Token
2075
2076        if self.__IsKeyword( "UI"):
2077            if not self.__IsToken( "="):
2078                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2079            if not self.__GetNextToken():
2080                raise Warning("expected UI name At Line ", self.FileName, self.CurrentLineNumber)
2081
2082            if self.__GetStringData():
2083                FfsInfObj.Ui = self.__Token
2084
2085        if self.__IsKeyword( "USE"):
2086            if not self.__IsToken( "="):
2087                raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2088            if not self.__GetNextToken():
2089                raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)
2090            FfsInfObj.UseArch = self.__Token
2091
2092
2093        if self.__GetNextToken():
2094            p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2095            if p.match(self.__Token):
2096                FfsInfObj.KeyStringList.append(self.__Token)
2097                if not self.__IsToken(","):
2098                    return
2099            else:
2100                self.__UndoToken()
2101                return
2102
2103            while self.__GetNextToken():
2104                if not p.match(self.__Token):
2105                    raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)
2106                FfsInfObj.KeyStringList.append(self.__Token)
2107
2108                if not self.__IsToken(","):
2109                    break
2110
2111    ## __GetFileStatement() method
2112    #
2113    #   Get FILE statements
2114    #
2115    #   @param  self        The object pointer
2116    #   @param  Obj         for whom FILE statement is got
2117    #   @param  MacroDict   dictionary used to replace macro
2118    #   @retval True        Successfully find FILE statement
2119    #   @retval False       Not able to find FILE statement
2120    #
2121    def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2122
2123        if not self.__IsKeyword( "FILE"):
2124            return False
2125
2126        FfsFileObj = CommonDataClass.FdfClass.FileStatementClassObject()
2127
2128        if not self.__GetNextWord():
2129            raise Warning("expected FFS type At Line ", self.FileName, self.CurrentLineNumber)
2130        FfsFileObj.FvFileType = self.__Token
2131
2132        if not self.__IsToken( "="):
2133            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2134
2135        if not self.__GetNextGuid():
2136            if not self.__GetNextWord():
2137                raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
2138            if self.__Token == 'PCD':
2139                if not self.__IsToken( "("):
2140                    raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2141                PcdPair = self.__GetNextPcdName()
2142                if not self.__IsToken( ")"):
2143                    raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2144                self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2145
2146        FfsFileObj.NameGuid = self.__Token
2147
2148        self.__GetFilePart( FfsFileObj, MacroDict.copy())
2149
2150        if ForCapsule:
2151            capsuleFfs = CapsuleData.CapsuleFfs()
2152            capsuleFfs.Ffs = FfsFileObj
2153            Obj.CapsuleDataList.append(capsuleFfs)
2154        else:
2155            Obj.FfsList.append(FfsFileObj)
2156
2157        return True
2158
2159    ## __FileCouldHaveRelocFlag() method
2160    #
2161    #   Check whether reloc strip flag can be set for a file type.
2162    #
2163    #   @param  self        The object pointer
2164    #   @param  FileType    The file type to check with
2165    #   @retval True        This type could have relocation strip flag
2166    #   @retval False       No way to have it
2167    #
2168
2169    def __FileCouldHaveRelocFlag (self, FileType):
2170        if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2171            return True
2172        else:
2173            return False
2174
2175    ## __SectionCouldHaveRelocFlag() method
2176    #
2177    #   Check whether reloc strip flag can be set for a section type.
2178    #
2179    #   @param  self        The object pointer
2180    #   @param  SectionType The section type to check with
2181    #   @retval True        This type could have relocation strip flag
2182    #   @retval False       No way to have it
2183    #
2184
2185    def __SectionCouldHaveRelocFlag (self, SectionType):
2186        if SectionType in ('TE', 'PE32'):
2187            return True
2188        else:
2189            return False
2190
2191    ## __GetFilePart() method
2192    #
2193    #   Get components for FILE statement
2194    #
2195    #   @param  self        The object pointer
2196    #   @param  FfsFileObj   for whom component is got
2197    #   @param  MacroDict   dictionary used to replace macro
2198    #
2199    def __GetFilePart(self, FfsFileObj, MacroDict = {}):
2200
2201        self.__GetFileOpts( FfsFileObj)
2202
2203        if not self.__IsToken("{"):
2204#            if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2205#                if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
2206#                    if self.__Token == 'RELOCS_STRIPPED':
2207#                        FfsFileObj.KeepReloc = False
2208#                    else:
2209#                        FfsFileObj.KeepReloc = True
2210#                else:
2211#                    raise Warning("File type %s could not have reloc strip flag At Line %d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2212#
2213#            if not self.__IsToken("{"):
2214            raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2215
2216        if not self.__GetNextToken():
2217            raise Warning("expected File name or section data At Line ", self.FileName, self.CurrentLineNumber)
2218
2219        if self.__Token == "FV":
2220            if not self.__IsToken( "="):
2221                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2222            if not self.__GetNextToken():
2223                raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
2224            FfsFileObj.FvName = self.__Token
2225
2226        elif self.__Token == "FD":
2227            if not self.__IsToken( "="):
2228                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2229            if not self.__GetNextToken():
2230                raise Warning("expected FD name At Line ", self.FileName, self.CurrentLineNumber)
2231            FfsFileObj.FdName = self.__Token
2232
2233        elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):
2234            self.__UndoToken()
2235            self.__GetSectionData( FfsFileObj, MacroDict)
2236        else:
2237            FfsFileObj.FileName = self.__Token
2238
2239        if not self.__IsToken( "}"):
2240            raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2241
2242    ## __GetFileOpts() method
2243    #
2244    #   Get options for FILE statement
2245    #
2246    #   @param  self        The object pointer
2247    #   @param  FfsFileObj   for whom options is got
2248    #
2249    def __GetFileOpts(self, FfsFileObj):
2250
2251        if self.__GetNextToken():
2252            Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2253            if Pattern.match(self.__Token):
2254                FfsFileObj.KeyStringList.append(self.__Token)
2255                if self.__IsToken(","):
2256                    while self.__GetNextToken():
2257                        if not Pattern.match(self.__Token):
2258                            raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)
2259                        FfsFileObj.KeyStringList.append(self.__Token)
2260
2261                        if not self.__IsToken(","):
2262                            break
2263
2264            else:
2265                self.__UndoToken()
2266
2267        if self.__IsKeyword( "FIXED", True):
2268            FfsFileObj.Fixed = True
2269
2270        if self.__IsKeyword( "CHECKSUM", True):
2271            FfsFileObj.CheckSum = True
2272
2273        if self.__GetAlignment():
2274            FfsFileObj.Alignment = self.__Token
2275
2276
2277
2278    ## __GetAlignment() method
2279    #
2280    #   Return the alignment value
2281    #
2282    #   @param  self        The object pointer
2283    #   @retval True        Successfully find alignment
2284    #   @retval False       Not able to find alignment
2285    #
2286    def __GetAlignment(self):
2287        if self.__IsKeyword( "Align", True):
2288            if not self.__IsToken( "="):
2289                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2290
2291            if not self.__GetNextToken():
2292                raise Warning("expected alignment value At Line ", self.FileName, self.CurrentLineNumber)
2293            return True
2294
2295        return False
2296
2297    ## __GetFilePart() method
2298    #
2299    #   Get section data for FILE statement
2300    #
2301    #   @param  self        The object pointer
2302    #   @param  FfsFileObj   for whom section is got
2303    #   @param  MacroDict   dictionary used to replace macro
2304    #
2305    def __GetSectionData(self, FfsFileObj, MacroDict = {}):
2306        Dict = {}
2307        Dict.update(MacroDict)
2308
2309        self.__GetDefineStatements(FfsFileObj)
2310
2311        Dict.update(FfsFileObj.DefineVarDict)
2312        self.__GetAprioriSection(FfsFileObj, Dict.copy())
2313        self.__GetAprioriSection(FfsFileObj, Dict.copy())
2314
2315        while True:
2316            IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)
2317            IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)
2318            if not IsLeafSection and not IsEncapSection:
2319                break
2320
2321    ## __GetLeafSection() method
2322    #
2323    #   Get leaf section for Obj
2324    #
2325    #   @param  self        The object pointer
2326    #   @param  Obj         for whom leaf section is got
2327    #   @param  MacroDict   dictionary used to replace macro
2328    #   @retval True        Successfully find section statement
2329    #   @retval False       Not able to find section statement
2330    #
2331    def __GetLeafSection(self, Obj, MacroDict = {}):
2332
2333        OldPos = self.GetFileBufferPos()
2334
2335        if not self.__IsKeyword( "SECTION"):
2336            if len(Obj.SectionList) == 0:
2337                raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber)
2338            else:
2339                return False
2340
2341        AlignValue = None
2342        if self.__GetAlignment():
2343            if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2344                raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2345            AlignValue = self.__Token
2346
2347        BuildNum = None
2348        if self.__IsKeyword( "BUILD_NUM"):
2349            if not self.__IsToken( "="):
2350                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2351
2352            if not self.__GetNextToken():
2353                raise Warning("expected Build number value At Line ", self.FileName, self.CurrentLineNumber)
2354
2355            BuildNum = self.__Token
2356
2357        if self.__IsKeyword( "VERSION"):
2358            if AlignValue == 'Auto':
2359                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2360            if not self.__IsToken( "="):
2361                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2362            if not self.__GetNextToken():
2363                raise Warning("expected version At Line ", self.FileName, self.CurrentLineNumber)
2364            VerSectionObj = CommonDataClass.FdfClass.VerSectionClassObject()
2365            VerSectionObj.Alignment = AlignValue
2366            VerSectionObj.BuildNum = BuildNum
2367            if self.__GetStringData():
2368                VerSectionObj.StringData = self.__Token
2369            else:
2370                VerSectionObj.FileName = self.__Token
2371            Obj.SectionList.append(VerSectionObj)
2372
2373        elif self.__IsKeyword( "UI"):
2374            if AlignValue == 'Auto':
2375                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2376            if not self.__IsToken( "="):
2377                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2378            if not self.__GetNextToken():
2379                raise Warning("expected UI At Line ", self.FileName, self.CurrentLineNumber)
2380            UiSectionObj = CommonDataClass.FdfClass.UiSectionClassObject()
2381            UiSectionObj.Alignment = AlignValue
2382            if self.__GetStringData():
2383                UiSectionObj.StringData = self.__Token
2384            else:
2385                UiSectionObj.FileName = self.__Token
2386            Obj.SectionList.append(UiSectionObj)
2387
2388        elif self.__IsKeyword( "FV_IMAGE"):
2389            if AlignValue == 'Auto':
2390                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2391            if not self.__IsToken( "="):
2392                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2393            if not self.__GetNextWord():
2394                raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
2395
2396            FvName = self.__Token.upper()
2397            FvObj = None
2398
2399            if self.__IsToken( "{"):
2400                FvObj = Fv.FV()
2401                FvObj.UiFvName = FvName
2402                self.__GetDefineStatements(FvObj)
2403                MacroDict.update(FvObj.DefineVarDict)
2404                self.__GetBlockStatement(FvObj)
2405                self.__GetSetStatements(FvObj)
2406                self.__GetFvAlignment(FvObj)
2407                self.__GetFvAttributes(FvObj)
2408                self.__GetAprioriSection(FvObj, MacroDict.copy())
2409                self.__GetAprioriSection(FvObj, MacroDict.copy())
2410
2411                while True:
2412                    IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
2413                    IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
2414                    if not IsInf and not IsFile:
2415                        break
2416
2417                if not self.__IsToken( "}"):
2418                    raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2419
2420            FvImageSectionObj = CommonDataClass.FdfClass.FvImageSectionClassObject()
2421            FvImageSectionObj.Alignment = AlignValue
2422            if FvObj != None:
2423                FvImageSectionObj.Fv = FvObj
2424                FvImageSectionObj.FvName = None
2425            else:
2426                FvImageSectionObj.FvName = FvName
2427
2428            Obj.SectionList.append(FvImageSectionObj)
2429
2430        elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
2431            if AlignValue == 'Auto':
2432                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2433            DepexSectionObj = CommonDataClass.FdfClass.DepexSectionClassObject()
2434            DepexSectionObj.Alignment = AlignValue
2435            DepexSectionObj.DepexType = self.__Token
2436
2437            if not self.__IsToken( "="):
2438                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2439            if not self.__IsToken( "{"):
2440                raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2441            if not self.__SkipToToken( "}"):
2442                raise Warning("expected Depex expression ending '}' At Line ", self.FileName, self.CurrentLineNumber)
2443
2444            DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
2445            Obj.SectionList.append(DepexSectionObj)
2446
2447        else:
2448
2449            if not self.__GetNextWord():
2450                raise Warning("expected section type At Line ", self.FileName, self.CurrentLineNumber)
2451
2452            # Encapsulation section appear, UndoToken and return
2453            if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
2454                self.SetFileBufferPos(OldPos)
2455                return False
2456
2457            if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2458                               "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2459                raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2460            if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
2461                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2462            # DataSection
2463            DataSectionObj = CommonDataClass.FdfClass.DataSectionClassObject()
2464            DataSectionObj.Alignment = AlignValue
2465            DataSectionObj.SecType = self.__Token
2466
2467            if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2468                if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
2469                    if self.__Token == 'RELOCS_STRIPPED':
2470                        DataSectionObj.KeepReloc = False
2471                    else:
2472                        DataSectionObj.KeepReloc = True
2473                else:
2474                    raise Warning("File type %s, section type %s, could not have reloc strip flag At Line %d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2475
2476            if self.__IsToken("="):
2477                if not self.__GetNextToken():
2478                    raise Warning("expected section file path At Line ", self.FileName, self.CurrentLineNumber)
2479                DataSectionObj.SectFileName = self.__Token
2480            else:
2481                if not self.__GetCglSection(DataSectionObj):
2482                    return False
2483
2484            Obj.SectionList.append(DataSectionObj)
2485
2486        return True
2487
2488    ## __GetCglSection() method
2489    #
2490    #   Get compressed or GUIDed section for Obj
2491    #
2492    #   @param  self        The object pointer
2493    #   @param  Obj         for whom leaf section is got
2494    #   @param  AlignValue  alignment value for complex section
2495    #   @retval True        Successfully find section statement
2496    #   @retval False       Not able to find section statement
2497    #
2498    def __GetCglSection(self, Obj, AlignValue = None):
2499
2500        if self.__IsKeyword( "COMPRESS"):
2501            type = "PI_STD"
2502            if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
2503                type = self.__Token
2504
2505            if not self.__IsToken("{"):
2506                raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2507
2508            CompressSectionObj = CommonDataClass.FdfClass.CompressSectionClassObject()
2509            CompressSectionObj.Alignment = AlignValue
2510            CompressSectionObj.CompType = type
2511            # Recursive sections...
2512            while True:
2513                IsLeafSection = self.__GetLeafSection(CompressSectionObj)
2514                IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
2515                if not IsLeafSection and not IsEncapSection:
2516                    break
2517
2518
2519            if not self.__IsToken( "}"):
2520                raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2521            Obj.SectionList.append(CompressSectionObj)
2522
2523#            else:
2524#               raise Warning("Compress type not known At Line ")
2525
2526            return True
2527
2528        elif self.__IsKeyword( "GUIDED"):
2529            GuidValue = None
2530            if self.__GetNextGuid():
2531                GuidValue = self.__Token
2532
2533            AttribDict = self.__GetGuidAttrib()
2534            if not self.__IsToken("{"):
2535                raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2536            GuidSectionObj = CommonDataClass.FdfClass.GuidSectionClassObject()
2537            GuidSectionObj.Alignment = AlignValue
2538            GuidSectionObj.NameGuid = GuidValue
2539            GuidSectionObj.SectionType = "GUIDED"
2540            GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
2541            GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
2542            # Recursive sections...
2543            while True:
2544                IsLeafSection = self.__GetLeafSection(GuidSectionObj)
2545                IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
2546                if not IsLeafSection and not IsEncapSection:
2547                    break
2548
2549            if not self.__IsToken( "}"):
2550                raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2551            Obj.SectionList.append(GuidSectionObj)
2552
2553            return True
2554
2555        return False
2556
2557    ## __GetGuidAttri() method
2558    #
2559    #   Get attributes for GUID section
2560    #
2561    #   @param  self        The object pointer
2562    #   @retval AttribDict  Dictionary of key-value pair of section attributes
2563    #
2564    def __GetGuidAttrib(self):
2565
2566        AttribDict = {}
2567        AttribDict["PROCESSING_REQUIRED"] = False
2568        AttribDict["AUTH_STATUS_VALID"] = False
2569        if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
2570            AttribKey = self.__Token
2571
2572            if not self.__IsToken("="):
2573                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2574
2575            if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2576                raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)
2577            AttribDict[AttribKey] = self.__Token
2578
2579        if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
2580            AttribKey = self.__Token
2581
2582            if not self.__IsToken("="):
2583                raise Warning("expected '=' At Line ")
2584
2585            if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2586                raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)
2587            AttribDict[AttribKey] = self.__Token
2588
2589        return AttribDict
2590
2591    ## __GetEncapsulationSec() method
2592    #
2593    #   Get encapsulation section for FILE
2594    #
2595    #   @param  self        The object pointer
2596    #   @param  FfsFile     for whom section is got
2597    #   @retval True        Successfully find section statement
2598    #   @retval False       Not able to find section statement
2599    #
2600    def __GetEncapsulationSec(self, FfsFileObj):
2601
2602        OldPos = self.GetFileBufferPos()
2603        if not self.__IsKeyword( "SECTION"):
2604            if len(FfsFileObj.SectionList) == 0:
2605                raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber)
2606            else:
2607                return False
2608
2609        AlignValue = None
2610        if self.__GetAlignment():
2611            if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2612                raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2613            AlignValue = self.__Token
2614
2615        if not self.__GetCglSection(FfsFileObj, AlignValue):
2616            self.SetFileBufferPos(OldPos)
2617            return False
2618        else:
2619            return True
2620
2621    ## __GetCapsule() method
2622    #
2623    #   Get capsule section contents and store its data into capsule list of self.Profile
2624    #
2625    #   @param  self        The object pointer
2626    #   @retval True        Successfully find a capsule
2627    #   @retval False       Not able to find a capsule
2628    #
2629    def __GetCapsule(self):
2630
2631        if not self.__GetNextToken():
2632            return False
2633
2634        S = self.__Token.upper()
2635        if S.startswith("[") and not S.startswith("[CAPSULE."):
2636            if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
2637                raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
2638            self.__UndoToken()
2639            return False
2640
2641        self.__UndoToken()
2642        if not self.__IsToken("[CAPSULE.", True):
2643            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2644            print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2645                    % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2646            raise Warning("expected [Capsule.] At Line ", self.FileName, self.CurrentLineNumber)
2647
2648        CapsuleObj = CommonDataClass.FdfClass.CapsuleClassObject()
2649
2650        CapsuleName = self.__GetUiName()
2651        if not CapsuleName:
2652            raise Warning("expected capsule name At line ", self.FileName, self.CurrentLineNumber)
2653
2654        CapsuleObj.UiCapsuleName = CapsuleName.upper()
2655
2656        if not self.__IsToken( "]"):
2657            raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
2658
2659        if self.__IsKeyword("CREATE_FILE"):
2660            if not self.__IsToken( "="):
2661                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2662
2663            if not self.__GetNextToken():
2664                raise Warning("expected file name At Line ", self.FileName, self.CurrentLineNumber)
2665
2666            CapsuleObj.CreateFile = self.__Token
2667
2668        self.__GetCapsuleStatements(CapsuleObj)
2669        self.Profile.CapsuleList.append(CapsuleObj)
2670        return True
2671
2672    ## __GetCapsuleStatements() method
2673    #
2674    #   Get statements for capsule
2675    #
2676    #   @param  self        The object pointer
2677    #   @param  Obj         for whom statements are got
2678    #
2679    def __GetCapsuleStatements(self, Obj):
2680        self.__GetCapsuleTokens(Obj)
2681        self.__GetDefineStatements(Obj)
2682        self.__GetSetStatements(Obj)
2683
2684        self.__GetCapsuleData(Obj)
2685
2686    ## __GetCapsuleStatements() method
2687    #
2688    #   Get token statements for capsule
2689    #
2690    #   @param  self        The object pointer
2691    #   @param  Obj         for whom token statements are got
2692    #
2693    def __GetCapsuleTokens(self, Obj):
2694
2695        if not self.__IsKeyword("CAPSULE_GUID"):
2696            raise Warning("expected 'CAPSULE_GUID' At Line ", self.FileName, self.CurrentLineNumber)
2697
2698        while self.__CurrentLine().find("=") != -1:
2699            NameValue = self.__CurrentLine().split("=")
2700            Obj.TokensDict[NameValue[0].strip()] = NameValue[1].strip()
2701            self.CurrentLineNumber += 1
2702            self.CurrentOffsetWithinLine = 0
2703
2704    ## __GetCapsuleData() method
2705    #
2706    #   Get capsule data for capsule
2707    #
2708    #   @param  self        The object pointer
2709    #   @param  Obj         for whom capsule data are got
2710    #
2711    def __GetCapsuleData(self, Obj):
2712
2713        while True:
2714            IsInf = self.__GetInfStatement(Obj, True)
2715            IsFile = self.__GetFileStatement(Obj, True)
2716            IsFv = self.__GetFvStatement(Obj)
2717            if not IsInf and not IsFile and not IsFv:
2718                break
2719
2720    ## __GetFvStatement() method
2721    #
2722    #   Get FV for capsule
2723    #
2724    #   @param  self        The object pointer
2725    #   @param  CapsuleObj  for whom FV is got
2726    #   @retval True        Successfully find a FV statement
2727    #   @retval False       Not able to find a FV statement
2728    #
2729    def __GetFvStatement(self, CapsuleObj):
2730
2731        if not self.__IsKeyword("FV"):
2732            return False
2733
2734        if not self.__IsToken("="):
2735            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2736
2737        if not self.__GetNextToken():
2738            raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
2739
2740#        CapsuleFv = CapsuleData.CapsuleFv()
2741#        CapsuleFv.FvName = self.__Token
2742#        CapsuleObj.CapsuleDataList.append(CapsuleFv)
2743        return True
2744
2745    ## __GetRule() method
2746    #
2747    #   Get Rule section contents and store its data into rule list of self.Profile
2748    #
2749    #   @param  self        The object pointer
2750    #   @retval True        Successfully find a Rule
2751    #   @retval False       Not able to find a Rule
2752    #
2753    def __GetRule(self):
2754
2755        if not self.__GetNextToken():
2756            return False
2757
2758        S = self.__Token.upper()
2759        if S.startswith("[") and not S.startswith("[RULE."):
2760            if not S.startswith("[OPTIONROM."):
2761                raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
2762            self.__UndoToken()
2763            return False
2764        self.__UndoToken()
2765        if not self.__IsToken("[Rule.", True):
2766            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2767            print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2768                    % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2769            raise Warning("expected [Rule.] At Line ", self.FileName, self.CurrentLineNumber)
2770
2771        if not self.__SkipToToken("."):
2772            raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
2773
2774        Arch = self.__SkippedChars.rstrip(".")
2775        if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
2776            raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
2777
2778        ModuleType = self.__GetModuleType()
2779
2780        TemplateName = ""
2781        if self.__IsToken("."):
2782            if not self.__GetNextWord():
2783                raise Warning("expected template name At Line ", self.FileName, self.CurrentLineNumber)
2784            TemplateName = self.__Token
2785
2786        if not self.__IsToken( "]"):
2787            raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
2788
2789        RuleObj = self.__GetRuleFileStatements()
2790        RuleObj.Arch = Arch.upper()
2791        RuleObj.ModuleType = ModuleType
2792        RuleObj.TemplateName = TemplateName
2793        if TemplateName == '' :
2794            self.Profile.RuleDict['RULE'             + \
2795                              '.'                    + \
2796                              Arch.upper()           + \
2797                              '.'                    + \
2798                              ModuleType.upper()     ] = RuleObj
2799        else :
2800            self.Profile.RuleDict['RULE'             + \
2801                              '.'                    + \
2802                              Arch.upper()           + \
2803                              '.'                    + \
2804                              ModuleType.upper()     + \
2805                              '.'                    + \
2806                              TemplateName.upper() ] = RuleObj
2807#        self.Profile.RuleList.append(rule)
2808        return True
2809
2810    ## __GetModuleType() method
2811    #
2812    #   Return the module type
2813    #
2814    #   @param  self        The object pointer
2815    #   @retval string      module type
2816    #
2817    def __GetModuleType(self):
2818
2819        if not self.__GetNextWord():
2820            raise Warning("expected Module type At Line ", self.FileName, self.CurrentLineNumber)
2821        if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
2822                             "DXE_DRIVER", "DXE_SAL_DRIVER", \
2823                             "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
2824                             "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
2825                             "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
2826                             "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
2827            raise Warning("Unknown Module type At line ", self.FileName, self.CurrentLineNumber)
2828        return self.__Token
2829
2830    ## __GetFileExtension() method
2831    #
2832    #   Return the file extension
2833    #
2834    #   @param  self        The object pointer
2835    #   @retval string      file name extension
2836    #
2837    def __GetFileExtension(self):
2838        if not self.__IsToken("."):
2839                raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
2840
2841        Ext = ""
2842        if self.__GetNextToken():
2843            Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
2844            if Pattern.match(self.__Token):
2845                Ext = self.__Token
2846                return '.' + Ext
2847            else:
2848                raise Warning("Unknown file extension At Line ", self.FileName, self.CurrentLineNumber)
2849
2850        else:
2851            raise Warning("expected file extension At Line ", self.FileName, self.CurrentLineNumber)
2852
2853    ## __GetRuleFileStatement() method
2854    #
2855    #   Get rule contents
2856    #
2857    #   @param  self        The object pointer
2858    #   @retval Rule        Rule object
2859    #
2860    def __GetRuleFileStatements(self):
2861
2862        if not self.__IsKeyword("FILE"):
2863            raise Warning("expected FILE At Line ", self.FileName, self.CurrentLineNumber)
2864
2865        if not self.__GetNextWord():
2866            raise Warning("expected FFS type At Line ", self.FileName, self.CurrentLineNumber)
2867
2868        Type = self.__Token.strip().upper()
2869        if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
2870                             "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
2871            raise Warning("Unknown FV type At line ", self.FileName, self.CurrentLineNumber)
2872
2873        if not self.__IsToken("="):
2874            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2875
2876        if not self.__IsKeyword("$(NAMED_GUID)"):
2877            if not self.__GetNextWord():
2878                raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
2879            if self.__Token == 'PCD':
2880                if not self.__IsToken( "("):
2881                    raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2882                PcdPair = self.__GetNextPcdName()
2883                if not self.__IsToken( ")"):
2884                    raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2885                self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2886
2887        NameGuid = self.__Token
2888
2889        KeepReloc = None
2890        if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2891            if self.__FileCouldHaveRelocFlag(Type):
2892                if self.__Token == 'RELOCS_STRIPPED':
2893                    KeepReloc = False
2894                else:
2895                    KeepReloc = True
2896            else:
2897                raise Warning("File type %s could not have reloc strip flag At Line %d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2898
2899        KeyStringList = []
2900        if self.__GetNextToken():
2901            Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2902            if Pattern.match(self.__Token):
2903                KeyStringList.append(self.__Token)
2904                if self.__IsToken(","):
2905                    while self.__GetNextToken():
2906                        if not Pattern.match(self.__Token):
2907                            raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)
2908                        KeyStringList.append(self.__Token)
2909
2910                        if not self.__IsToken(","):
2911                            break
2912
2913            else:
2914                self.__UndoToken()
2915
2916
2917        Fixed = False
2918        if self.__IsKeyword("Fixed", True):
2919            Fixed = True
2920
2921        CheckSum = False
2922        if self.__IsKeyword("CheckSum", True):
2923            CheckSum = True
2924
2925        AlignValue = ""
2926        if self.__GetAlignment():
2927            if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2928                raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
2929            AlignValue = self.__Token
2930
2931        if self.__IsToken("{"):
2932            # Complex file rule expected
2933            Rule = RuleComplexFile.RuleComplexFile()
2934            Rule.FvFileType = Type
2935            Rule.NameGuid = NameGuid
2936            Rule.Alignment = AlignValue
2937            Rule.CheckSum = CheckSum
2938            Rule.Fixed = Fixed
2939            Rule.KeyStringList = KeyStringList
2940            if KeepReloc != None:
2941                Rule.KeepReloc = KeepReloc
2942
2943            while True:
2944                IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
2945                IsLeaf = self.__GetEfiSection(Rule)
2946                if not IsEncapsulate and not IsLeaf:
2947                    break
2948
2949            if not self.__IsToken("}"):
2950                raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2951
2952            return Rule
2953
2954        elif self.__IsToken("|"):
2955            # Ext rule expected
2956            Ext = self.__GetFileExtension()
2957
2958            Rule = RuleSimpleFile.RuleSimpleFile()
2959
2960            Rule.FvFileType = Type
2961            Rule.NameGuid = NameGuid
2962            Rule.Alignment = AlignValue
2963            Rule.CheckSum = CheckSum
2964            Rule.Fixed = Fixed
2965            Rule.FileExtension = Ext
2966            Rule.KeyStringList = KeyStringList
2967            if KeepReloc != None:
2968                Rule.KeepReloc = KeepReloc
2969
2970            return Rule
2971
2972        else:
2973            # Simple file rule expected
2974            if not self.__GetNextWord():
2975                raise Warning("expected leaf section type At Line ", self.FileName, self.CurrentLineNumber)
2976
2977            SectionName = self.__Token
2978
2979            if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2980                                    "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
2981                raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
2982
2983
2984            if self.__IsKeyword("Fixed", True):
2985                Fixed = True
2986
2987            if self.__IsKeyword("CheckSum", True):
2988                CheckSum = True
2989
2990            if self.__GetAlignment():
2991                if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2992                    raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
2993                if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
2994                    raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2995                AlignValue = self.__Token
2996
2997            if not self.__GetNextToken():
2998                raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber)
2999
3000            Rule = RuleSimpleFile.RuleSimpleFile()
3001            Rule.SectionType = SectionName
3002            Rule.FvFileType = Type
3003            Rule.NameGuid = NameGuid
3004            Rule.Alignment = AlignValue
3005            Rule.CheckSum = CheckSum
3006            Rule.Fixed = Fixed
3007            Rule.FileName = self.__Token
3008            Rule.KeyStringList = KeyStringList
3009            if KeepReloc != None:
3010                Rule.KeepReloc = KeepReloc
3011            return Rule
3012
3013    ## __GetEfiSection() method
3014    #
3015    #   Get section list for Rule
3016    #
3017    #   @param  self        The object pointer
3018    #   @param  Obj         for whom section is got
3019    #   @retval True        Successfully find section statement
3020    #   @retval False       Not able to find section statement
3021    #
3022    def __GetEfiSection(self, Obj):
3023
3024        OldPos = self.GetFileBufferPos()
3025        if not self.__GetNextWord():
3026            return False
3027        SectionName = self.__Token
3028
3029        if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3030                               "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3031            self.__UndoToken()
3032            return False
3033
3034        if SectionName == "FV_IMAGE":
3035            FvImageSectionObj = FvImageSection.FvImageSection()
3036            if self.__IsKeyword("FV_IMAGE"):
3037                pass
3038            if self.__IsToken( "{"):
3039                FvObj = Fv.FV()
3040                self.__GetDefineStatements(FvObj)
3041                self.__GetBlockStatement(FvObj)
3042                self.__GetSetStatements(FvObj)
3043                self.__GetFvAlignment(FvObj)
3044                self.__GetFvAttributes(FvObj)
3045                self.__GetAprioriSection(FvObj)
3046                self.__GetAprioriSection(FvObj)
3047
3048                while True:
3049                    IsInf = self.__GetInfStatement(FvObj)
3050                    IsFile = self.__GetFileStatement(FvObj)
3051                    if not IsInf and not IsFile:
3052                        break
3053
3054                if not self.__IsToken( "}"):
3055                    raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3056                FvImageSectionObj.Fv = FvObj
3057                FvImageSectionObj.FvName = None
3058
3059            else:
3060                if not self.__IsKeyword("FV"):
3061                    raise Warning("expected 'FV' At Line ", self.FileName, self.CurrentLineNumber)
3062                FvImageSectionObj.FvFileType = self.__Token
3063
3064                if self.__GetAlignment():
3065                    if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3066                        raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
3067                    FvImageSectionObj.Alignment = self.__Token
3068
3069                if self.__IsToken('|'):
3070                    FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
3071                elif self.__GetNextToken():
3072                    if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3073                               "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3074                        FvImageSectionObj.FvFileName = self.__Token
3075                    else:
3076                        self.__UndoToken()
3077                else:
3078                    raise Warning("expected FV file name At Line ", self.FileName, self.CurrentLineNumber)
3079
3080            Obj.SectionList.append(FvImageSectionObj)
3081            return True
3082
3083        EfiSectionObj = EfiSection.EfiSection()
3084        EfiSectionObj.SectionType = SectionName
3085
3086        if not self.__GetNextToken():
3087            raise Warning("expected file type At Line ", self.FileName, self.CurrentLineNumber)
3088
3089        if self.__Token == "STRING":
3090            if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
3091                raise Warning("%s section could NOT have string data At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3092
3093            if not self.__IsToken('='):
3094                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3095
3096            if not self.__GetNextToken():
3097                raise Warning("expected Quoted String At Line ", self.FileName, self.CurrentLineNumber)
3098
3099            if self.__GetStringData():
3100                EfiSectionObj.StringData = self.__Token
3101
3102            if self.__IsKeyword("BUILD_NUM"):
3103                if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3104                    raise Warning("%s section could NOT have BUILD_NUM At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3105
3106                if not self.__IsToken("="):
3107                    raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3108                if not self.__GetNextToken():
3109                    raise Warning("expected Build number At Line ", self.FileName, self.CurrentLineNumber)
3110                EfiSectionObj.BuildNum = self.__Token
3111
3112        else:
3113            EfiSectionObj.FileType = self.__Token
3114            self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
3115
3116        if self.__IsKeyword("Optional"):
3117            if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
3118                raise Warning("%s section could NOT be optional At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3119            EfiSectionObj.Optional = True
3120
3121            if self.__IsKeyword("BUILD_NUM"):
3122                if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3123                    raise Warning("%s section could NOT have BUILD_NUM At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3124
3125                if not self.__IsToken("="):
3126                    raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3127                if not self.__GetNextToken():
3128                    raise Warning("expected Build number At Line ", self.FileName, self.CurrentLineNumber)
3129                EfiSectionObj.BuildNum = self.__Token
3130
3131        if self.__GetAlignment():
3132            if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3133                raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3134            if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3135                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3136            EfiSectionObj.Alignment = self.__Token
3137
3138        if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3139            if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
3140                if self.__Token == 'RELOCS_STRIPPED':
3141                    EfiSectionObj.KeepReloc = False
3142                else:
3143                    EfiSectionObj.KeepReloc = True
3144                if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
3145                    raise Warning("Section type %s has reloc strip flag conflict with Rule At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3146            else:
3147                raise Warning("Section type %s could not have reloc strip flag At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3148
3149
3150        if self.__IsToken('|'):
3151            EfiSectionObj.FileExtension = self.__GetFileExtension()
3152        elif self.__GetNextToken():
3153            if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3154                       "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3155
3156                if self.__Token.startswith('PCD'):
3157                    self.__UndoToken()
3158                    self.__GetNextWord()
3159
3160                    if self.__Token == 'PCD':
3161                        if not self.__IsToken( "("):
3162                            raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3163                        PcdPair = self.__GetNextPcdName()
3164                        if not self.__IsToken( ")"):
3165                            raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3166                        self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3167
3168                EfiSectionObj.FileName = self.__Token
3169
3170            else:
3171                self.__UndoToken()
3172        else:
3173            raise Warning("expected section file name At Line ", self.FileName, self.CurrentLineNumber)
3174
3175        Obj.SectionList.append(EfiSectionObj)
3176        return True
3177
3178    ## __RuleSectionCouldBeOptional() method
3179    #
3180    #   Get whether a section could be optional
3181    #
3182    #   @param  self        The object pointer
3183    #   @param  SectionType The section type to check
3184    #   @retval True        section could be optional
3185    #   @retval False       section never optional
3186    #
3187    def __RuleSectionCouldBeOptional(self, SectionType):
3188        if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3189            return True
3190        else:
3191            return False
3192
3193    ## __RuleSectionCouldHaveBuildNum() method
3194    #
3195    #   Get whether a section could have build number information
3196    #
3197    #   @param  self        The object pointer
3198    #   @param  SectionType The section type to check
3199    #   @retval True        section could have build number information
3200    #   @retval False       section never have build number information
3201    #
3202    def __RuleSectionCouldHaveBuildNum(self, SectionType):
3203        if SectionType in ("VERSION"):
3204            return True
3205        else:
3206            return False
3207
3208    ## __RuleSectionCouldHaveString() method
3209    #
3210    #   Get whether a section could have string
3211    #
3212    #   @param  self        The object pointer
3213    #   @param  SectionType The section type to check
3214    #   @retval True        section could have string
3215    #   @retval False       section never have string
3216    #
3217    def __RuleSectionCouldHaveString(self, SectionType):
3218        if SectionType in ("UI", "VERSION"):
3219            return True
3220        else:
3221            return False
3222
3223    ## __CheckRuleSectionFileType() method
3224    #
3225    #   Get whether a section matches a file type
3226    #
3227    #   @param  self        The object pointer
3228    #   @param  SectionType The section type to check
3229    #   @param  FileType    The file type to check
3230    #
3231    def __CheckRuleSectionFileType(self, SectionType, FileType):
3232        if SectionType == "COMPAT16":
3233            if FileType not in ("COMPAT16", "SEC_COMPAT16"):
3234                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3235        elif SectionType == "PE32":
3236            if FileType not in ("PE32", "SEC_PE32"):
3237                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3238        elif SectionType == "PIC":
3239            if FileType not in ("PIC", "PIC"):
3240                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3241        elif SectionType == "TE":
3242            if FileType not in ("TE", "SEC_TE"):
3243                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3244        elif SectionType == "RAW":
3245            if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
3246                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3247        elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
3248            if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
3249                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3250        elif SectionType == "UI":
3251            if FileType not in ("UI", "SEC_UI"):
3252                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3253        elif SectionType == "VERSION":
3254            if FileType not in ("VERSION", "SEC_VERSION"):
3255                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3256        elif SectionType == "PEI_DEPEX":
3257            if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
3258                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3259        elif SectionType == "GUID":
3260            if FileType not in ("PE32", "SEC_GUID"):
3261                raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3262
3263    ## __GetRuleEncapsulationSection() method
3264    #
3265    #   Get encapsulation section for Rule
3266    #
3267    #   @param  self        The object pointer
3268    #   @param  Rule        for whom section is got
3269    #   @retval True        Successfully find section statement
3270    #   @retval False       Not able to find section statement
3271    #
3272    def __GetRuleEncapsulationSection(self, Rule):
3273
3274        if self.__IsKeyword( "COMPRESS"):
3275            Type = "PI_STD"
3276            if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
3277                Type = self.__Token
3278
3279            if not self.__IsToken("{"):
3280                raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
3281
3282            CompressSectionObj = CompressSection.CompressSection()
3283
3284            CompressSectionObj.CompType = Type
3285            # Recursive sections...
3286            while True:
3287                IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
3288                IsLeaf = self.__GetEfiSection(CompressSectionObj)
3289                if not IsEncapsulate and not IsLeaf:
3290                    break
3291
3292            if not self.__IsToken( "}"):
3293                raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3294            Rule.SectionList.append(CompressSectionObj)
3295
3296            return True
3297
3298        elif self.__IsKeyword( "GUIDED"):
3299            GuidValue = None
3300            if self.__GetNextGuid():
3301                GuidValue = self.__Token
3302
3303            if self.__IsKeyword( "$(NAMED_GUID)"):
3304                GuidValue = self.__Token
3305
3306            AttribDict = self.__GetGuidAttrib()
3307
3308            if not self.__IsToken("{"):
3309                raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
3310            GuidSectionObj = GuidSection.GuidSection()
3311            GuidSectionObj.NameGuid = GuidValue
3312            GuidSectionObj.SectionType = "GUIDED"
3313            GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
3314            GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
3315
3316            # Efi sections...
3317            while True:
3318                IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
3319                IsLeaf = self.__GetEfiSection(GuidSectionObj)
3320                if not IsEncapsulate and not IsLeaf:
3321                    break
3322
3323            if not self.__IsToken( "}"):
3324                raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3325            Rule.SectionList.append(GuidSectionObj)
3326
3327            return True
3328
3329        return False
3330
3331    ## __GetVtf() method
3332    #
3333    #   Get VTF section contents and store its data into VTF list of self.Profile
3334    #
3335    #   @param  self        The object pointer
3336    #   @retval True        Successfully find a VTF
3337    #   @retval False       Not able to find a VTF
3338    #
3339    def __GetVtf(self):
3340
3341        if not self.__GetNextToken():
3342            return False
3343
3344        S = self.__Token.upper()
3345        if S.startswith("[") and not S.startswith("[VTF."):
3346            if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
3347                raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3348            self.__UndoToken()
3349            return False
3350
3351        self.__UndoToken()
3352        if not self.__IsToken("[VTF.", True):
3353            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3354            print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3355                    % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3356            raise Warning("expected [VTF.] At Line ", self.FileName, self.CurrentLineNumber)
3357
3358        if not self.__SkipToToken("."):
3359            raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
3360
3361        Arch = self.__SkippedChars.rstrip(".").upper()
3362        if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
3363            raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber)
3364
3365        if not self.__GetNextWord():
3366            raise Warning("expected VTF name At Line ", self.FileName, self.CurrentLineNumber)
3367        Name = self.__Token.upper()
3368
3369        VtfObj = Vtf.Vtf()
3370        VtfObj.UiName = Name
3371        VtfObj.KeyArch = Arch
3372
3373        if self.__IsToken(","):
3374            if not self.__GetNextWord():
3375                raise Warning("expected Arch list At Line ", self.FileName, self.CurrentLineNumber)
3376            if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
3377                raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber)
3378            VtfObj.ArchList = self.__Token.upper()
3379
3380        if not self.__IsToken( "]"):
3381            raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
3382
3383        if self.__IsKeyword("IA32_RST_BIN"):
3384            if not self.__IsToken("="):
3385                raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3386
3387            if not self.__GetNextToken():
3388                raise Warning("expected Reset file At Line ", self.FileName, self.CurrentLineNumber)
3389
3390            VtfObj.ResetBin = self.__Token
3391
3392        while self.__GetComponentStatement(VtfObj):
3393            pass
3394
3395        self.Profile.VtfList.append(VtfObj)
3396        return True
3397
3398    ## __GetComponentStatement() method
3399    #
3400    #   Get components in VTF
3401    #
3402    #   @param  self        The object pointer
3403    #   @param  VtfObj         for whom component is got
3404    #   @retval True        Successfully find a component
3405    #   @retval False       Not able to find a component
3406    #
3407    def __GetComponentStatement(self, VtfObj):
3408
3409        if not self.__IsKeyword("COMP_NAME"):
3410            return False
3411
3412        if not self.__IsToken("="):
3413            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3414
3415        if not self.__GetNextWord():
3416            raise Warning("expected Component Name At Line ", self.FileName, self.CurrentLineNumber)
3417
3418        CompStatementObj = ComponentStatement.ComponentStatement()
3419        CompStatementObj.CompName = self.__Token
3420
3421        if not self.__IsKeyword("COMP_LOC"):
3422            raise Warning("expected COMP_LOC At Line ", self.FileName, self.CurrentLineNumber)
3423
3424        if not self.__IsToken("="):
3425            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3426
3427        CompStatementObj.CompLoc = ""
3428        if self.__GetNextWord():
3429            CompStatementObj.CompLoc = self.__Token
3430            if self.__IsToken('|'):
3431                if not self.__GetNextWord():
3432                    raise Warning("Expected Region Name At Line ", self.FileName, self.CurrentLineNumber)
3433
3434                if self.__Token not in ("F", "N", "S"):    #, "H", "L", "PH", "PL"): not support
3435                    raise Warning("Unknown location type At line ", self.FileName, self.CurrentLineNumber)
3436
3437                CompStatementObj.FilePos = self.__Token
3438        else:
3439            self.CurrentLineNumber += 1
3440            self.CurrentOffsetWithinLine = 0
3441
3442        if not self.__IsKeyword("COMP_TYPE"):
3443            raise Warning("expected COMP_TYPE At Line ", self.FileName, self.CurrentLineNumber)
3444
3445        if not self.__IsToken("="):
3446            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3447
3448        if not self.__GetNextToken():
3449            raise Warning("expected Component type At Line ", self.FileName, self.CurrentLineNumber)
3450        if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
3451            if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
3452                not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
3453                raise Warning("Unknown location type At line ", self.FileName, self.CurrentLineNumber)
3454        CompStatementObj.CompType = self.__Token
3455
3456        if not self.__IsKeyword("COMP_VER"):
3457            raise Warning("expected COMP_VER At Line ", self.FileName, self.CurrentLineNumber)
3458
3459        if not self.__IsToken("="):
3460            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3461
3462        if not self.__GetNextToken():
3463            raise Warning("expected Component version At Line ", self.FileName, self.CurrentLineNumber)
3464
3465        Pattern = re.compile('-$|[0-9]{0,1}[0-9]{1}\.[0-9]{0,1}[0-9]{1}')
3466        if Pattern.match(self.__Token) == None:
3467            raise Warning("Unknown version format At line ", self.FileName, self.CurrentLineNumber)
3468        CompStatementObj.CompVer = self.__Token
3469
3470        if not self.__IsKeyword("COMP_CS"):
3471            raise Warning("expected COMP_CS At Line ", self.FileName, self.CurrentLineNumber)
3472
3473        if not self.__IsToken("="):
3474            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3475
3476        if not self.__GetNextToken():
3477            raise Warning("expected Component CS At Line ", self.FileName, self.CurrentLineNumber)
3478        if self.__Token not in ("1", "0"):
3479            raise Warning("Unknown  Component CS At line ", self.FileName, self.CurrentLineNumber)
3480        CompStatementObj.CompCs = self.__Token
3481
3482
3483        if not self.__IsKeyword("COMP_BIN"):
3484            raise Warning("expected COMP_BIN At Line ", self.FileName, self.CurrentLineNumber)
3485
3486        if not self.__IsToken("="):
3487            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3488
3489        if not self.__GetNextToken():
3490            raise Warning("expected Component file At Line ", self.FileName, self.CurrentLineNumber)
3491
3492        CompStatementObj.CompBin = self.__Token
3493
3494        if not self.__IsKeyword("COMP_SYM"):
3495            raise Warning("expected COMP_SYM At Line ", self.FileName, self.CurrentLineNumber)
3496
3497        if not self.__IsToken("="):
3498            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3499
3500        if not self.__GetNextToken():
3501            raise Warning("expected Component symbol file At Line ", self.FileName, self.CurrentLineNumber)
3502
3503        CompStatementObj.CompSym = self.__Token
3504
3505        if not self.__IsKeyword("COMP_SIZE"):
3506            raise Warning("expected COMP_SIZE At Line ", self.FileName, self.CurrentLineNumber)
3507
3508        if not self.__IsToken("="):
3509            raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3510
3511        if self.__IsToken("-"):
3512            CompStatementObj.CompSize = self.__Token
3513        elif self.__GetNextDecimalNumber():
3514            CompStatementObj.CompSize = self.__Token
3515        elif self.__GetNextHexNumber():
3516            CompStatementObj.CompSize = self.__Token
3517        else:
3518            raise Warning("Unknown size At line ", self.FileName, self.CurrentLineNumber)
3519
3520        VtfObj.ComponentStatementList.append(CompStatementObj)
3521        return True
3522
3523    ## __GetFvInFd() method
3524    #
3525    #   Get FV list contained in FD
3526    #
3527    #   @param  self        The object pointer
3528    #   @param  FdName      FD name
3529    #   @retval FvList      list of FV in FD
3530    #
3531    def __GetFvInFd (self, FdName):
3532
3533        FvList = []
3534        if FdName.upper() in self.Profile.FdDict.keys():
3535            FdObj = self.Profile.FdDict[FdName.upper()]
3536            for elementRegion in FdObj.RegionList:
3537                if elementRegion.RegionType == 'FV':
3538                    for elementRegionData in elementRegion.RegionDataList:
3539                        if elementRegionData != None and elementRegionData.upper() not in FvList:
3540                            FvList.append(elementRegionData.upper())
3541        return FvList
3542
3543    ## __GetReferencedFdFvTuple() method
3544    #
3545    #   Get FD and FV list referenced by a FFS file
3546    #
3547    #   @param  self        The object pointer
3548    #   @param  FfsFile     contains sections to be searched
3549    #   @param  RefFdList   referenced FD by section
3550    #   @param  RefFvList   referenced FV by section
3551    #
3552    def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
3553
3554        for FfsObj in FvObj.FfsList:
3555            if isinstance(FfsObj, FfsFileStatement.FileStatement):
3556                if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
3557                    RefFvList.append(FfsObj.FvName.upper())
3558                elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
3559                    RefFdList.append(FfsObj.FdName.upper())
3560                else:
3561                    self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
3562
3563    ## __GetReferencedFdFvTupleFromSection() method
3564    #
3565    #   Get FD and FV list referenced by a FFS section
3566    #
3567    #   @param  self        The object pointer
3568    #   @param  FfsFile     contains sections to be searched
3569    #   @param  FdList      referenced FD by section
3570    #   @param  FvList      referenced FV by section
3571    #
3572    def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
3573
3574        SectionStack = []
3575        SectionStack.extend(FfsFile.SectionList)
3576        while SectionStack != []:
3577            SectionObj = SectionStack.pop()
3578            if isinstance(SectionObj, FvImageSection.FvImageSection):
3579                if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
3580                    FvList.append(SectionObj.FvName.upper())
3581                if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
3582                    FvList.append(SectionObj.Fv.UiFvName.upper())
3583                    self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
3584
3585            if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
3586                SectionStack.extend(SectionObj.SectionList)
3587
3588    ## CycleReferenceCheck() method
3589    #
3590    #   Check whether cycle reference exists in FDF
3591    #
3592    #   @param  self        The object pointer
3593    #   @retval True        cycle reference exists
3594    #   @retval False       Not exists cycle reference
3595    #
3596    def CycleReferenceCheck(self):
3597
3598        CycleRefExists = False
3599
3600        try:
3601            for FvName in self.Profile.FvDict.keys():
3602                LogStr = "Cycle Reference Checking for FV: %s\n" % FvName
3603                RefFvStack = []
3604                RefFvStack.append(FvName)
3605                FdAnalyzedList = []
3606
3607                while RefFvStack != []:
3608                    FvNameFromStack = RefFvStack.pop()
3609                    if FvNameFromStack.upper() in self.Profile.FvDict.keys():
3610                        FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
3611                    else:
3612                        continue
3613
3614                    RefFdList = []
3615                    RefFvList = []
3616                    self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
3617
3618                    for RefFdName in RefFdList:
3619                        if RefFdName in FdAnalyzedList:
3620                            continue
3621
3622                        LogStr += "FD %s is referenced by FV %s\n" % (RefFdName, FvNameFromStack)
3623                        FvInFdList = self.__GetFvInFd(RefFdName)
3624                        if FvInFdList != []:
3625                            LogStr += "FD %s contains FV: " % RefFdName
3626                            for FvObj in FvInFdList:
3627                                LogStr += FvObj
3628                                LogStr += ' \n'
3629                                if FvObj not in RefFvStack:
3630                                    RefFvStack.append(FvObj)
3631
3632                                if FvName in RefFvStack:
3633                                    CycleRefExists = True
3634                                    raise Warning(LogStr)
3635                        FdAnalyzedList.append(RefFdName)
3636
3637                    for RefFvName in RefFvList:
3638                        LogStr += "FV %s is referenced by FV %s\n" % (RefFvName, FvNameFromStack)
3639                        if RefFvName not in RefFvStack:
3640                            RefFvStack.append(RefFvName)
3641
3642                        if FvName in RefFvStack:
3643                            CycleRefExists = True
3644                            raise Warning(LogStr)
3645
3646        except Warning:
3647            print LogStr
3648
3649        finally:
3650            return CycleRefExists
3651
3652if __name__ == "__main__":
3653    import sys
3654    try:
3655        test_file = sys.argv[1]
3656    except IndexError, v:
3657        print "Usage: %s filename" % sys.argv[0]
3658        sys.exit(1)
3659
3660    parser = FdfParser(test_file)
3661    try:
3662        parser.ParseFile()
3663        parser.CycleReferenceCheck()
3664    except Warning, X:
3665        print X.message
3666    else:
3667        print "Success!"
3668
3669