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