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