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