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