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