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