Check In tool source code based on Build tool project revision r1655.
[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"):\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         if self.__Token == "FV":\r
1624             self.__UndoToken()\r
1625             self.__GetRegionFvType( RegionObj)\r
1626 \r
1627         elif self.__Token == "FILE":\r
1628             self.__UndoToken()\r
1629             self.__GetRegionFileType( RegionObj)\r
1630 \r
1631         else:\r
1632             self.__UndoToken()\r
1633             self.__GetRegionDataType( RegionObj)\r
1634             \r
1635         return True\r
1636             \r
1637     ## __GetRegionFvType() method\r
1638     #\r
1639     #   Get region fv data for region\r
1640     #\r
1641     #   @param  self        The object pointer\r
1642     #   @param  RegionObj   for whom region data is got\r
1643     #\r
1644     def __GetRegionFvType(self, RegionObj):\r
1645 \r
1646         if not self.__IsKeyword( "FV"):\r
1647             raise Warning("expected Keyword 'FV' At Line ", self.FileName, self.CurrentLineNumber)\r
1648         \r
1649         if not self.__IsToken( "="):\r
1650             raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
1651         \r
1652         if not self.__GetNextToken():\r
1653             raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)\r
1654         \r
1655         RegionObj.RegionType = "FV"\r
1656         RegionObj.RegionDataList.append(self.__Token)\r
1657         \r
1658         while self.__IsKeyword( "FV"):\r
1659         \r
1660             if not self.__IsToken( "="):\r
1661                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
1662         \r
1663             if not self.__GetNextToken():\r
1664                 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)\r
1665         \r
1666             RegionObj.RegionDataList.append(self.__Token)\r
1667         \r
1668     ## __GetRegionFileType() method\r
1669     #\r
1670     #   Get region file data for region\r
1671     #\r
1672     #   @param  self        The object pointer\r
1673     #   @param  RegionObj   for whom region data is got\r
1674     #\r
1675     def __GetRegionFileType(self, RegionObj):\r
1676 \r
1677         if not self.__IsKeyword( "FILE"):\r
1678             raise Warning("expected Keyword 'FILE' At Line ", self.FileName, self.CurrentLineNumber)\r
1679 \r
1680         if not self.__IsToken( "="):\r
1681             raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
1682 \r
1683         if not self.__GetNextToken():\r
1684             raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber)\r
1685 \r
1686         RegionObj.RegionType = "FILE"\r
1687         RegionObj.RegionDataList.append( self.__Token)\r
1688         \r
1689         while self.__IsKeyword( "FILE"):\r
1690         \r
1691             if not self.__IsToken( "="):\r
1692                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
1693         \r
1694             if not self.__GetNextToken():\r
1695                 raise Warning("expected FILE name At Line ", self.FileName, self.CurrentLineNumber)\r
1696         \r
1697             RegionObj.RegionDataList.append(self.__Token)\r
1698 \r
1699     ## __GetRegionDataType() method\r
1700     #\r
1701     #   Get region array data for region\r
1702     #\r
1703     #   @param  self        The object pointer\r
1704     #   @param  RegionObj   for whom region data is got\r
1705     #\r
1706     def __GetRegionDataType(self, RegionObj):\r
1707         \r
1708         if not self.__IsKeyword( "DATA"):\r
1709             raise Warning("expected Region Data type At Line ", self.FileName, self.CurrentLineNumber)\r
1710 \r
1711         if not self.__IsToken( "="):\r
1712             raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
1713         \r
1714         if not self.__IsToken( "{"):\r
1715             raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)\r
1716         \r
1717         if not self.__GetNextHexNumber():\r
1718             raise Warning("expected Hex byte At Line ", self.FileName, self.CurrentLineNumber)\r
1719         \r
1720         if len(self.__Token) > 4:\r
1721             raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber)\r
1722         \r
1723         DataString = self.__Token\r
1724         DataString += ","\r
1725         \r
1726         while self.__IsToken(","):\r
1727             if not self.__GetNextHexNumber():\r
1728                 raise Warning("Invalid Hex number At Line ", self.FileName, self.CurrentLineNumber)\r
1729             if len(self.__Token) > 4:\r
1730                 raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber)\r
1731             DataString += self.__Token\r
1732             DataString += ","\r
1733             \r
1734         if not self.__IsToken( "}"):\r
1735             raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)\r
1736         \r
1737         DataString = DataString.rstrip(",")\r
1738         RegionObj.RegionType = "DATA"\r
1739         RegionObj.RegionDataList.append( DataString)\r
1740         \r
1741         while self.__IsKeyword( "DATA"):\r
1742 \r
1743             if not self.__IsToken( "="):\r
1744                 raise Warning("expected '=' 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.__GetNextHexNumber():\r
1750                 raise Warning("expected Hex byte At Line ", self.FileName, self.CurrentLineNumber)\r
1751         \r
1752             if len(self.__Token) > 4:\r
1753                 raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber)\r
1754         \r
1755             DataString = self.__Token\r
1756             DataString += ","\r
1757         \r
1758             while self.__IsToken(","):\r
1759                 self.__GetNextHexNumber()\r
1760                 if len(self.__Token) > 4:\r
1761                     raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber)\r
1762                 DataString += self.__Token\r
1763                 DataString += ","\r
1764             \r
1765             if not self.__IsToken( "}"):\r
1766                 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)\r
1767         \r
1768             DataString = DataString.rstrip(",")\r
1769             RegionObj.RegionDataList.append( DataString)\r
1770     \r
1771     ## __GetFv() method\r
1772     #\r
1773     #   Get FV section contents and store its data into FV dictionary of self.Profile\r
1774     #\r
1775     #   @param  self        The object pointer\r
1776     #   @retval True        Successfully find a FV\r
1777     #   @retval False       Not able to find a FV\r
1778     #    \r
1779     def __GetFv(self):\r
1780         if not self.__GetNextToken():\r
1781             return False\r
1782 \r
1783         S = self.__Token.upper()\r
1784         if S.startswith("[") and not S.startswith("[FV."):\r
1785             if not S.startswith("[CAPSULE.") \\r
1786                 and not S.startswith("[VTF.") and not S.startswith("[RULE."):\r
1787                 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
1788             self.__UndoToken()\r
1789             return False\r
1790 \r
1791         self.__UndoToken()\r
1792         if not self.__IsToken("[FV.", True):\r
1793             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1794             print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1795                     % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1796             raise Warning("Unknown Keyword At Line ", self.FileName, self.CurrentLineNumber)\r
1797         \r
1798         FvName = self.__GetUiName()\r
1799         self.CurrentFvName = FvName.upper()\r
1800         \r
1801         if not self.__IsToken( "]"):\r
1802             raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)\r
1803         \r
1804         FvObj = CommonDataClass.FdfClass.FvClassObject()\r
1805         FvObj.UiFvName = self.CurrentFvName\r
1806         self.Profile.FvDict[self.CurrentFvName] = FvObj\r
1807         \r
1808         Status = self.__GetCreateFile(FvObj)\r
1809         if not Status:\r
1810             raise Warning("FV name error At Line ", self.FileName, self.CurrentLineNumber)\r
1811 \r
1812         self.__GetDefineStatements(FvObj)\r
1813 \r
1814         self.__GetAddressStatements(FvObj)\r
1815         \r
1816         self.__GetBlockStatement(FvObj)\r
1817 \r
1818         self.__GetSetStatements(FvObj)\r
1819 \r
1820         self.__GetFvAlignment(FvObj)\r
1821 \r
1822         self.__GetFvAttributes(FvObj)\r
1823         \r
1824         self.__GetFvNameGuid(FvObj)\r
1825 \r
1826         self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
1827         self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
1828         \r
1829         while True:\r
1830             isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
1831             isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
1832             if not isInf and not isFile:\r
1833                 break\r
1834         \r
1835         return True\r
1836 \r
1837     ## __GetFvAlignment() method\r
1838     #\r
1839     #   Get alignment for FV\r
1840     #\r
1841     #   @param  self        The object pointer\r
1842     #   @param  Obj         for whom alignment is got\r
1843     #   @retval True        Successfully find a alignment statement\r
1844     #   @retval False       Not able to find a alignment statement\r
1845     #\r
1846     def __GetFvAlignment(self, Obj):\r
1847         \r
1848         if not self.__IsKeyword( "FvAlignment"):\r
1849             return False\r
1850         \r
1851         if not self.__IsToken( "="):\r
1852             raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
1853         \r
1854         if not self.__GetNextToken():\r
1855             raise Warning("expected alignment value At Line ", self.FileName, self.CurrentLineNumber)\r
1856         \r
1857         if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \\r
1858                                         "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \\r
1859                                         "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \\r
1860                                         "1G", "2G"):\r
1861             raise Warning("Unknown alignment value At Line ", self.FileName, self.CurrentLineNumber)\r
1862         Obj.FvAlignment = self.__Token\r
1863         return True\r
1864     \r
1865     ## __GetFvAttributes() method\r
1866     #\r
1867     #   Get attributes for FV\r
1868     #\r
1869     #   @param  self        The object pointer\r
1870     #   @param  Obj         for whom attribute is got\r
1871     #   @retval None\r
1872     #\r
1873     def __GetFvAttributes(self, FvObj):\r
1874         \r
1875         while self.__GetNextWord():\r
1876             name = self.__Token\r
1877             if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \\r
1878                            "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
1879                            "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \\r
1880                            "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \\r
1881                            "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \\r
1882                            "WRITE_POLICY_RELIABLE"):\r
1883                 self.__UndoToken()\r
1884                 return\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() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
1890                 raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)\r
1891             \r
1892             FvObj.FvAttributeDict[name] = self.__Token\r
1893 \r
1894         return\r
1895     \r
1896     ## __GetFvNameGuid() method\r
1897     #\r
1898     #   Get FV GUID for FV\r
1899     #\r
1900     #   @param  self        The object pointer\r
1901     #   @param  Obj         for whom GUID is got\r
1902     #   @retval None\r
1903     #\r
1904     def __GetFvNameGuid(self, FvObj):\r
1905 \r
1906         if not self.__IsKeyword( "FvNameGuid"):\r
1907             return\r
1908 \r
1909         if not self.__IsToken( "="):\r
1910             raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1911 \r
1912         if not self.__GetNextGuid():\r
1913             raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)\r
1914 \r
1915         FvObj.FvNameGuid = self.__Token\r
1916 \r
1917         return\r
1918 \r
1919     ## __GetAprioriSection() method\r
1920     #\r
1921     #   Get token statements\r
1922     #\r
1923     #   @param  self        The object pointer\r
1924     #   @param  FvObj       for whom apriori is got\r
1925     #   @param  MacroDict   dictionary used to replace macro\r
1926     #   @retval True        Successfully find apriori statement\r
1927     #   @retval False       Not able to find apriori statement\r
1928     #\r
1929     def __GetAprioriSection(self, FvObj, MacroDict = {}):\r
1930         \r
1931         if not self.__IsKeyword( "APRIORI"):\r
1932             return False\r
1933         \r
1934         if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):\r
1935             raise Warning("expected Apriori file type At Line ", self.FileName, self.CurrentLineNumber)\r
1936         AprType = self.__Token\r
1937         \r
1938         if not self.__IsToken( "{"):\r
1939             raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)\r
1940         \r
1941         AprSectionObj = CommonDataClass.FdfClass.AprioriSectionClassObject()\r
1942         AprSectionObj.AprioriType = AprType\r
1943         \r
1944         self.__GetDefineStatements(AprSectionObj)\r
1945         MacroDict.update(AprSectionObj.DefineVarDict)\r
1946         \r
1947         while True:\r
1948             IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)\r
1949             IsFile = self.__GetFileStatement( AprSectionObj)\r
1950             if not IsInf and not IsFile:\r
1951                 break\r
1952         \r
1953         if not self.__IsToken( "}"):\r
1954             raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)\r
1955 \r
1956         FvObj.AprioriSectionList.append(AprSectionObj)\r
1957         return True\r
1958 \r
1959     ## __GetInfStatement() method\r
1960     #\r
1961     #   Get INF statements\r
1962     #\r
1963     #   @param  self        The object pointer\r
1964     #   @param  Obj         for whom inf statement is got\r
1965     #   @param  MacroDict   dictionary used to replace macro\r
1966     #   @retval True        Successfully find inf statement\r
1967     #   @retval False       Not able to find inf statement\r
1968     #\r
1969     def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
1970 \r
1971         if not self.__IsKeyword( "INF"):\r
1972             return False\r
1973         \r
1974         ffsInf = CommonDataClass.FdfClass.FfsInfStatementClassObject()\r
1975         self.__GetInfOptions( ffsInf)\r
1976         \r
1977         if not self.__GetNextToken():\r
1978             raise Warning("expected INF file path At Line ", self.FileName, self.CurrentLineNumber)\r
1979         ffsInf.InfFileName = self.__Token\r
1980         \r
1981 #        if ffsInf.InfFileName.find('$') >= 0:\r
1982 #            ffsInf.InfFileName = GenFdsGlobalVariable.GenFdsGlobalVariable.MacroExtend(ffsInf.InfFileName, MacroDict)\r
1983             \r
1984         if not ffsInf.InfFileName in self.Profile.InfList:\r
1985             self.Profile.InfList.append(ffsInf.InfFileName)\r
1986             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1987             self.Profile.InfFileLineList.append(FileLineTuple)\r
1988         \r
1989         if self.__IsToken('|'):\r
1990             if self.__IsKeyword('RELOCS_STRIPPED'):\r
1991                 ffsInf.KeepReloc = False\r
1992             elif self.__IsKeyword('RELOCS_RETAINED'):\r
1993                 ffsInf.KeepReloc = True\r
1994             else:\r
1995                 raise Warning("Unknown reloc strip flag At Line ", self.FileName, self.CurrentLineNumber)\r
1996         \r
1997         if ForCapsule:\r
1998             capsuleFfs = CapsuleData.CapsuleFfs()\r
1999             capsuleFfs.Ffs = ffsInf\r
2000             Obj.CapsuleDataList.append(capsuleFfs)\r
2001         else:\r
2002             Obj.FfsList.append(ffsInf)\r
2003         return True\r
2004     \r
2005     ## __GetInfOptions() method\r
2006     #\r
2007     #   Get options for INF\r
2008     #\r
2009     #   @param  self        The object pointer\r
2010     #   @param  FfsInfObj   for whom option is got\r
2011     #\r
2012     def __GetInfOptions(self, FfsInfObj):\r
2013         \r
2014         if self.__IsKeyword( "RuleOverride"):\r
2015             if not self.__IsToken( "="):\r
2016                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2017             if not self.__GetNextToken():\r
2018                 raise Warning("expected Rule name At Line ", self.FileName, self.CurrentLineNumber)\r
2019             FfsInfObj.Rule = self.__Token\r
2020             \r
2021         if self.__IsKeyword( "VERSION"):\r
2022             if not self.__IsToken( "="):\r
2023                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2024             if not self.__GetNextToken():\r
2025                 raise Warning("expected Version At Line ", self.FileName, self.CurrentLineNumber)\r
2026             \r
2027             if self.__GetStringData():\r
2028                 FfsInfObj.Version = self.__Token\r
2029         \r
2030         if self.__IsKeyword( "UI"):\r
2031             if not self.__IsToken( "="):\r
2032                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2033             if not self.__GetNextToken():\r
2034                 raise Warning("expected UI name At Line ", self.FileName, self.CurrentLineNumber)\r
2035             \r
2036             if self.__GetStringData():\r
2037                 FfsInfObj.Ui = self.__Token\r
2038 \r
2039         if self.__IsKeyword( "USE"):\r
2040             if not self.__IsToken( "="):\r
2041                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2042             if not self.__GetNextToken():\r
2043                 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)\r
2044             FfsInfObj.UseArch = self.__Token\r
2045 \r
2046                 \r
2047         if self.__GetNextToken():\r
2048             p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
2049             if p.match(self.__Token):\r
2050                 FfsInfObj.KeyStringList.append(self.__Token)\r
2051                 if not self.__IsToken(","):\r
2052                     return\r
2053             else:\r
2054                 self.__UndoToken()\r
2055                 return\r
2056                 \r
2057             while self.__GetNextToken():\r
2058                 if not p.match(self.__Token):\r
2059                     raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)\r
2060                 FfsInfObj.KeyStringList.append(self.__Token)\r
2061     \r
2062                 if not self.__IsToken(","):\r
2063                     break\r
2064                 \r
2065     ## __GetFileStatement() method\r
2066     #\r
2067     #   Get FILE statements\r
2068     #\r
2069     #   @param  self        The object pointer\r
2070     #   @param  Obj         for whom FILE statement is got\r
2071     #   @param  MacroDict   dictionary used to replace macro\r
2072     #   @retval True        Successfully find FILE statement\r
2073     #   @retval False       Not able to find FILE statement\r
2074     #\r
2075     def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
2076 \r
2077         if not self.__IsKeyword( "FILE"):\r
2078             return False\r
2079         \r
2080         FfsFileObj = CommonDataClass.FdfClass.FileStatementClassObject()\r
2081         \r
2082         if not self.__GetNextWord():\r
2083             raise Warning("expected FFS type At Line ", self.FileName, self.CurrentLineNumber)\r
2084         FfsFileObj.FvFileType = self.__Token\r
2085         \r
2086         if not self.__IsToken( "="):\r
2087             raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2088 \r
2089         if not self.__GetNextGuid():\r
2090             if not self.__GetNextWord():\r
2091                 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)\r
2092             if self.__Token == 'PCD':\r
2093                 if not self.__IsToken( "("):\r
2094                     raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
2095                 PcdPair = self.__GetNextPcdName()\r
2096                 if not self.__IsToken( ")"):\r
2097                     raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
2098                 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
2099                 \r
2100         FfsFileObj.NameGuid = self.__Token\r
2101     \r
2102         self.__GetFilePart( FfsFileObj, MacroDict.copy())\r
2103         \r
2104         if ForCapsule:\r
2105             capsuleFfs = CapsuleData.CapsuleFfs()\r
2106             capsuleFfs.Ffs = FfsFileObj\r
2107             Obj.CapsuleDataList.append(capsuleFfs)\r
2108         else:\r
2109             Obj.FfsList.append(FfsFileObj)\r
2110                 \r
2111         return True\r
2112     \r
2113     ## __FileCouldHaveRelocFlag() method\r
2114     #\r
2115     #   Check whether reloc strip flag can be set for a file type.\r
2116     #\r
2117     #   @param  self        The object pointer\r
2118     #   @param  FileType    The file type to check with\r
2119     #   @retval True        This type could have relocation strip flag\r
2120     #   @retval False       No way to have it\r
2121     #\r
2122     \r
2123     def __FileCouldHaveRelocFlag (self, FileType):\r
2124         if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):\r
2125             return True\r
2126         else:\r
2127             return False\r
2128     \r
2129     ## __SectionCouldHaveRelocFlag() method\r
2130     #\r
2131     #   Check whether reloc strip flag can be set for a section type.\r
2132     #\r
2133     #   @param  self        The object pointer\r
2134     #   @param  SectionType The section type to check with\r
2135     #   @retval True        This type could have relocation strip flag\r
2136     #   @retval False       No way to have it\r
2137     #\r
2138     \r
2139     def __SectionCouldHaveRelocFlag (self, SectionType):\r
2140         if SectionType in ('TE', 'PE32'):\r
2141             return True\r
2142         else:\r
2143             return False\r
2144         \r
2145     ## __GetFilePart() method\r
2146     #\r
2147     #   Get components for FILE statement\r
2148     #\r
2149     #   @param  self        The object pointer\r
2150     #   @param  FfsFileObj   for whom component is got\r
2151     #   @param  MacroDict   dictionary used to replace macro\r
2152     #\r
2153     def __GetFilePart(self, FfsFileObj, MacroDict = {}):\r
2154         \r
2155         self.__GetFileOpts( FfsFileObj)\r
2156         \r
2157         if not self.__IsToken("{"):\r
2158 #            if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2159 #                if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2160 #                    if self.__Token == 'RELOCS_STRIPPED':\r
2161 #                        FfsFileObj.KeepReloc = False\r
2162 #                    else:\r
2163 #                        FfsFileObj.KeepReloc = True\r
2164 #                else:\r
2165 #                    raise Warning("File type %s could not have reloc strip flag At Line %d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2166 #            \r
2167 #            if not self.__IsToken("{"):\r
2168             raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)\r
2169             \r
2170         if not self.__GetNextToken():\r
2171             raise Warning("expected File name or section data At Line ", self.FileName, self.CurrentLineNumber)\r
2172         \r
2173         if self.__Token == "FV":\r
2174             if not self.__IsToken( "="):\r
2175                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2176             if not self.__GetNextToken():\r
2177                 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)\r
2178             FfsFileObj.FvName = self.__Token\r
2179             \r
2180         elif self.__Token == "FD":\r
2181             if not self.__IsToken( "="):\r
2182                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2183             if not self.__GetNextToken():\r
2184                 raise Warning("expected FD name At Line ", self.FileName, self.CurrentLineNumber)\r
2185             FfsFileObj.FdName = self.__Token\r
2186             \r
2187         elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):\r
2188             self.__UndoToken()\r
2189             self.__GetSectionData( FfsFileObj, MacroDict)\r
2190         else:\r
2191             FfsFileObj.FileName = self.__Token\r
2192         \r
2193         if not self.__IsToken( "}"):\r
2194             raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)\r
2195     \r
2196     ## __GetFileOpts() method\r
2197     #\r
2198     #   Get options for FILE statement\r
2199     #\r
2200     #   @param  self        The object pointer\r
2201     #   @param  FfsFileObj   for whom options is got\r
2202     #\r
2203     def __GetFileOpts(self, FfsFileObj):\r
2204         \r
2205         if self.__GetNextToken():\r
2206             Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
2207             if Pattern.match(self.__Token):\r
2208                 FfsFileObj.KeyStringList.append(self.__Token)\r
2209                 if self.__IsToken(","):\r
2210                     while self.__GetNextToken():\r
2211                         if not Pattern.match(self.__Token):\r
2212                             raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)\r
2213                         FfsFileObj.KeyStringList.append(self.__Token)\r
2214 \r
2215                         if not self.__IsToken(","):\r
2216                             break\r
2217                     \r
2218             else:\r
2219                 self.__UndoToken()\r
2220 \r
2221         if self.__IsKeyword( "FIXED", True):\r
2222             FfsFileObj.Fixed = True\r
2223             \r
2224         if self.__IsKeyword( "CHECKSUM", True):\r
2225             FfsFileObj.CheckSum = True\r
2226             \r
2227         if self.__GetAlignment():\r
2228             FfsFileObj.Alignment = self.__Token\r
2229             \r
2230         \r
2231     \r
2232     ## __GetAlignment() method\r
2233     #\r
2234     #   Return the alignment value\r
2235     #\r
2236     #   @param  self        The object pointer\r
2237     #   @retval True        Successfully find alignment\r
2238     #   @retval False       Not able to find alignment\r
2239     #\r
2240     def __GetAlignment(self):\r
2241         if self.__IsKeyword( "Align", True):\r
2242             if not self.__IsToken( "="):\r
2243                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2244             \r
2245             if not self.__GetNextToken():\r
2246                 raise Warning("expected alignment value At Line ", self.FileName, self.CurrentLineNumber)\r
2247             return True\r
2248             \r
2249         return False\r
2250     \r
2251     ## __GetFilePart() method\r
2252     #\r
2253     #   Get section data for FILE statement\r
2254     #\r
2255     #   @param  self        The object pointer\r
2256     #   @param  FfsFileObj   for whom section is got\r
2257     #   @param  MacroDict   dictionary used to replace macro\r
2258     #\r
2259     def __GetSectionData(self, FfsFileObj, MacroDict = {}):\r
2260         Dict = {}\r
2261         Dict.update(MacroDict)\r
2262         \r
2263         self.__GetDefineStatements(FfsFileObj)\r
2264         \r
2265         Dict.update(FfsFileObj.DefineVarDict)\r
2266         self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2267         self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2268         \r
2269         while True:\r
2270             IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)\r
2271             IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)\r
2272             if not IsLeafSection and not IsEncapSection:\r
2273                 break\r
2274          \r
2275     ## __GetLeafSection() method\r
2276     #\r
2277     #   Get leaf section for Obj\r
2278     #\r
2279     #   @param  self        The object pointer\r
2280     #   @param  Obj         for whom leaf section is got\r
2281     #   @param  MacroDict   dictionary used to replace macro\r
2282     #   @retval True        Successfully find section statement\r
2283     #   @retval False       Not able to find section statement\r
2284     #\r
2285     def __GetLeafSection(self, Obj, MacroDict = {}):\r
2286         \r
2287         OldPos = self.GetFileBufferPos()\r
2288         \r
2289         if not self.__IsKeyword( "SECTION"):\r
2290             if len(Obj.SectionList) == 0:\r
2291                 raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber)\r
2292             else:\r
2293                 return False\r
2294         \r
2295         AlignValue = None\r
2296         if self.__GetAlignment():\r
2297             AlignValue = self.__Token\r
2298             \r
2299         BuildNum = None\r
2300         if self.__IsKeyword( "BUILD_NUM"):\r
2301             if not self.__IsToken( "="):\r
2302                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2303             \r
2304             if not self.__GetNextToken():\r
2305                 raise Warning("expected Build number value At Line ", self.FileName, self.CurrentLineNumber)\r
2306             \r
2307             BuildNum = self.__Token\r
2308             \r
2309         if self.__IsKeyword( "VERSION"):\r
2310             if not self.__IsToken( "="):\r
2311                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2312             if not self.__GetNextToken():\r
2313                 raise Warning("expected version At Line ", self.FileName, self.CurrentLineNumber)\r
2314             VerSectionObj = CommonDataClass.FdfClass.VerSectionClassObject()\r
2315             VerSectionObj.Alignment = AlignValue\r
2316             VerSectionObj.BuildNum = BuildNum\r
2317             if self.__GetStringData():\r
2318                 VerSectionObj.StringData = self.__Token\r
2319             else:\r
2320                 VerSectionObj.FileName = self.__Token\r
2321             Obj.SectionList.append(VerSectionObj)\r
2322 \r
2323         elif self.__IsKeyword( "UI"):\r
2324             if not self.__IsToken( "="):\r
2325                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2326             if not self.__GetNextToken():\r
2327                 raise Warning("expected UI At Line ", self.FileName, self.CurrentLineNumber)\r
2328             UiSectionObj = CommonDataClass.FdfClass.UiSectionClassObject()\r
2329             UiSectionObj.Alignment = AlignValue\r
2330             if self.__GetStringData():\r
2331                 UiSectionObj.StringData = self.__Token\r
2332             else:\r
2333                 UiSectionObj.FileName = self.__Token\r
2334             Obj.SectionList.append(UiSectionObj)\r
2335             \r
2336         elif self.__IsKeyword( "FV_IMAGE"):\r
2337             if not self.__IsToken( "="):\r
2338                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2339             if not self.__GetNextWord():\r
2340                 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)\r
2341             \r
2342             FvName = self.__Token.upper()\r
2343             FvObj = None\r
2344 \r
2345             if self.__IsToken( "{"):\r
2346                 FvObj = Fv.FV()\r
2347                 FvObj.UiFvName = FvName\r
2348                 self.__GetDefineStatements(FvObj)\r
2349                 MacroDict.update(FvObj.DefineVarDict)\r
2350                 self.__GetBlockStatement(FvObj)\r
2351                 self.__GetSetStatements(FvObj)\r
2352                 self.__GetFvAlignment(FvObj)\r
2353                 self.__GetFvAttributes(FvObj)\r
2354                 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2355                 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2356     \r
2357                 while True:\r
2358                     IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())\r
2359                     IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())\r
2360                     if not IsInf and not IsFile:\r
2361                         break\r
2362     \r
2363                 if not self.__IsToken( "}"):\r
2364                     raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)\r
2365             \r
2366             FvImageSectionObj = CommonDataClass.FdfClass.FvImageSectionClassObject()\r
2367             FvImageSectionObj.Alignment = AlignValue\r
2368             if FvObj != None:\r
2369                 FvImageSectionObj.Fv = FvObj\r
2370                 FvImageSectionObj.FvName = None\r
2371             else:\r
2372                 FvImageSectionObj.FvName = FvName\r
2373                 \r
2374             Obj.SectionList.append(FvImageSectionObj) \r
2375            \r
2376         elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP"):\r
2377             DepexSectionObj = CommonDataClass.FdfClass.DepexSectionClassObject()\r
2378             DepexSectionObj.Alignment = AlignValue\r
2379             DepexSectionObj.DepexType = self.__Token\r
2380             \r
2381             if not self.__IsToken( "="):\r
2382                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2383             if not self.__IsToken( "{"):\r
2384                 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)\r
2385             if not self.__SkipToToken( "}"):\r
2386                 raise Warning("expected Depex expression ending '}' At Line ", self.FileName, self.CurrentLineNumber)\r
2387             \r
2388             DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')\r
2389             Obj.SectionList.append(DepexSectionObj)\r
2390         \r
2391         else:\r
2392             \r
2393             if not self.__GetNextWord():\r
2394                 raise Warning("expected section type At Line ", self.FileName, self.CurrentLineNumber)\r
2395             \r
2396             # Encapsulation section appear, UndoToken and return\r
2397             if self.__Token == "COMPRESS" or self.__Token == "GUIDED":\r
2398                 self.SetFileBufferPos(OldPos)\r
2399                 return False\r
2400             \r
2401             if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
2402                                "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):\r
2403                 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2404             # DataSection\r
2405             DataSectionObj = CommonDataClass.FdfClass.DataSectionClassObject()\r
2406             DataSectionObj.Alignment = AlignValue\r
2407             DataSectionObj.SecType = self.__Token\r
2408             \r
2409             if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2410                 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
2411                     if self.__Token == 'RELOCS_STRIPPED':\r
2412                         DataSectionObj.KeepReloc = False\r
2413                     else:\r
2414                         DataSectionObj.KeepReloc = True\r
2415                 else:\r
2416                     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
2417             \r
2418             if self.__IsToken("="):\r
2419                 if not self.__GetNextToken():\r
2420                     raise Warning("expected section file path At Line ", self.FileName, self.CurrentLineNumber)\r
2421                 DataSectionObj.SectFileName = self.__Token\r
2422             else:\r
2423                 if not self.__GetCglSection(DataSectionObj):\r
2424                     return False\r
2425             \r
2426             Obj.SectionList.append(DataSectionObj)\r
2427             \r
2428         return True\r
2429             \r
2430     ## __GetCglSection() method\r
2431     #\r
2432     #   Get compressed or GUIDed section for Obj\r
2433     #\r
2434     #   @param  self        The object pointer\r
2435     #   @param  Obj         for whom leaf section is got\r
2436     #   @param  AlignValue  alignment value for complex section\r
2437     #   @retval True        Successfully find section statement\r
2438     #   @retval False       Not able to find section statement\r
2439     #\r
2440     def __GetCglSection(self, Obj, AlignValue = None):\r
2441         \r
2442         if self.__IsKeyword( "COMPRESS"):\r
2443             type = "PI_STD"\r
2444             if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):\r
2445                 type = self.__Token\r
2446                 \r
2447             if not self.__IsToken("{"):\r
2448                 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)\r
2449 \r
2450             CompressSectionObj = CommonDataClass.FdfClass.CompressSectionClassObject()\r
2451             CompressSectionObj.Alignment = AlignValue\r
2452             CompressSectionObj.CompType = type\r
2453             # Recursive sections...\r
2454             while True:\r
2455                 IsLeafSection = self.__GetLeafSection(CompressSectionObj)\r
2456                 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)\r
2457                 if not IsLeafSection and not IsEncapSection:\r
2458                     break\r
2459             \r
2460             \r
2461             if not self.__IsToken( "}"):\r
2462                 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)\r
2463             Obj.SectionList.append(CompressSectionObj)\r
2464                 \r
2465 #            else:\r
2466 #               raise Warning("Compress type not known At Line ") \r
2467            \r
2468             return True\r
2469         \r
2470         elif self.__IsKeyword( "GUIDED"):\r
2471             GuidValue = None\r
2472             if self.__GetNextGuid():\r
2473                 GuidValue = self.__Token\r
2474 \r
2475             AttribDict = self.__GetGuidAttrib()\r
2476             if not self.__IsToken("{"):\r
2477                 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)\r
2478             GuidSectionObj = CommonDataClass.FdfClass.GuidSectionClassObject()\r
2479             GuidSectionObj.Alignment = AlignValue\r
2480             GuidSectionObj.NameGuid = GuidValue\r
2481             GuidSectionObj.SectionType = "GUIDED"\r
2482             GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
2483             GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
2484             # Recursive sections...\r
2485             while True:\r
2486                 IsLeafSection = self.__GetLeafSection(GuidSectionObj)\r
2487                 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)\r
2488                 if not IsLeafSection and not IsEncapSection:\r
2489                     break\r
2490             \r
2491             if not self.__IsToken( "}"):\r
2492                 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)\r
2493             Obj.SectionList.append(GuidSectionObj)\r
2494                 \r
2495             return True\r
2496         \r
2497         return False\r
2498 \r
2499     ## __GetGuidAttri() method\r
2500     #\r
2501     #   Get attributes for GUID section\r
2502     #\r
2503     #   @param  self        The object pointer\r
2504     #   @retval AttribDict  Dictionary of key-value pair of section attributes\r
2505     #\r
2506     def __GetGuidAttrib(self):\r
2507         \r
2508         AttribDict = {}\r
2509         AttribDict["PROCESSING_REQUIRED"] = False\r
2510         AttribDict["AUTH_STATUS_VALID"] = False\r
2511         if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):\r
2512             AttribKey = self.__Token\r
2513 \r
2514             if not self.__IsToken("="):\r
2515                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2516             \r
2517             if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
2518                 raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)\r
2519             AttribDict[AttribKey] = self.__Token\r
2520             \r
2521         if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):\r
2522             AttribKey = self.__Token\r
2523 \r
2524             if not self.__IsToken("="):\r
2525                 raise Warning("expected '=' At Line ")\r
2526 \r
2527             if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
2528                 raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)\r
2529             AttribDict[AttribKey] = self.__Token\r
2530             \r
2531         return AttribDict\r
2532             \r
2533     ## __GetEncapsulationSec() method\r
2534     #\r
2535     #   Get encapsulation section for FILE\r
2536     #\r
2537     #   @param  self        The object pointer\r
2538     #   @param  FfsFile     for whom section is got\r
2539     #   @retval True        Successfully find section statement\r
2540     #   @retval False       Not able to find section statement\r
2541     #\r
2542     def __GetEncapsulationSec(self, FfsFileObj):        \r
2543         \r
2544         OldPos = self.GetFileBufferPos()\r
2545         if not self.__IsKeyword( "SECTION"):\r
2546             if len(FfsFileObj.SectionList) == 0:\r
2547                 raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber)\r
2548             else:\r
2549                 return False\r
2550         \r
2551         AlignValue = None\r
2552         if self.__GetAlignment():\r
2553             AlignValue = self.__Token\r
2554             \r
2555         if not self.__GetCglSection(FfsFileObj, AlignValue):\r
2556             self.SetFileBufferPos(OldPos)\r
2557             return False\r
2558         else:\r
2559             return True\r
2560 \r
2561     ## __GetCapsule() method\r
2562     #\r
2563     #   Get capsule section contents and store its data into capsule list of self.Profile\r
2564     #\r
2565     #   @param  self        The object pointer\r
2566     #   @retval True        Successfully find a capsule\r
2567     #   @retval False       Not able to find a capsule\r
2568     #\r
2569     def __GetCapsule(self):\r
2570         \r
2571         if not self.__GetNextToken():\r
2572             return False\r
2573 \r
2574         S = self.__Token.upper()\r
2575         if S.startswith("[") and not S.startswith("[CAPSULE."):\r
2576             if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
2577                 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
2578             self.__UndoToken()\r
2579             return False\r
2580 \r
2581         self.__UndoToken()\r
2582         if not self.__IsToken("[CAPSULE.", True):\r
2583             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2584             print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
2585                     % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
2586             raise Warning("expected [Capsule.] At Line ", self.FileName, self.CurrentLineNumber)        \r
2587             \r
2588         CapsuleObj = CommonDataClass.FdfClass.CapsuleClassObject()\r
2589 \r
2590         CapsuleName = self.__GetUiName()\r
2591         if not CapsuleName:\r
2592             raise Warning("expected capsule name At line ", self.FileName, self.CurrentLineNumber)\r
2593         \r
2594         CapsuleObj.UiCapsuleName = CapsuleName.upper()\r
2595         \r
2596         if not self.__IsToken( "]"):\r
2597             raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)\r
2598         \r
2599         if self.__IsKeyword("CREATE_FILE"):\r
2600             if not self.__IsToken( "="):\r
2601                 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2602             \r
2603             if not self.__GetNextToken():\r
2604                 raise Warning("expected file name At Line ", self.FileName, self.CurrentLineNumber)\r
2605             \r
2606             CapsuleObj.CreateFile = self.__Token\r
2607         \r
2608         self.__GetCapsuleStatements(CapsuleObj)\r
2609         self.Profile.CapsuleList.append(CapsuleObj)\r
2610         return True    \r
2611             \r
2612     ## __GetCapsuleStatements() method\r
2613     #\r
2614     #   Get statements for capsule\r
2615     #\r
2616     #   @param  self        The object pointer\r
2617     #   @param  Obj         for whom statements are got\r
2618     #\r
2619     def __GetCapsuleStatements(self, Obj):\r
2620         self.__GetCapsuleTokens(Obj)\r
2621         self.__GetDefineStatements(Obj)\r
2622         self.__GetSetStatements(Obj)\r
2623         \r
2624         self.__GetCapsuleData(Obj)\r
2625                 \r
2626     ## __GetCapsuleStatements() method\r
2627     #\r
2628     #   Get token statements for capsule\r
2629     #\r
2630     #   @param  self        The object pointer\r
2631     #   @param  Obj         for whom token statements are got\r
2632     #\r
2633     def __GetCapsuleTokens(self, Obj):\r
2634         \r
2635         if not self.__IsKeyword("CAPSULE_GUID"):\r
2636             raise Warning("expected 'CAPSULE_GUID' At Line ", self.FileName, self.CurrentLineNumber)\r
2637         \r
2638         while self.__CurrentLine().find("=") != -1:\r
2639             NameValue = self.__CurrentLine().split("=")\r
2640             Obj.TokensDict[NameValue[0].strip()] = NameValue[1].strip()\r
2641             self.CurrentLineNumber += 1\r
2642             self.CurrentOffsetWithinLine = 0\r
2643     \r
2644     ## __GetCapsuleData() method\r
2645     #\r
2646     #   Get capsule data for capsule\r
2647     #\r
2648     #   @param  self        The object pointer\r
2649     #   @param  Obj         for whom capsule data are got\r
2650     #\r
2651     def __GetCapsuleData(self, Obj):\r
2652         \r
2653         while True:\r
2654             IsInf = self.__GetInfStatement(Obj, True)\r
2655             IsFile = self.__GetFileStatement(Obj, True)\r
2656             IsFv = self.__GetFvStatement(Obj)\r
2657             if not IsInf and not IsFile and not IsFv:\r
2658                 break\r
2659     \r
2660     ## __GetFvStatement() method\r
2661     #\r
2662     #   Get FV for capsule\r
2663     #\r
2664     #   @param  self        The object pointer\r
2665     #   @param  CapsuleObj  for whom FV is got\r
2666     #   @retval True        Successfully find a FV statement\r
2667     #   @retval False       Not able to find a FV statement\r
2668     #\r
2669     def __GetFvStatement(self, CapsuleObj):\r
2670         \r
2671         if not self.__IsKeyword("FV"):\r
2672             return False\r
2673         \r
2674         if not self.__IsToken("="):\r
2675             raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2676         \r
2677         if not self.__GetNextToken():\r
2678             raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)\r
2679         \r
2680 #        CapsuleFv = CapsuleData.CapsuleFv()\r
2681 #        CapsuleFv.FvName = self.__Token\r
2682 #        CapsuleObj.CapsuleDataList.append(CapsuleFv)\r
2683         return True\r
2684     \r
2685     ## __GetRule() method\r
2686     #\r
2687     #   Get Rule section contents and store its data into rule list of self.Profile\r
2688     #\r
2689     #   @param  self        The object pointer\r
2690     #   @retval True        Successfully find a Rule\r
2691     #   @retval False       Not able to find a Rule\r
2692     #\r
2693     def __GetRule(self):\r
2694         \r
2695         if not self.__GetNextToken():\r
2696             return False\r
2697 \r
2698         S = self.__Token.upper()\r
2699         if S.startswith("[") and not S.startswith("[RULE."):\r
2700             if not S.startswith("[OPTIONROM."):\r
2701                 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
2702             self.__UndoToken()\r
2703             return False\r
2704         self.__UndoToken()\r
2705         if not self.__IsToken("[Rule.", True):\r
2706             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2707             print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
2708                     % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
2709             raise Warning("expected [Rule.] At Line ", self.FileName, self.CurrentLineNumber)\r
2710 \r
2711         if not self.__SkipToToken("."):\r
2712             raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)\r
2713         \r
2714         Arch = self.__SkippedChars.rstrip(".")\r
2715         if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "COMMON"):\r
2716             raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber)\r
2717         \r
2718         ModuleType = self.__GetModuleType()\r
2719         \r
2720         TemplateName = ""\r
2721         if self.__IsToken("."):\r
2722             if not self.__GetNextWord():\r
2723                 raise Warning("expected template name At Line ", self.FileName, self.CurrentLineNumber)\r
2724             TemplateName = self.__Token\r
2725             \r
2726         if not self.__IsToken( "]"):\r
2727             raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)\r
2728         \r
2729         RuleObj = self.__GetRuleFileStatements()\r
2730         RuleObj.Arch = Arch.upper()\r
2731         RuleObj.ModuleType = ModuleType\r
2732         RuleObj.TemplateName = TemplateName\r
2733         if TemplateName == '' :\r
2734             self.Profile.RuleDict['RULE'             + \\r
2735                               '.'                    + \\r
2736                               Arch.upper()           + \\r
2737                               '.'                    + \\r
2738                               ModuleType.upper()     ] = RuleObj\r
2739         else :\r
2740             self.Profile.RuleDict['RULE'             + \\r
2741                               '.'                    + \\r
2742                               Arch.upper()           + \\r
2743                               '.'                    + \\r
2744                               ModuleType.upper()     + \\r
2745                               '.'                    + \\r
2746                               TemplateName.upper() ] = RuleObj\r
2747 #        self.Profile.RuleList.append(rule)\r
2748         return True\r
2749     \r
2750     ## __GetModuleType() method\r
2751     #\r
2752     #   Return the module type\r
2753     #\r
2754     #   @param  self        The object pointer\r
2755     #   @retval string      module type\r
2756     #\r
2757     def __GetModuleType(self):\r
2758         \r
2759         if not self.__GetNextWord():\r
2760             raise Warning("expected Module type At Line ", self.FileName, self.CurrentLineNumber)\r
2761         if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \\r
2762                              "DXE_DRIVER", "DXE_SAL_DRIVER", \\r
2763                              "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \\r
2764                              "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \\r
2765                              "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \\r
2766                              "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION"):\r
2767             raise Warning("Unknown Module type At line ", self.FileName, self.CurrentLineNumber)\r
2768         return self.__Token\r
2769     \r
2770     ## __GetFileExtension() method\r
2771     #\r
2772     #   Return the file extension\r
2773     #\r
2774     #   @param  self        The object pointer\r
2775     #   @retval string      file name extension\r
2776     #\r
2777     def __GetFileExtension(self):\r
2778         if not self.__IsToken("."):\r
2779                 raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)\r
2780             \r
2781         Ext = ""\r
2782         if self.__GetNextToken():\r
2783             Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')\r
2784             if Pattern.match(self.__Token):\r
2785                 Ext = self.__Token                            \r
2786                 return '.' + Ext    \r
2787             else:\r
2788                 raise Warning("Unknown file extension At Line ", self.FileName, self.CurrentLineNumber)\r
2789                 \r
2790         else:\r
2791             raise Warning("expected file extension At Line ", self.FileName, self.CurrentLineNumber)\r
2792         \r
2793     ## __GetRuleFileStatement() method\r
2794     #\r
2795     #   Get rule contents\r
2796     #\r
2797     #   @param  self        The object pointer\r
2798     #   @retval Rule        Rule object\r
2799     #\r
2800     def __GetRuleFileStatements(self):\r
2801         \r
2802         if not self.__IsKeyword("FILE"):\r
2803             raise Warning("expected FILE At Line ", self.FileName, self.CurrentLineNumber)\r
2804         \r
2805         if not self.__GetNextWord():\r
2806             raise Warning("expected FV type At Line ", self.FileName, self.CurrentLineNumber)\r
2807         \r
2808         Type = self.__Token.strip().upper()\r
2809         if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\\r
2810                              "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE"):\r
2811             raise Warning("Unknown FV type At line ", self.FileName, self.CurrentLineNumber)\r
2812 \r
2813         if not self.__IsToken("="):\r
2814             raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)\r
2815         \r
2816         if not self.__IsKeyword("$(NAMED_GUID)"):\r
2817             if not self.__GetNextWord():\r
2818                 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)\r
2819             if self.__Token == 'PCD':\r
2820                 if not self.__IsToken( "("):\r
2821                     raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
2822                 PcdPair = self.__GetNextPcdName()\r
2823                 if not self.__IsToken( ")"):\r
2824                     raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
2825                 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
2826             \r
2827         NameGuid = self.__Token\r
2828 \r
2829         KeepReloc = None\r
2830         if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2831             if self.__FileCouldHaveRelocFlag(Type):\r
2832                 if self.__Token == 'RELOCS_STRIPPED':\r
2833                     KeepReloc = False\r
2834                 else:\r
2835                     KeepReloc = True\r
2836             else:\r
2837                 raise Warning("File type %s could not have reloc strip flag At Line %d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2838         \r
2839         KeyStringList = []\r
2840         if self.__GetNextToken():\r
2841             Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
2842             if Pattern.match(self.__Token):\r
2843                 KeyStringList.append(self.__Token)\r
2844                 if self.__IsToken(","):\r
2845                     while self.__GetNextToken():\r
2846                         if not Pattern.match(self.__Token):\r
2847                             raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)\r
2848                         KeyStringList.append(self.__Token)\r
2849 \r
2850                         if not self.__IsToken(","):\r
2851                             break\r
2852                     \r
2853             else:\r
2854                 self.__UndoToken()\r
2855 \r
2856         \r
2857         Fixed = False\r
2858         if self.__IsKeyword("Fixed", True):\r
2859             Fixed = True\r
2860             \r
2861         CheckSum = False\r
2862         if self.__IsKeyword("CheckSum", True):\r
2863             CheckSum = True\r
2864             \r
2865         AlignValue = ""\r
2866         if self.__GetAlignment():\r
2867             if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
2868                 raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)\r
2869             AlignValue = self.__Token\r
2870 \r
2871         if self.__IsToken("{"):\r
2872             # Complex file rule expected\r
2873             Rule = RuleComplexFile.RuleComplexFile()\r
2874             Rule.FvFileType = Type\r
2875             Rule.NameGuid = NameGuid\r
2876             Rule.Alignment = AlignValue\r
2877             Rule.CheckSum = CheckSum\r
2878             Rule.Fixed = Fixed\r
2879             Rule.KeyStringList = KeyStringList\r
2880             if KeepReloc != None:\r
2881                 Rule.KeepReloc = KeepReloc\r
2882             \r
2883             while True:\r
2884                 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)\r
2885                 IsLeaf = self.__GetEfiSection(Rule)\r
2886                 if not IsEncapsulate and not IsLeaf:\r
2887                     break\r
2888                 \r
2889             if not self.__IsToken("}"):\r
2890                 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)\r
2891             \r
2892             return Rule\r
2893         \r
2894         elif self.__IsToken("|"):\r
2895             # Ext rule expected\r
2896             Ext = self.__GetFileExtension()\r
2897             \r
2898             Rule = RuleSimpleFile.RuleSimpleFile()\r
2899 \r
2900             Rule.FvFileType = Type\r
2901             Rule.NameGuid = NameGuid\r
2902             Rule.Alignment = AlignValue\r
2903             Rule.CheckSum = CheckSum\r
2904             Rule.Fixed = Fixed\r
2905             Rule.FileExtension = Ext\r
2906             Rule.KeyStringList = KeyStringList\r
2907             if KeepReloc != None:\r
2908                 Rule.KeepReloc = KeepReloc\r
2909             \r
2910             return Rule\r
2911             \r
2912         else:\r
2913             # Simple file rule expected\r
2914             if not self.__GetNextWord():\r
2915                 raise Warning("expected leaf section type At Line ", self.FileName, self.CurrentLineNumber)\r
2916 \r
2917             SectionName = self.__Token\r
2918         \r
2919             if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
2920                                     "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):\r
2921                 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)\r
2922 \r
2923 \r
2924             if self.__IsKeyword("Fixed", True):\r
2925                 Fixed = True              \r
2926     \r
2927             if self.__IsKeyword("CheckSum", True):\r
2928                 CheckSum = True\r
2929     \r
2930             if self.__GetAlignment():\r
2931                 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
2932                     raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)\r
2933                 AlignValue = self.__Token\r
2934             \r
2935             if not self.__GetNextToken():\r
2936                 raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber)\r
2937             \r
2938             Rule = RuleSimpleFile.RuleSimpleFile()\r
2939             Rule.SectionType = SectionName\r
2940             Rule.FvFileType = Type\r
2941             Rule.NameGuid = NameGuid\r
2942             Rule.Alignment = AlignValue\r
2943             Rule.CheckSum = CheckSum\r
2944             Rule.Fixed = Fixed\r
2945             Rule.FileName = self.__Token\r
2946             Rule.KeyStringList = KeyStringList\r
2947             if KeepReloc != None:\r
2948                 Rule.KeepReloc = KeepReloc\r
2949             return Rule\r
2950         \r
2951     ## __GetEfiSection() method\r
2952     #\r
2953     #   Get section list for Rule\r
2954     #\r
2955     #   @param  self        The object pointer\r
2956     #   @param  Obj         for whom section is got\r
2957     #   @retval True        Successfully find section statement\r
2958     #   @retval False       Not able to find section statement\r