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