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